简体   繁体   English

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

[英]matplotlib savefig() plots different from show()

When I use show() to plot the graphs in X , the graphs looks very good. 当我使用show()X绘制图形时,图形看起来非常好。 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. 但是当我开始使用savefig()生成大量图形时, savefig()生成的图形的字体,线条,多边形看起来都比show()生成的图形小。 My environment is Ubuntu and the backend for show() is Qt4Agg . 我的环境是Ubuntu, show()的后端是Qt4Agg How can I make the show() plot and the savefig() plot looks consistent? 如何使show()图和savefig()图看起来一致?

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 ). savefig指定已保存图形的DPI(如果未在.matplotlibrc中指定,则默认值为100,请查看savefig的dpi savefig )。 It doesn't inheret it from the DPI of the original figure. 它并没有从原始数字的DPI中得到它。

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 . DPI会影响文本的相对大小和线条上笔画的宽度等。如果您希望看起来相同, fig.dpi fig.savefig传递给fig.savefig

Eg 例如

import matplotlib.pyplot as plt

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

You render your matplotlib plots to different devices (eg, 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. 您将matplotlib图表渲染到不同的设备(例如,通过石英在屏幕上使用不同的函数( plot vs savefig )通过pdf 渲染到参数几乎相同,但这些参数的默认值不相同两个功能。

Put another way, the savefig default parameters are different from the default display parameters. 换句话说,在savefig默认参数是默认的显示参数不同

Aligning them is simple if you do it in the matplotlib config file . 如果你在matplotlib配置文件中执行它们,那么对齐它们很简单。 The template file is included with the source package, and named matplotlibrc.template . 模板文件包含在源包中,名为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 . 如果您在安装matplotlib时没有创建一个,则可以从matplotlib源或matplotlib网站获取此模板。

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. 按照自己的方式自定义此文件后,将其重命名为matplotlibrc (无扩展名)并将其保存到目录.matplotlib (注意前导'。'),该目录应位于您的主目录中。

The config parameters for saving figures begins at about line 314 in the supplied matplotlibrc.template (first line before this section is: ### SAVING FIGURES). 用于保存数字的配置参数从提供的matplotlibrc.template中的314行开始(本节前面的第一行是:### 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 , ie, PLT.show() , begin at about line 277 a in the matplotlibrc.template (this section preceded with the line: ### FIGURE): 用于显示的这些相同参数,即PLT.show() ,从matplotlibrc.template中的277a 开始(此部分前面是行:### 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). 正如你可以通过比较参数这两个块的值看,对于相同的人物的属性的默认设置是用于savefig显示器 (显示) 不同

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. figsize(width,height)调整绘图的绝对尺寸,有助于确保两个绘图看起来相同。

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() . 如另一个答案中所述, dpi选项会影响文本的相对大小和行上行程的宽度等。使用dpi = fig.dpi选项可确保show()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. forward允许动态改变大小。

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. 这些提示至少帮助我解决了我的不同savefig()show()图像的问题。

I have fixed this in my matplotlib source, but it's not a pretty fix. 我已经在matplotlib源代码中修复了这个问题,但这不是一个很好的修复方法。 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(). 它们每个都获得正确的线宽,字体大小等值,但是当渲染为PDF或PNG时,与使用show()渲染时相比,它会略大。

I added a few lines to the source for PNG generation, in the file matplotlib/backends/backend_agg.py. 我在文件matplotlib / backends / backend_agg.py中添加了几行代码来生成PNG。 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: 添加到我的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)

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

Leon, had you also changed that setting? 莱昂,你有没改变过这个环境?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM