matplotlib show figure again

matplotlib, python

Solution

I can't find a satisfactory answer, so I handle this problem by writing a custom `Figure` class extending `matplotlib.figure.Figure` and providing a new `show()` method, which create a `gtk.Window` object each time called.

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()

Make this file as start file of `IPython`. And

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

Works! I never touched GUI programming, and don't know if this would have any side-effect. Comment freely if you think something should be done that way.

Problem

When using 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 ``` So my questions are: How can I get the previous plot back if I have called figure.show()? Is there a more convenient alternative to `figure.add_suplot(111)` if I have multiple figures and thus `from pylab import *; plot(..); show()` seems not a solution I'm looking for. And what I eagerly want is ``` showfunc(stuff) # or stuff.showfunc() ``` where `stuff` is an object containing all the plots arranged in one picture, and `showfunc` is STATELESS(I mean, each time I call it, I behaves as if it's first time called). Is this possible when working with `matplotlib`?

Original source

Related problems