【问题标题】:matplotlib pyplot show capture imagematplotlib pyplot 显示捕获图像
【发布时间】:2015-09-16 15:47:13
【问题描述】:

在 python 交互式会话中,运行以下代码:

import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.show()

如何让 show() 不阻塞也不实际显示图像,而是将其存储在文件中? 我无法将代码更改为plt.savefig('figure.png')。 (有一个很好的理由,如果有兴趣,我可以解释。)

要走的路似乎是指定一个自定义后端渲染器,但到目前为止还没有成功。是否可以采用现有的后端渲染器并更改 show() 方法以保存到文件? (让我们说“figure%d.png”和 %d 到目前为止 show() 被调用的次数。)

也欢迎自定义后端渲染器旁边的其他建议。在 IPython 笔记本中,如果您执行 plt.show(),它会设法获取图像并将其放在活动代码块的下方。这是怎么做到的?

【问题讨论】:

  • 我对您的需求背后的原因非常感兴趣。您能否解释一下为什么不能使用 plt.savefig() 代替?顺便说一句,你可以让 show() 不阻塞只使用 plt.show(block=False)。它会在返回提示时显示图像。
  • @Alejandro 我想发送代码并在远程服务器上执行它。如果调用 plt.show() ,我希望服务器将图像存储在本地并将其作为响应发送回调用方,以便它可以简单地显示,就好像指令在本地执行一样。
  • 您也可以考虑http://mpld3.github.io/stackoverflow.com/questions/5515278/plot-matplotlib-on-the-web

标签: matplotlib ipython


【解决方案1】:

您可以使用here 的解决方案来创建没有 gui 的图形。这使用FigureCanvasAgg(这是default 构建的gui,你可能会使用不同的)。然后可以对 pyplot 中的节目进行猴子修补,

import matplotlib.pyplot as plt
from matplotlib.backends.backend_agg import FigureCanvasAgg

def show(fig=None):

    if fig == None:
        fig = plt.gcf()
    canvas = FigureCanvasAgg(fig)
    canvas.print_figure("./out.png", dpi=80)

plt.show = show    
plt.plot([1,2,3])
plt.show()

不确定这是否能避免您在使用 savefig 时遇到的问题?

【讨论】:

  • 我考虑过猴子补丁,但这带来了一个不同的问题。我可以在具有完全相同名称的新模块中修补 show 函数,以便代码 import matplotlib.pyplot as plt plt.plot([1,2,3]) plt.show() 可以工作吗?基本上将补丁从用户那里抽象出来。 (并且只是将带有补丁的新模块放在工作目录中?)
  • 由于您想在服务器上运行它并且 从不 计划显示显示窗口,我想您可以将 matplotlib 服务器代码更改为 show(使用调用时的警告消息)。也许更明确的是定义 matplotlib 模块的自定义版本以在您的服务器上使用,该模块导入和修补您需要的任何功能(使用pypi.python.org/pypi/wrapt)。
【解决方案2】:

我最终为 matplotlib 创建了一个自定义后端。在 matplotlib 包中有一个 backends 文件夹,其中包含一个 backend_template.py。

从此我基本上删除了除了函数shownew_figure_managernew_figure_manager_given_figure 之外的所有内容。后者我稍微适应了一下:

canvas = FigureCanvasAgg(figure)
manager = FigureManagerBase(canvas, num)
return manager

我没有修改new_figure_manager,并在文件末尾设置了FigureCanvas = FigureCanvasAgg,这样我基本上可以重用Agg 后端的大部分功能。然后你可以随意实现show函数。

最后一步是设置matplotlibrc配置文件并添加一行backend : module://matplotlib_custom_backend

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 2017-07-27
    • 1970-01-01
    相关资源
    最近更新 更多