Matplotlib: how to show a figure that has been closed

I have a function that returns a Figure created using pyplot . This function closes the shape before returning it. If I hadn’t closed it, it would have been very easy to show it using plt.show() , but suppose I cannot do this.

I can easily save the returned Figure to a file, but I cannot find a way to display it (i.e. it has a popup window with an image).

 from matplotlib import pyplot as plt def new_figure(): fig = plt.figure() plt.plot([0, 1], [2, 3]) plt.close(fig) return fig fig = new_figure() fig.savefig('output.svg') fig.show() 

How can I show a number?

+4
source share
1 answer

When plt.close is called on the figure instance, the graphical interface (FigureManager) is actually destroyed, which is used to display the figure on the screen (see JoeKington's comment in Matplotlib: reopen a closed digit? ). Thus, an instance of the figure still exists and has not been destroyed. To display the figure again on the screen, we would have to somehow restore the interface to replace the one that was destroyed when plt.close(fig) called.

You can do this by simply creating a new shape using plt.figure() , steal its manager and use it to display the shape we want to display on the screen. Alternatively, you can manually restore the interface for displaying a picture using the GUI toolkit. I will give an example of PySide using the Qt4Agg backend. In addition, there is a good example that shows how this can be done with Tkinter (TkAgg) here: http://matplotlib.org/examples/user_interfaces/embedding_in_tk.html (I tested this approach also and it works).

Layout Approach:

This solution is based on how to close the show () window, but keep the figure alive? and Receiving a drawing manager through the OO interface in Matplotlib . The GUI toolkit that is used to build the graphical interface for displaying a figure on the screen depends on the backend used by matplotlib. If the backend is used by TkAgg, TkInter will give some warning in Python 2.7 that can be ignored (see this post in the 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 Approach:

This is to restore the GUI with a new canvas and toolbar to display the fig instance on the screen.

Important note: The code below must be executed in a new dedicated Python console (press F6) if it is launched from Spyder , since Spyder is also a Qt application that launches its own QApplication (see PySide Qt script does not start 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_()) 

that leads to:

enter image description here

+8
source

Source: https://habr.com/ru/post/910260/


All Articles