繁体   English   中英

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

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

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

savefig指定已保存图形的DPI(如果未在.matplotlibrc中指定,则默认值为100,请查看savefig的dpi savefig )。 它并没有从原始数字的DPI中得到它。

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

例如

import matplotlib.pyplot as plt

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

您将matplotlib图表渲染到不同的设备(例如,通过石英在屏幕上使用不同的函数( plot vs savefig )通过pdf 渲染到参数几乎相同,但这些参数的默认值不相同两个功能。

换句话说,在savefig默认参数是默认的显示参数不同

如果你在matplotlib配置文件中执行它们,那么对齐它们很简单。 模板文件包含在源包中,名为matplotlibrc.template 如果您在安装matplotlib时没有创建一个,则可以从matplotlib源或matplotlib网站获取此模板。

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

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

特别是,您需要查看以下内容:

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() ,从matplotlibrc.template中的277a 开始(此部分前面是行:### FIGURE):

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

正如你可以通过比较参数这两个块的值看,对于相同的人物的属性的默认设置是用于savefig显示器 (显示) 不同

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

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

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()图像的问题。

我已经在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()图像会出现不同,即使我将savefig dpi设置为与图dpi相同。 因此,我没有像上面那样更改源代码,而是将figure.dpi设置保留为默认值80,并且能够使用savefig()生成图像,该图像看起来像是show()中的图像。

莱昂,你有没改变过这个环境?

暂无
暂无

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

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