当在figure 实例上调用plt.close 时,实际上被破坏的是用于在屏幕上显示图形的图形界面(FigureManager)(参见 JoeKington 的评论在Matplotlib: re-open a closed figure?)。所以图形实例仍然存在并且没有被销毁。为了再次在屏幕上显示该图形,我们必须以某种方式重建一个接口,以替换在调用plt.close(fig) 时被破坏的接口。
这可以通过简单地使用plt.figure() 创建一个新图形来完成,“窃取”它的管理器,并使用它来显示我们想要在屏幕上显示的图形。或者,可以手动重建界面以使用 GUI 工具包显示图形。我提供了一个使用 Qt4Agg 后端的 PySide 示例。此外,这里有一个很好的例子,展示了如何使用 Tkinter (TkAgg) 完成此操作:http://matplotlib.org/examples/user_interfaces/embedding_in_tk.html(我也测试过这种方法并且它有效)。
假人方法:
此解决方案基于how to close a show() window but keep the figure alive? 和Obtaining the figure manager via the OO interface in Matplotlib。用于构建在屏幕上显示图形的图形界面的 GUI 工具包依赖于 matplotlib 使用的backend。如果使用的后端是 TkAgg,TkInter 将在 Python 2.7 中给出一些可以忽略的警告(参见 post on python bug tracker)。
import matplotlib.pyplot as plt
def new_figure():
fig = plt.figure()
plt.plot([0, 1], [2, 3])
plt.close(fig)
return fig
def show_figure(fig):
# create a dummy figure and use its
# manager to display "fig"
dummy = plt.figure()
new_manager = dummy.canvas.manager
new_manager.canvas.figure = fig
fig.set_canvas(new_manager.canvas)
if __name__ == '__main__':
fig = new_figure()
show_figure(fig)
plt.show()
Pyside 方法:
这包括使用新的画布和工具栏重建 GUI,以在屏幕上显示 fig 实例。
重要提示:如果从Spyder 运行,下面的代码必须在新的专用 Python 控制台中执行(按 F6),因为 Spyder 也是一个启动它自己的 QApplication 的 Qt 应用程序(参见PySide Qt script doesn't launch from Spyder but works from shell)。
import matplotlib
matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4']='PySide'
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT
import matplotlib.pyplot as plt
from PySide import QtGui
import sys
def new_figure():
fig = plt.figure()
plt.plot([0, 1], [2, 3])
plt.close(fig)
return fig
class myFigCanvas(QtGui.QWidget):
def __init__(self, fig, parent=None):
super(myFigCanvas, self).__init__(parent)
#---- create new canvas and toolbar --
canvas = FigureCanvasQTAgg(fig)
toolbar = NavigationToolbar2QT(canvas, self)
#---- setup layout of GUI ----
grid = QtGui.QGridLayout()
grid.addWidget(canvas, 0, 0)
grid.addWidget(toolbar, 1, 0)
self.setLayout(grid)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
fig = new_figure()
new_canvas = myFigCanvas(fig)
new_canvas.show()
sys.exit(app.exec_())
导致: