Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matplotlib sequence of figures in the same window

I'm testing an algorithm and I'd like to produce a sequence of figures displaying intermediate results using matplotlib.

I'm not needing animations, nor multiple figures all on the screens, nor subplots.

I'd just like to produce a sequence of figures (possibly using pyplot), and when I'm done, a single window is shown. Then I'd like to navigate in the sequence of figures using the arrows.

How can I do something like that?

I tried to search, but I can only find subplot or multiple figures on the screen.

Thanks

like image 208
AkiRoss Avatar asked Nov 18 '12 19:11

AkiRoss


People also ask

How do you plot multiple graphs on the same window in Python?

In Matplotlib, we can draw multiple graphs in a single plot in two ways. One is by using subplot() function and other by superimposition of second graph on the first i.e, all graphs will appear on the same plot.

How do I show multiple figures in matplotlib?

The easiest way to display multiple images in one figure is use figure(), add_subplot(), and imshow() methods of Matplotlib. The approach which is used to follow is first initiating fig object by calling fig=plt. figure() and then add an axes object to the fig by calling add_subplot() method.

How do I display multiple images in one figure correctly in matplotlib?

MatPlotLib with PythonCreate random data using numpy. Add a subplot to the current figure, nrows=1, ncols=4 and at index=1. Display data as an image, i.e., on a 2D regular raster, using imshow() method with cmap="Blues_r". Add a subplot to the current figure, nrows=1, ncols=4 and at index=2.

Can a matplotlib figure have more than one set of axes?

Sometimes it is natural to have more than one distinct group of Axes grids, in which case Matplotlib has the concept of SubFigure : SubFigure. A virtual figure within a figure.


1 Answers

The most general approach is to create a sequence of axes in the same figure, and only display one at a time.

Here's an example of that (The left and right arrow keys control which plot is displayed):

import matplotlib.pyplot as plt
import numpy as np

def main():
    x = np.linspace(0, 10, 100)
    axes = AxesSequence()
    for i, ax in zip(range(3), axes):
        ax.plot(x, np.sin(i * x))
        ax.set_title('Line {}'.format(i))
    for i, ax in zip(range(5), axes):
        ax.imshow(np.random.random((10,10)))
        ax.set_title('Image {}'.format(i))
    axes.show()

class AxesSequence(object):
    """Creates a series of axes in a figure where only one is displayed at any
    given time. Which plot is displayed is controlled by the arrow keys."""
    def __init__(self):
        self.fig = plt.figure()
        self.axes = []
        self._i = 0 # Currently displayed axes index
        self._n = 0 # Last created axes index
        self.fig.canvas.mpl_connect('key_press_event', self.on_keypress)

    def __iter__(self):
        while True:
            yield self.new()

    def new(self):
        # The label needs to be specified so that a new axes will be created
        # instead of "add_axes" just returning the original one.
        ax = self.fig.add_axes([0.15, 0.1, 0.8, 0.8], 
                               visible=False, label=self._n)
        self._n += 1
        self.axes.append(ax)
        return ax

    def on_keypress(self, event):
        if event.key == 'right':
            self.next_plot()
        elif event.key == 'left':
            self.prev_plot()
        else:
            return
        self.fig.canvas.draw()

    def next_plot(self):
        if self._i < len(self.axes):
            self.axes[self._i].set_visible(False)
            self.axes[self._i+1].set_visible(True)
            self._i += 1

    def prev_plot(self):
        if self._i > 0:
            self.axes[self._i].set_visible(False)
            self.axes[self._i-1].set_visible(True)
            self._i -= 1

    def show(self):
        self.axes[0].set_visible(True)
        plt.show()

if __name__ == '__main__':
    main()

If they're all the same type of plot, you could just update the data of the artists involved. This is especially easy if you have the same number of items in each plot. I'll leave out an example for the moment, but if the example above is too memory-hungry, just updating the data of the artists will be considerably lighter.

like image 120
Joe Kington Avatar answered Oct 13 '22 10:10

Joe Kington