How to animate a time-ordered sequence of matplotlib plots

后端 未结 3 1186
悲&欢浪女
悲&欢浪女 2020-12-14 03:20

I want to plot a sequence of .png images in matplotlib. The goal is to plot them rapidly to simulate the effect of a movie, but I have additional reasons for wanting to avoi

相关标签:
3条回答
  • 2020-12-14 04:17

    I have implemented a handy script that just suits your need. Try it out here

    Below is a example that show images together with its bounding box:

    import os
    import glob
    from scipy.misc import imread
    from matplotlib.pyplot import Rectangle
    
    video_dir = 'YOUR-VIDEO-DIRECTORY'
    
    img_files = glob.glob(os.path.join(video_dir, '*.jpg'))
    box_files = glob.glob(os.path.join(video_dir, '*.txt'))
    
    def redraw_fn(f, axes):
        img = imread(img_files[f])
        box = bbread(box_files[f])  # Define your own bounding box reading utility
        x, y, w, h = box
        if not redraw_fn.initialized:
            im = axes.imshow(img, animated=True)
            bb = Rectangle((x, y), w, h,
                           fill=False,  # remove background
                           edgecolor="red")
            axes.add_patch(bb)
            redraw_fn.im = im
            redraw_fn.bb = bb
            redraw_fn.initialized = True
        else:
            redraw_fn.im.set_array(img)
            redraw_fn.bb.set_xy((x, y))
            redraw_fn.bb.set_width(w)
            redraw_fn.bb.set_height(h)
    redraw_fn.initialized = False
    
    videofig(len(img_files), redraw_fn, play_fps=30)
    
    0 讨论(0)
  • 2020-12-14 04:19

    The best way I have found for this was with the command pylab.ion() after you import pylab.

    Here is a script that does use show(), but which displays the different plots each time pylab.draw() is called, and which leaves the plot windows showing indefinitely. It uses simple input logic to decide when to close the figures (because using show() means pylab won't process clicks on the windows x button), but that should be simple to add to your gui as another button or as a text field.

    import numpy as np
    import pylab
    pylab.ion()
    
    def get_fig(fig_num, some_data, some_labels):
    
        fig = pylab.figure(fig_num,figsize=(8,8),frameon=False)
        ax = fig.add_subplot(111)
        ax.set_ylim([0.1,0.8]); ax.set_xlim([0.1, 0.8]);
        ax.set_title("Quarterly Stapler Thefts")
        ax.pie(some_data, labels=some_labels, autopct='%1.1f%%', shadow=True);
        return fig
    
    my_labels = ("You", "Me", "Some guy", "Bob")
    
    # To ensure first plot is always made.
    do_plot = 1; num_plots = 0;
    
    while do_plot:
        num_plots = num_plots + 1;
        data = np.random.rand(1,4).tolist()[0]
    
        fig = get_fig(num_plots,data,my_labels)
        fig.canvas.draw()
        pylab.draw()
    
        print "Close any of the previous plots? If yes, enter its number, otherwise enter 0..."
        close_plot = raw_input()
    
        if int(close_plot) > 0:
            pylab.close(int(close_plot))
    
        print "Create another random plot? 1 for yes; 0 for no."
        do_plot = raw_input();
    
        # Don't allow plots to go over 10.
        if num_plots > 10:
            do_plot = 0
    
    pylab.show()
    

    By modifying the basic logic here, I can have it close windows and plot images consecutively to simulate playing a movie, or I can maintain keyboard control over how it steps through the movie.

    Note: This has worked for me across platforms and seems strictly superior to the window canvas manager approach above, and doesn't require the 'TkAgg' option.

    0 讨论(0)
  • 2020-12-14 04:22

    Based on http://matplotlib.sourceforge.net/examples/animation/simple_anim_tkagg.html:

    import time
    import numpy as np
    import matplotlib
    matplotlib.use('TkAgg') # do this before importing pylab
    
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = fig.add_subplot(111)
    
    def animate():
        tstart = time.time()                   # for profiling
        data=np.random.randn(10,10)
        im=plt.imshow(data)
    
        for i in np.arange(1,200):
            data=np.random.randn(10,10)
            im.set_data(data)
            fig.canvas.draw()                         # redraw the canvas
        print 'FPS:' , 200/(time.time()-tstart)
    
    win = fig.canvas.manager.window
    fig.canvas.manager.window.after(100, animate)
    plt.show()
    

    plt.imshow can accept a float array, uint8 array, or a PIL image. So if you have a directory of PNG files, you could open them as PIL images and animate them like this:

    import matplotlib
    matplotlib.use('TkAgg') # do this before importing pylab
    import matplotlib.pyplot as plt
    import Image
    import glob
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    
    def animate():
        filenames=sorted(glob.glob('*.png'))
        im=plt.imshow(Image.open(filenames[0]))
        for filename in filenames[1:]:
            image=Image.open(filename)
            im.set_data(image)
            fig.canvas.draw() 
    
    win = fig.canvas.manager.window
    fig.canvas.manager.window.after(100, animate)
    plt.show()
    
    0 讨论(0)
提交回复
热议问题