matplotlib savefig() 绘图与 show() 不同

发布于 2024-12-11 22:54:25 字数 268 浏览 3 评论 0原文

当我使用 show()X 中绘制图形时,图形看起来非常好。但是,当我开始使用 savefig() 生成大量图形时,savefig() 生成的图形 ' 字体、线条、多边形看起来都比 show() 生成的图形小。我的环境是 Ubuntu,show() 的后端是 Qt4Agg。如何使 show() 图和 savefig() 图看起来一致?

When I use show() to plot the graphs in X, the graphs looks very good. However when I start to use savefig() to generate large amount of graphs, the savefig() generated graphs
' font, lines, polygons all look smaller than the show() generated graph. My environment is Ubuntu and the backend for show() is Qt4Agg. How can I make the show() plot and the savefig() plot looks consistent?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甜是你 2024-12-18 22:54:25

savefig 指定保存图形的 DPI(如果未在 .matplotlibrc 中指定,则默认值为 100,请查看 dpi kwarg 到savefig)。它并不是从原始图形的 DPI 继承的。

DPI 会影响文本的相对大小和线条上笔画的宽度等。如果您希望内容看起来相同,请将 fig.dpi 传递给 fig.savefig

例如

import matplotlib.pyplot as plt

fig = plt.figure()
plt.plot(range(10))
fig.savefig('temp.png', dpi=fig.dpi)

savefig specifies the DPI for the saved figure (The default is 100 if it's not specified in your .matplotlibrc, have a look at the dpi kwarg to savefig). It doesn't inheret it from the DPI of the original figure.

The DPI affects the relative size of the text and width of the stroke on lines, etc. If you want things to look identical, then pass fig.dpi to fig.savefig.

E.g.

import matplotlib.pyplot as plt

fig = plt.figure()
plt.plot(range(10))
fig.savefig('temp.png', dpi=fig.dpi)
衣神在巴黎 2024-12-18 22:54:25

老问题,但显然谷歌喜欢它,所以我想在对这个问题进行一些研究后我把答案放在这里。

如果您从头开始创建图形,则可以在创建时为其指定大小选项:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(3, 6))

plt.plot(range(10)) #plot example
plt.show() #for control

fig.savefig('temp.png', dpi=fig.dpi)

figsize(width,height) 调整绘图的绝对尺寸,并有助于确保两个绘图看起来相同。

正如另一个答案中所述,dpi 选项会影响文本的相对大小和线条上笔画的宽度等。使用选项 dpi=fig.dpi 可确保show()savefig() 的相对大小是相同的。

或者,可以在创建后更改图形大小:

fig.set_size_inches(3, 6, forward=True)

forward 允许动态更改大小。

如果您在创建的图像中遇到太大边框的问题,您可以使用以下方法调整边框:

plt.tight_layout()
#or:
plt.tight_layout(pad=2)

或者:

fig.savefig('temp.png', dpi=fig.dpi, bbox_inches='tight')
#or:
fig.savefig('temp.png', dpi=fig.dpi, bbox_inches='tight', pad_inches=0.5)

第一个选项只是最小化布局和边框,第二个选项允许手动调整边框。这些技巧至少帮助我解决了不同 savefig()show() 图像的问题。

Old question, but apparently Google likes it so I thought I put an answer down here after some research about this problem.

If you create a figure from scratch you can give it a size option while creation:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(3, 6))

plt.plot(range(10)) #plot example
plt.show() #for control

fig.savefig('temp.png', dpi=fig.dpi)

figsize(width,height) adjusts the absolute dimension of your plot and helps to make sure both plots look the same.

As stated in another answer the dpi option affects the relative size of the text and width of the stroke on lines, etc. Using the option dpi=fig.dpi makes sure the relative size of those are the same both for show() and savefig().

Alternatively the figure size can be changed after creation with:

fig.set_size_inches(3, 6, forward=True)

forward allows to change the size on the fly.

If you have trouble with too large borders in the created image you can adjust those either with:

plt.tight_layout()
#or:
plt.tight_layout(pad=2)

or:

fig.savefig('temp.png', dpi=fig.dpi, bbox_inches='tight')
#or:
fig.savefig('temp.png', dpi=fig.dpi, bbox_inches='tight', pad_inches=0.5)

The first option just minimizes the layout and borders and the second option allows to manually adjust the borders a bit. These tips helped at least me to solve my problem of different savefig() and show() images.

吝吻 2024-12-18 22:54:25

您将 matplotlib 绘图渲染到不同的设备(例如,通过 Quartz 在屏幕上显示,与使用不同函数通过 pdf 呈现到文件(plotsavefig),其参数几乎相同,但这些参数的默认值对于两个函数来说并不相同

savefig 默认参数默认display 参数

对齐很简单 。如果您在matplotlib配置文件中执行此操作,则模板文件包含在源包中,并命名为matplotlibrc.template。安装matplotlib时没有创建一个,你可以得到这个模板来自 matplotlib 源,或来自 matplotlib 网站

。您想要的,将其重命名为 matplotlibrc (无扩展名)并将其保存到目录 .matplotlib (注意开头的“.”)应该位于您的主目录中。

用于保存图形的配置参数从提供的matplotlibrc.template中的大约第314行开始(本节之前的第一行是: ### SAVING数字)。

特别是,您需要查看这些:

savefig.dpi       : 100         # figure dots per inch
savefig.facecolor : white       # figure facecolor when saving
savefig.edgecolor : white       # figure edgecolor when saving
savefig.extension : auto        # what extension to use for savefig('foo'), or 'auto'

这些行下面是字体类型和各种特定于图像格式的参数的设置。

这些相同的参数用于显示,即PLT.show(),大​​约从第277行开始matplotlibrc.template(本节前面有一行:###Figure):

figure.figsize   : 8, 6          
figure.dpi       : 80            
figure.facecolor : 0.75       
figure.edgecolor : white     

通过比较这两个参数块的值可以看到,同一图形属性的默认设置为 >不同对于savefigdisplay(显示)。

You render your matplotlib plots to different devices (e.g., on-screen via Quartz versus to to-file via pdf using different functions (plot versus savefig) whose parameters are nearly the same, yet the default values for those parameters are not the same for both functions.

Put another way, the savefig default parameters are different from the default display parameters.

Aligning them is simple if you do it in the matplotlib config file. The template file is included with the source package, and named matplotlibrc.template. If you did not create one when you installed matplotlib, you can get this template from the matplotlib source, or from the matplotlib website.

Once you have customized this file the way you want, rename it to matplotlibrc (no extension) and save it to the directory .matplotlib (note the leading '.') which should be in your home directory.

The config parameters for saving figures begins at about line 314 in the supplied matplotlibrc.template (first line before this section is: ### SAVING FIGURES).

In particular, you will want to look at these:

savefig.dpi       : 100         # figure dots per inch
savefig.facecolor : white       # figure facecolor when saving
savefig.edgecolor : white       # figure edgecolor when saving
savefig.extension : auto        # what extension to use for savefig('foo'), or 'auto'

Below these lines are the settings for font type and various image format-specific parameters.

These same parameters for display, i.e., PLT.show(), begin at about line 277 a in the matplotlibrc.template (this section preceded with the line: ### FIGURE):

figure.figsize   : 8, 6          
figure.dpi       : 80            
figure.facecolor : 0.75       
figure.edgecolor : white     

As you can see by comparing the values of these two blocks of parameters, the default settings for the same figure attribute are different for savefig versus display (show).

痴情 2024-12-18 22:54:25

我已经在 matplotlib 源代码中修复了这个问题,但这并不是一个很好的修复。但是,如果您像我一样非常注重图表的外观,那么这是值得的。

问题似乎出在渲染后端;它们都获得了正确的线宽、字体大小等值,但渲染为 PDF 或 PNG 时的值比使用 show() 渲染时的值稍大。

我在文件 matplotlib/backends/backend_agg.py 中添加了几行用于 PNG 生成的源代码。您可以对您使用的每个后端进行类似的更改,或者找到一种方法在单个位置进行更巧妙的更改;)

添加到我的 matplotlib/backends/backend_agg.py 文件中:

    # The top of the file, added lines 42 - 44
42  # @warning: CHANGED FROM SOURCE to draw thinner lines
43  PATH_SCALAR = .8
44  FONT_SCALAR = .95

    # In the draw_markers method, added lines 90 - 91
89  def draw_markers(self, *kl, **kw):
90      # @warning: CHANGED FROM SOURCE to draw thinner lines
91      kl[0].set_linewidth(kl[0].get_linewidth()*PATH_SCALAR)
92      return self._renderer.draw_markers(*kl, **kw)

    # At the bottom of the draw_path method, added lines 131 - 132:
130 else:
131     # @warning: CHANGED FROM SOURCE to draw thinner lines
132     gc.set_linewidth(gc.get_linewidth()*PATH_SCALAR)
133     self._renderer.draw_path(gc, path, transform, rgbFace)

    # At the bottom of the _get_agg_font method, added line 242 and the *FONT_SCALAR
241     font.clear()
242     # @warning: CHANGED FROM SOURCE to draw thinner lines
243     size = prop.get_size_in_points()*FONT_SCALAR
244     font.set_size(size, self.dpi)

所以这适合我现在的需求,但是,取决于根据您正在做的事情,您可能希望在其他方法中实现类似的更改。或者找到一种更好的方法来完成同样的事情,而无需进行如此多的线路更改!

更新: 在 Github 上向 matplotlib 项目发布问题后,我能够找到问题的根源:我更改了 matplotlibrc 文件中的figure.dpi 设置。如果该值与默认值不同,即使我将 savefig dpi 设置为与图形 dpi 相同,我的 savefig() 图像也会有所不同。因此,我没有像上面那样更改源,而是将figure.dpi设置保留为默认80,并且能够使用savefig()生成看起来像show()中的图像的图像。

Leon,你也改变了那个设置吗?

I have fixed this in my matplotlib source, but it's not a pretty fix. However, if you, like me, are very particular about how the graph looks, it's worth it.

The issue seems to be in the rendering backends; they each get the correct values for linewidth, font size, etc., but that comes out slightly larger when rendered as a PDF or PNG than when rendered with show().

I added a few lines to the source for PNG generation, in the file matplotlib/backends/backend_agg.py. You could make similar changes for each backend you use, or find a way to make a more clever change in a single location ;)

Added to my matplotlib/backends/backend_agg.py file:

    # The top of the file, added lines 42 - 44
42  # @warning: CHANGED FROM SOURCE to draw thinner lines
43  PATH_SCALAR = .8
44  FONT_SCALAR = .95

    # In the draw_markers method, added lines 90 - 91
89  def draw_markers(self, *kl, **kw):
90      # @warning: CHANGED FROM SOURCE to draw thinner lines
91      kl[0].set_linewidth(kl[0].get_linewidth()*PATH_SCALAR)
92      return self._renderer.draw_markers(*kl, **kw)

    # At the bottom of the draw_path method, added lines 131 - 132:
130 else:
131     # @warning: CHANGED FROM SOURCE to draw thinner lines
132     gc.set_linewidth(gc.get_linewidth()*PATH_SCALAR)
133     self._renderer.draw_path(gc, path, transform, rgbFace)

    # At the bottom of the _get_agg_font method, added line 242 and the *FONT_SCALAR
241     font.clear()
242     # @warning: CHANGED FROM SOURCE to draw thinner lines
243     size = prop.get_size_in_points()*FONT_SCALAR
244     font.set_size(size, self.dpi)

So that suits my needs for now, but, depending on what you're doing, you may want to implement similar changes in other methods. Or find a better way to do the same without so many line changes!

Update: After posting an issue to the matplotlib project at Github, I was able to track down the source of my problem: I had changed the figure.dpi setting in the matplotlibrc file. If that value is different than the default, my savefig() images come out different, even if I set the savefig dpi to be the same as the figure dpi. So, instead of changing the source as above, I just kept the figure.dpi setting as the default 80, and was able to generate images with savefig() that looked like images from show().

Leon, had you also changed that setting?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文