在 Matplotlib 中设置绘图画布的大小

Posted

技术标签:

【中文标题】在 Matplotlib 中设置绘图画布的大小【英文标题】:Setting the size of the plotting canvas in Matplotlib 【发布时间】:2013-04-10 02:05:40 【问题描述】:

我希望 Matplotlib/Pyplot 生成具有一致画布大小的绘图。也就是说,图形可以有不同的大小以适应轴的描述,但绘图区域(绘制曲线的矩形)应该始终具有相同的大小。

有没有一种简单的方法来实现这一点? pyplot.figure() 的选项 figsize 似乎设置了图形的整体大小,而不是画布的大小,因此每当轴描述占用或多或少的空间时,我都会得到不同的画布大小。

【问题讨论】:

gridspec 有可能让你控制你想要的(见最后 3 个examples here)。您能否添加一些示例来显示导致问题的不同轴描述? 这是 MPL 将要绘制的内容和 如何 绘制它的描述分离的方式的成本。可以肯定的是,手动操作,并刻意避免tight_layout, 是最好的方法。 【参考方案1】:

这是我对 Matplotlib 最大的不满之一。我经常使用栅格数据,例如我想添加颜色图、图例和一些标题。 matplotlib 库中的任何简单示例都将导致不同的分辨率,因此会导致重新采样数据。尤其是在进行图像分析时,您不需要任何(不需要的)重采样。

这是我通常做的事情,虽然我很想知道是否有更简单或更好的方法。

让我们从加载图片开始,并以相同的分辨率将其输出:

import matplotlib.pyplot as plt
import urllib2

# load the image
img = plt.imread(urllib2.urlopen('http://upload.wikimedia.org/wikipedia/en/thumb/5/56/Matplotlib_logo.svg/500px-Matplotlib_logo.svg.png'))

# get the dimensions
ypixels, xpixels, bands = img.shape

# get the size in inches
dpi = 72.
xinch = xpixels / dpi
yinch = ypixels / dpi

# plot and save in the same size as the original
fig = plt.figure(figsize=(xinch,yinch))

ax = plt.axes([0., 0., 1., 1.], frameon=False, xticks=[],yticks=[])
ax.imshow(img, interpolation='none')

plt.savefig('D:\\mpl_logo.png', dpi=dpi, transparent=True)

请注意,我手动定义了轴位置,以便跨越整个图形。

以与上述类似的方式,您可以在图像周围添加一些边距以允许标签或颜色条等。

此示例在图像上方添加 20% 的边距,然后用于绘制标题:

fig = plt.figure(figsize=(xinch,yinch/.8))

ax = plt.axes([0., 0., 1., .8], frameon=False, xticks=[],yticks=[])
ax.imshow(img, interpolation='none')
ax.set_title('Matplotlib is fun!', size=16, weight='bold')

plt.savefig('D:\\mpl_logo_with_title.png', dpi=dpi)

所以图形的 y 尺寸(高度)增加了,轴的 y 尺寸减少了。这提供了更大的(整体)输出图像,但轴区域仍然是相同的大小。

拥有像 .set_scale() 这样的图形或轴属性来强制实现真正的 1-on-x 输出可能会很好。

【讨论】:

你能用一些矢量格式代替吗?它应该(我认为)将每个像素绘制为一个矩形。或者只是方式超过样本。 谢谢您,您的建议奏效了!顺便说一句,我想我确实在调用 figure() 后立即使用 subplot_adjust(0,0,1,1) 找到了一种更优雅的方法。然后,您不需要定义轴位置,因为它们已经和图一样大。最后,如果您不想手动指定边距,可以使用参数 bbox_inches='tight' 调用 savefig()。在这种情况下,绘图区域将完全由 (xinch,yinch) 定义,并且图形将足够大以容纳轴描述。 (正如 tcaswell 所指出的,不要使用tight_layout!) 这听起来确实更容易,感谢您的提示。我稍后会尝试你的建议。 @tcaswell,谢谢,这可能在某些情况下有效,我认为 pcolor 应该能够很容易地做到这一点。不过,任何其他后处理都会更加困难。 @Dario 如果你这样做,那么你已经关闭了所有轴标签。如果您正在制作光栅图像,最好使用 PIL 来保存图像。 @tcaswell 它会关闭标签,但如果你调用 savefig(bbox_inches='tight'),你会得到它们。还是我错过了你的意思?【参考方案2】:

您可以在 Matplotlib rc 中指定以下设置:

import matplotlib
matplotlib.rcParams['figure.figsize'] = [10, 10] # for square canvas
matplotlib.rcParams['figure.subplot.left'] = 0
matplotlib.rcParams['figure.subplot.bottom'] = 0
matplotlib.rcParams['figure.subplot.right'] = 1
matplotlib.rcParams['figure.subplot.top'] = 1

【讨论】:

以上是关于在 Matplotlib 中设置绘图画布的大小的主要内容,如果未能解决你的问题,请参考以下文章

在 matplotlib 中设置可变点大小

如何在 ipython 笔记本中设置 matplotlib 图形默认大小?

在 matplotlib 中设置子图的大小

如何在 HTML5 画布上绘图

在 tkinter 画布中嵌入来自 Arduino 的 Matplotlib 实时绘图数据

Matplotlib