【问题标题】:matplotlib show figure againmatplotlib 再次显示图
【发布时间】:2014-03-30 17:54:26
【问题描述】:

使用 matplotlib 时:

from matplotlib import pyplot as plt

figure = plt.figure()

ax = figure.add_subplot(111)
ax.plot(x,y)

figure.show()  # figure is shown in GUI

# How can I view the figure again after I closed the GUI window?

figure.show()  # Exception in Tkinter callback... TclError: this isn't a Tk application
figure.show()  # nothing happened

所以我的问题是:

  1. 如果我调用了 figure.show(),如何找回之前的情节?

  2. 如果我有多个数字,figure.add_suplot(111) 是否有更方便的替代方案,因此from pylab import *; plot(..); show() 似乎不是我正在寻找的解决方案。

而我迫切想要的是

showfunc(stuff) # or
stuff.showfunc()

其中stuff 是一个对象,其中包含排列在一张图片中的所有图,showfunc 是无状态的(我的意思是,每次调用它时,我的行为就像是第一次调用它一样)。与matplotlib 合作时这可能吗?

【问题讨论】:

  • 不清楚这里的问题是什么。你指的是之前的哪个情节?
  • @ebarr 我的意思是,我如何在关闭 GUI 窗口后再次查看该图?再次创建figureplot?我认为应该有更好的方法来做到这一点。
  • 所以show 应该只在脚本中运行一次,因为它会启动 Tk 主循环运行。文档说“版本 v1.0.0 中的新功能:show 现在仅在 GUI 主循环尚未运行时才启动它。因此,现在允许对 show 进行多次调用。”。您能否添加更多有关您需要此功能的信息?您是在构建 GUI,还是只想一个接一个地查看图表?
  • 你使用的是什么版本的matplotlib
  • @ebarr 看图一个接一个。

标签: python matplotlib


【解决方案1】:

我找不到满意的答案,所以我通过编写自定义Figure 类扩展matplotlib.figure.Figure 并提供新的show() 方法来处理这个问题,该方法每次调用都会创建一个gtk.Window 对象。

import gtk
import sys
import os
import threading

from matplotlib.figure import Figure as MPLFigure
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas
from matplotlib.backends.backend_gtkagg import NavigationToolbar2GTKAgg as NaviToolbar


class ThreadFigure(threading.Thread):
    def __init__(self, figure, count):
        threading.Thread.__init__(self)
        self.figure =   figure
        self.count  =   count
    def run(self):
        window  =   gtk.Window()
        # window.connect('destroy', gtk.main_quit)

        window.set_default_size(640, 480)
        window.set_icon_from_file(...)  # provide an icon if you care about the looks

        window.set_title('MPL Figure #{}'.format(self.count))
        window.set_wmclass('MPL Figure', 'MPL Figure')

        vbox    =   gtk.VBox()
        window.add(vbox)

        canvas  =   FigureCanvas(self.figure)
        vbox.pack_start(canvas)

        toolbar =   NaviToolbar(canvas, window)
        vbox.pack_start(toolbar, expand = False, fill = False)

        window.show_all()
        # gtk.main() ... should not be called, otherwise BLOCKING


class Figure(MPLFigure):
    display_count = 0
    def show(self):
        Figure.display_count += 1 
        thrfig = ThreadFigure(self, Figure.display_count)
        thrfig.start()

将此文件设为IPython 的起始文件。和

figure = Figure()
ax = figure.add_subplot(211)
... (same story as using standard `matplotlib.pyplot` )
figure.show()

# window closed accidentally or intentionally...

figure.show()
# as if `.show()` is never called

有效!我从未接触过 GUI 编程,也不知道这是否会产生任何副作用。如果您认为应该这样做,请随意发表评论。

【讨论】:

  • 这一定是我遇到过的最有用的 matplotlib 解决方法之一。这个解决方案做得很好。摆脱神秘的 Tcl/Tk 窗口系统并进入 Gtk 确实是一种解放,并解决了许多其他与线程相关的 matplotlib 不当行为等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多