Python Matplotlib:获取子地块以填充图形

Python Matplotlib:获取子地块以填充图形,python,matplotlib,subplot,Python,Matplotlib,Subplot,我想了解如何在将图像打印为子地块时覆盖默认matplotlib行为的建议,因为子地块大小似乎与地物大小不匹配。我想设置我的数字大小(例如,与A4页面的宽度相匹配),并自动拉伸子图以填充可用空间。在以下示例中,下面的代码给出了一个在面板之间有大量空白的图形: import numpy as np import matplotlib.pyplot as plt data=np.random.rand(10,4) #creating a wide figure with 2 subplots in

我想了解如何在将图像打印为子地块时覆盖默认matplotlib行为的建议,因为子地块大小似乎与地物大小不匹配。我想设置我的数字大小(例如,与A4页面的宽度相匹配),并自动拉伸子图以填充可用空间。在以下示例中,下面的代码给出了一个在面板之间有大量空白的图形:

import numpy as np
import matplotlib.pyplot as plt

data=np.random.rand(10,4)

#creating a wide figure with 2 subplots in 1 row
fig,ax=plt.subplots(1,2, figsize=(9,3))  
ax=ax.reshape(1,len(ax))

for i in [0,1]:
    plt.sca(ax[0,i])
    plt.imshow(data,interpolation='nearest')
    plt.colorbar()

我想将子图水平拉伸,以便填充图形空间。我将沿每个轴绘制许多具有不同数量值的类似绘图,绘图之间的空间似乎取决于x值与y值的比率,因此我想知道是否有一种很好的通用方法来设置子绘图宽度以填充空间。能否以某种方式指定子批次的物理大小?我已经搜索了几个小时的解决方案,因此提前感谢您提供的任何帮助。

您可以使用
ax.set\u position
方法调整轴区域。它与相对坐标一起工作,因此如果要制作A4图像,则:

import numpy as np
import matplotlib.pyplot as plt

# figsize keyword talks some obscure units which need a conversion from standard units
plt.figure(figsize=np.array([210,297]) / 25.4)

x = np.linspace(0,2*np.pi, 100)
plt.plot(x, np.sin(x))

plt.gca().set_position([0, 0, 1, 1])

plt.show()
现在,轴区域(打印区域)填充整个页面

给定给
设置位置的坐标是相对坐标[左、下、宽、高],其中每个方向按页面大小缩放

正如其他答案中所指出的,
imshow
matshow
有时会尝试保持图片中的像素为方形。轴比和
imshow
之间存在着相当特殊的相互作用

  • 如果调用
    imshow
    时没有
    extent=[…]
    aspect='auto'
    关键字参数,它会执行本地默认值中指示的操作,通常会尝试保持像素为方形
  • 如果发生这种情况(或设置了
    aspect='equal'
    ),轴的作用就像调用了
    plt.axis('scaled')
    ,即保持X和Y坐标长度相等(每单位像素),并更改轴大小以匹配范围
  • 这可以通过设置
    plt.axis('tight')
    来覆盖(这使得x和y限制与图像精确匹配)
老把戏是使用
轴(“自动”)或
轴(“正常”)
,但这些现在已经被弃用(使用
缩放
相等
,或
紧密


是的,这有点乱。

一位朋友想出了一个解决方案,似乎效果相当不错,我想我会把它发布给任何在imshow中有类似问题设置方面的人——对于下面的nx、figsize、nplots\u hori和nplots\u vert,似乎都能做到这一点

import numpy as np
import matplotlib.pyplot as plt

nx=5
data=np.random.rand(10,nx)

figsize=[10,8]
nplots_hori=2
nplots_vert=2

fig,ax=plt.subplots(nplots_vert, nplots_hori, figsize=figsize)
if nplots_vert==1: ax=ax.reshape(1,len(ax))

plt.tight_layout()
for i in range(nplots_hori):
    for j in range(nplots_vert):
        plt.sca(ax[j,i])
        plt.imshow(data, aspect='auto')

plt.tight_layout()
plt.show()

首先,当您有
对象作为处理时,使用对
plt
的调用。那条路通向痛苦。其次,
imshow
将轴比例的纵横比设置为1。这就是为什么斧子这么窄。了解所有这些,您的示例将变成:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.rand(10,4)

#creating a wide figure with 2 subplots in 1 row
fig, axes = plt.subplots(1, 2, figsize=(9,3))  

for ax in axes.flatten():  # flatten in case you have a second row at some point
    img = ax.imshow(data, interpolation='nearest')
    ax.set_aspect('auto')

plt.colorbar(img)
在我的系统上,看起来是这样的:

非常感谢您的回复。在使用plt.plot()时,该解决方案似乎有效,但在使用plt.imshow()时则无效,这正是我正在使用的。我用它来绘制二维直方图,图上的每个正方形对应一个箱子,它的颜色对应于它包含的值的数量。你知道一种调整imshow()对象大小的方法,或者一种更好的方法来显示二维柱状图,这样你的方法就可以工作了吗?@user3798292,你可以试着按照这里的规定设置位置,但是不使用pyplot命令,而是使用直接对象接口(
ax.imshow(…)
而不是
plt.imshow(…)
)@user3798292:您已经向您指出了一些解决方案,但我对此添加了一些评论
imshow
从这个意义上讲有点奇怪。
plt.gca().set_position([0,0,1,1])
正是我需要的,我需要使用
.imshow()
和Cartopy来填充整个图形。在我的用例中,
plt.axis('tight')
使它显示了地球的整个投影,这不是我想要的。谢谢你非常有用的回答!我喜欢用“模糊单位”来指英寸。也很对。