如何更改使用Matplotlib绘制的图形的大小?

如何更改使用Matplotlib绘制的图形的大小?

5427639 次浏览

弃用说明:
根据官方Matplotlib指南,不再推荐使用pylab模块。请考虑使用matplotlib.pyplot模块,如另一个答案所述。

以下似乎工作:

from pylab import rcParamsrcParams['figure.figsize'] = 5, 10

这使得该图的宽度为5英寸,高度为10英寸

然后,图类将此用作其参数之一的默认值。

Google中'matplotlib figure size'的第一个链接是调整图片大小页面的Google缓存)。

这是上面页面的测试脚本。它创建同一图像的不同大小的test[1-3].png文件:

#!/usr/bin/env python"""This is a small demo file that helps teach how to adjust figure sizesfor matplotlib
"""
import matplotlibprint "using MPL version:", matplotlib.__version__matplotlib.use("WXAgg") # do this before pylab so you don'tget the default back end.
import pylabimport numpy as np
# Generate and plot some simple data:x = np.arange(0, 2*np.pi, 0.1)y = np.sin(x)
pylab.plot(x,y)F = pylab.gcf()
# Now check everything with the defaults:DPI = F.get_dpi()print "DPI:", DPIDefaultSize = F.get_size_inches()print "Default size in Inches", DefaultSizeprint "Which should result in a %i x %i Image"%(DPI*DefaultSize[0], DPI*DefaultSize[1])# the default is 100dpi for savefig:F.savefig("test1.png")# this gives me a 797 x 566 pixel image, which is about 100 DPI
# Now make the image twice as big, while keeping the fonts and all the# same sizeF.set_size_inches( (DefaultSize[0]*2, DefaultSize[1]*2) )Size = F.get_size_inches()print "Size in Inches", SizeF.savefig("test2.png")# this results in a 1595x1132 image
# Now make the image twice as big, making all the fonts and lines# bigger too.
F.set_size_inches( DefaultSize )# resetthe sizeSize = F.get_size_inches()print "Size in Inches", SizeF.savefig("test3.png", dpi = (200)) # change the dpi# this also results in a 1595x1132 image, but the fonts are larger.

输出:

using MPL version: 0.98.1DPI: 80Default size in Inches [ 8.  6.]Which should result in a 640 x 480 ImageSize in Inches [ 16.  12.]Size in Inches [ 16.  12.]

两点说明:

  1. 模块注释和实际输出不同。

  2. 这个答案允许轻松地将所有三个图像组合在一个图像文件中以查看大小差异。

#0告诉您呼叫签名:

from matplotlib.pyplot import figure
figure(figsize=(8, 6), dpi=80)

figure(figsize=(1,1))将创建一个逐英寸的图像,这将是80×80像素,除非您还提供不同的dpi参数。

如果您已经创建了图形,您可以使用#0来调整图形大小:

fig = matplotlib.pyplot.gcf()fig.set_size_inches(18.5, 10.5)fig.savefig('test2png.png', dpi=100)

要将大小更改传播到现有GUI窗口,请添加forward=True

fig.set_size_inches(18.5, 10.5, forward=True)

此外,正如评论中提到的ErikShilts,您还可以使用#0来“以每英寸点数为单位设置图形的分辨率”

fig.set_dpi(100)

尝试注释fig = ...

import numpy as npimport matplotlib.pyplot as plt
N = 50x = np.random.rand(N)y = np.random.rand(N)area = np.pi * (15 * np.random.rand(N))**2
fig = plt.figure(figsize=(18, 18))plt.scatter(x, y, s=area, alpha=0.5)plt.show()

这对我很有效:

from matplotlib import pyplot as plt
F = plt.gcf()Size = F.get_size_inches()F.set_size_inches(Size[0]*2, Size[1]*2, forward=True) # Set forward to True to resize window along with plot in figure.plt.show() # Or plt.imshow(z_array) if using an animation, where z_array is a matrix or NumPy array

这个论坛帖子也可能有帮助:调整图形窗口的大小

即使在绘制图形后,这也会立即调整图形的大小(至少使用Qt4Agg/TkAgg-但不是Mac OS X-使用Matplotlib 1.4.0):

matplotlib.pyplot.get_current_fig_manager().resize(width_px, height_px)

如果您正在寻找一种方法来更改熊猫中的图形大小,您可以执行以下操作:

df['some_column'].plot(figsize=(10, 5))

其中df是Pandas数据框。或者,使用现有的图形或轴:

fig, ax = plt.subplots(figsize=(10, 5))df['some_column'].plot(ax=ax)

如果您想更改默认设置,您可以执行以下操作:

import matplotlib
matplotlib.rc('figure', figsize=(10, 5))

有关更多详细信息,请查看文档:#0

使用plt.rc参数

如果您想在不使用图形环境的情况下更改大小,也有这种解决方法。例如,如果您使用#0,您可以设置一个具有宽度和高度的元组。

import matplotlib.pyplot as pltplt.rcParams["figure.figsize"] = (20,3)

当您内联绘制(例如,使用IPython笔记本)时,这非常有用。作为阿斯迈尔注意到,最好不要将此语句放在导入语句的同一单元格中。

要将后续绘图的全局图形大小重置为默认值:

plt.rcParams["figure.figsize"] = plt.rcParamsDefault["figure.figsize"]

转换为cm

figsize元组接受英寸,因此如果您想将其设置为厘米,则必须将它们除以2.54。看看这个问题

您可以简单地使用(从matplotlib.figure.图):

fig.set_size_inches(width,height)

从Matplotlib 2.0.0开始,对画布的更改将立即可见,如forward关键字默认为#1

如果您只想更改宽度高度而不是两者,您可以使用

fig.set_figwidth(val)fig.set_figheight(val)

这些也会立即更新您的画布,但仅限于Matplotlib 2.2.0及更高版本。

对于旧版本

您需要显式指定forward=True才能在比上述指定更早的版本中实时更新您的画布。请注意,set_figwidthset_figheight函数在比Matplotlib 1.5.0更早的版本中不支持forward参数。

简化和简化西霍狄莉亚的回答

如果您想通过因子sizefactor更改图形的当前大小:

import matplotlib.pyplot as plt
# Here goes your code
fig_size = plt.gcf().get_size_inches() # Get current sizesizefactor = 0.8 # Set a zoom factor# Modify the current size by the factorplt.gcf().set_size_inches(sizefactor * fig_size)

更改当前大小后,您可能需要微调子情节布局。您可以在图形窗口GUI中或通过命令subplots_adjust执行此操作

例如,

plt.subplots_adjust(left=0.16, bottom=0.19, top=0.82)

我总是使用以下模式:

x_inches = 150*(1/25.4)     # [mm]*constanty_inches = x_inches*(0.8)dpi = 96
fig = plt.figure(1, figsize = (x_inches,y_inches), dpi = dpi, constrained_layout = True)

使用此示例,您可以以英寸或毫米为单位设置图形尺寸。当设置constrained_layoutTrue时,绘图可以无边框填充您的图形。

以像素为单位精确设置图像大小的不同方法比较

这个问题的答案将集中在:

  • savefig: 如何保存到一个文件,而不仅仅是显示在屏幕上
  • 以像素为单位设置大小

这里是一个快速比较的一些方法,我已经尝试与图片显示什么给予。

当前状态总结: 事情很混乱,我不确定这是否是一个基本的限制,或者用例只是没有得到开发人员足够的重视。我很难找到关于这个问题的上游讨论。

没有尝试设置图像尺寸的基线示例

比较一下:

Base.py

#!/usr/bin/env python3


import sys


import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl


fig, ax = plt.subplots()
print('fig.dpi = {}'.format(fig.dpi))
print('fig.get_size_inches() = ' + str(fig.get_size_inches())
t = np.arange(-10., 10., 1.)
plt.plot(t, t, '.')
plt.plot(t, t**2, '.')
ax.text(0., 60., 'Hello', fontdict=dict(size=25))
plt.savefig('base.png', format='png')

跑步:

./base.py
identify base.png

产出:

fig.dpi = 100.0
fig.get_size_inches() = [6.4 4.8]
base.png PNG 640x480 640x480+0+0 8-bit sRGB 13064B 0.000u 0:00.000

Enter image description here

到目前为止我最好的方法: plt.savefig(dpi=h/fig.get_size_inches()[1]高度控制

我想这就是我大多数时候会用到的方法,因为它很简单,而且规模很大:

得到 _ size

#!/usr/bin/env python3


import sys


import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl


height = int(sys.argv[1])
fig, ax = plt.subplots()
t = np.arange(-10., 10., 1.)
plt.plot(t, t, '.')
plt.plot(t, t**2, '.')
ax.text(0., 60., 'Hello', fontdict=dict(size=25))
plt.savefig(
'get_size.png',
format='png',
dpi=height/fig.get_size_inches()[1]
)

跑步:

./get_size.py 431

产出:

get_size.png PNG 574x431 574x431+0+0 8-bit sRGB 10058B 0.000u 0:00.000

Enter image description here

还有

./get_size.py 1293

产出:

main.png PNG 1724x1293 1724x1293+0+0 8-bit sRGB 46709B 0.000u 0:00.000

Enter image description here

我倾向于只设置高度,因为我通常最关心的是图像在文本中间会占用多少垂直空间。

plt.savefig(bbox_inches='tight'改变图像大小

我总是觉得图片周围有太多的空白,并且倾向于从以下几个方面添加 bbox_inches='tight': 删除已保存图像周围的空白

然而,这种方法通过裁剪图像来实现,并且不会得到所需的大小。

相反,在同一问题中提出的另一种方法似乎行之有效:

plt.tight_layout(pad=1)
plt.savefig(...

它给出了高度等于431的理想高度:

Enter image description here

固定高度,set_aspect,自动大小宽度和小边距

嗯,set_aspect又把事情搞砸了,并且阻止 plt.tight_layout实际上去掉了边距... ... 这是一个重要的用例,我还没有一个很好的解决方案。

问题: 如何在 Matplotlib 获取固定的像素高度、固定的数据 x/y 长宽比,并自动删除水平空白边?

宽度控制

如果你真的需要一个特定的宽度除了高度,这似乎工作正常:

Width.py

#!/usr/bin/env python3


import sys


import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl


h = int(sys.argv[1])
w = int(sys.argv[2])
fig, ax = plt.subplots()
wi, hi = fig.get_size_inches()
fig.set_size_inches(hi*(w/h), hi)
t = np.arange(-10., 10., 1.)
plt.plot(t, t, '.')
plt.plot(t, t**2, '.')
ax.text(0., 60., 'Hello', fontdict=dict(size=25))
plt.savefig(
'width.png',
format='png',
dpi=h/hi
)

跑步:

./width.py 431 869

产出:

width.png PNG 869x431 869x431+0+0 8-bit sRGB 10965B 0.000u 0:00.000

Enter image description here

而且宽度很小:

./width.py 431 869

产出:

width.png PNG 211x431 211x431+0+0 8-bit sRGB 6949B 0.000u 0:00.000

Enter image description here

所以看起来字体的缩放是正确的,我们只是在很小的宽度上遇到了一些问题,标签被切断,例如左上角的 100

我设法解决了 删除已保存图像周围的空白的问题

plt.tight_layout(pad=1)

它给出了:

width.png PNG 211x431 211x431+0+0 8-bit sRGB 7134B 0.000u 0:00.000

Enter image description here

从这里,我们还可以看到,tight_layout删除了图像顶部的大量空白,所以我通常总是使用它。

固定魔术基地高度,fig.set_size_inchesplt.savefig(dpi=上的 dpi缩放

我相信这与 https://stackoverflow.com/a/13714720/895245中提到的方法是一样的

魔术

#!/usr/bin/env python3


import sys


import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl


magic_height = 300
w = int(sys.argv[1])
h = int(sys.argv[2])
dpi = 80
fig, ax = plt.subplots(dpi=dpi)
fig.set_size_inches(magic_height*w/(h*dpi), magic_height/dpi)
t = np.arange(-10., 10., 1.)
plt.plot(t, t, '.')
plt.plot(t, t**2, '.')
ax.text(0., 60., 'Hello', fontdict=dict(size=25))
plt.savefig(
'magic.png',
format='png',
dpi=h/magic_height*dpi,
)

跑步:

./magic.py 431 231

产出:

magic.png PNG 431x231 431x231+0+0 8-bit sRGB 7923B 0.000u 0:00.000

Enter image description here

为了看看它是否适合放大:

./magic.py 1291 693

产出:

magic.png PNG 1291x693 1291x693+0+0 8-bit sRGB 25013B 0.000u 0:00.000

Enter image description here

所以我们看到这种方法也很有效。我遇到的唯一问题是必须设置 magic_height参数或等效参数。

固定 DPI + set_size_inches

这种方法给出了一个稍微错误的像素大小,并且它使得很难无缝地缩放所有东西。

Set _ size _ inch. py

#!/usr/bin/env python3


import sys


import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl


w = int(sys.argv[1])
h = int(sys.argv[2])
fig, ax = plt.subplots()
fig.set_size_inches(w/fig.dpi, h/fig.dpi)
t = np.arange(-10., 10., 1.)
plt.plot(t, t, '.')
plt.plot(t, t**2, '.')
ax.text(
0,
60.,
'Hello',
# Keep font size fixed independently of DPI.
# https://stackoverflow.com/questions/39395616/matplotlib-change-figsize-but-keep-fontsize-constant
fontdict=dict(size=10*h/fig.dpi),
)
plt.savefig(
'set_size_inches.png',
format='png',
)

跑步:

./set_size_inches.py 431 231

产出:

set_size_inches.png PNG 430x231 430x231+0+0 8-bit sRGB 8078B 0.000u 0:00.000

所以高度略有偏差,图像:

Enter image description here

如果我把它放大3倍,像素大小也是正确的:

./set_size_inches.py 1291 693

产出:

set_size_inches.png PNG 1291x693 1291x693+0+0 8-bit sRGB 19798B 0.000u 0:00.000

Enter image description here

然而,我们从中了解到,为了使这种方法能够很好地进行伸缩,您需要使每个依赖于 DPI 的设置与大小成正比(以英寸为单位)。

在前面的示例中,我们只使“ Hello”文本成比例,并且它的高度确实保持在60到80之间,正如我们所预期的那样。但是所有我们没有这么做的东西,看起来都很小,包括:

  • 轴线宽度轴线宽度
  • 勾选标签
  • 点标记

SVG

我找不到如何为 SVG 图像设置它,我的方法只适用于 PNG,例如:

Get _ size _ svg. py

#!/usr/bin/env python3


import sys


import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl


height = int(sys.argv[1])
fig, ax = plt.subplots()
t = np.arange(-10., 10., 1.)
plt.plot(t, t, '.')
plt.plot(t, t**2, '.')
ax.text(0., 60., 'Hello', fontdict=dict(size=25))
plt.savefig(
'get_size_svg.svg',
format='svg',
dpi=height/fig.get_size_inches()[1]
)

跑步:

./get_size_svg.py 431

生成的输出包含:

<svg height="345.6pt" version="1.1" viewBox="0 0 460.8 345.6" width="460.8pt"

身份证上写着:

get_size_svg.svg SVG 614x461 614x461+0+0 8-bit sRGB 17094B 0.000u 0:00.000

如果我在 Chromium 86中打开它,浏览器调试工具鼠标悬停图像确认高度为460.79。

但是当然,因为 SVG 是一种矢量格式,所以理论上所有东西都应该是等比例的,所以你可以直接转换成任何固定大小的格式,而不会丢失分辨率,例如:

inkscape -h 431 get_size_svg.svg -b FFF -e get_size_svg.png

给出了确切的高度:

Enter image description here

我在这里使用的是 墨迹而不是 图像魔术convert,因为你也需要混淆 -density来使用 ImageMagick 获得清晰的 SVG 调整大小:

在 HTML 中设置 <img height=""对于浏览器也是适用的。

在 matplotlib 3.2.2上进行了测试。