我希望在将图像绘制为子图时如何覆盖默认的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值的比率,所以我想知道是否有一个很好的通用方法来设置子图宽度填充空间。可以以某种方式指定子图的物理尺寸吗?我一直在寻找解决方案几个小时,所以提前感谢您提供的任何帮助。
答案 0 :(得分:7)
您可以使用ax.set_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()
现在轴区域(绘图区域)填满整个页面。
set_position
的坐标是相对坐标[左,下,宽,高],每个方向按页面大小缩放。
正如其他答案中所指出的,imshow
和matshow
有时会尝试将像素保持在图片中。轴比率和imshow
之间存在相当特殊的相互作用。
imshow
或extent=[...]
关键字参数的情况下调用aspect='auto'
,它会执行本地默认值中指示的内容,通常会尝试保持像素正方形aspect='equal'
已设置),则轴的作用就像调用plt.axis('scaled')
一样,即保持X和Y坐标等长(每单位像素数)并将轴大小更改为匹配范围plt.axis('tight')
(使x和y限制精确地适合图像)来覆盖旧技巧是使用axis('auto')
或axis('normal')
,但现在已弃用这些技巧(使用scaled
,equal
或tight
)。
是的,这有点乱。
答案 1 :(得分:2)
首先,当您处理plt
个对象时,您正在使用Axes
来电。那条路导致痛苦。其次,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)
在我的系统上,看起来像这样:
答案 2 :(得分:0)
一位朋友想出了一个似乎运行得相当好的解决方案,我认为我会为任何有类似问题的人发布 - 在imshow中设置aspect ='auto'似乎可以解决这个问题,因为任何选择nx, figsize,nplots_hori和nplots_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()