Matplotlib:获取子图填充数字

时间:2014-07-02 15:38:12

标签: 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 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值的比率,所以我想知道是否有一个很好的通用方法来设置子图宽度填充空间。可以以某种方式指定子图的物理尺寸吗?我一直在寻找解决方案几个小时,所以提前感谢您提供的任何帮助。

3 个答案:

答案 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的坐标是相对坐标[左,下,宽,高],每个方向按页面大小缩放。

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

  • 如果在没有imshowextent=[...]关键字参数的情况下调用aspect='auto',它会执行本地默认值中指示的内容,通常会尝试保持像素正方形
  • 如果发生这种情况(或aspect='equal'已设置),则轴的作用就像调用plt.axis('scaled')一样,即保持X和Y坐标等长(每单位像素数)并将轴大小更改为匹配范围
  • 这可以通过设置plt.axis('tight')(使x和y限制精确地适合图像)来覆盖

旧技巧是使用axis('auto')axis('normal'),但现在已弃用这些技巧(使用scaledequaltight)。

是的,这有点乱。

答案 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)

在我的系统上,看起来像这样: enter image description here

答案 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()