3

I'm currently trying to animate a scatterplot of monthly data saved in a pandas dataframe. So far I made loop, which generates one single plot after another. Now I would like to join them in a single gif (or mp4 I don't care). Is there an easy way to make use of mathplotlibs animation function? I can't get my head around, how to loop sliced data through FuncAnimation. So far I did this:

time = df.monat.unique()
for i in time:
    dft = df[(df.monat == i) & (df.xcol < 4000)]
    plt.scatter(x=dft['xcol'],
            y=dft['ycol'],
            s=dft['scol'] / 25,
            c=dft['clr'],
            linewidth=0,
            alpha=0.8)
    plt.title('Title ' + str(i), fontsize=10)
    plt.xlabel('x label', fontsize=9)
    plt.ylabel('y label', fontsize=9)
    legend1_line2d = list()
    for val in clrdict.values():
        legend1_line2d.append(mlines.Line2D([0], [0],
            linestyle='none',
            marker='o',
            alpha=0.6,
            markersize=6,
            markeredgecolor=None,
            markeredgewidth=0,
            markerfacecolor=val))
    legend1 = plt.legend(legend1_line2d,
             names,
             frameon=False,
             numpoints=1,
             fontsize=8,
             loc='upper right') 
    plt.show()

1 Answer 1

3

I figured it out by myself:

Generate an empty plot (fig). Like before all unique time-values are stored in a series(time). A simple counter (i) helps generating the correct slice of the data (dft) for each month (df.monat == a value from the series 'time') within the update-function. The update-function is called times the value of the frame-parameter in the anim.FuncAnimation (frames=len(time)).

Hope, this will be helpful for somebody else (most of the explanations for the matplotlib FuncAnimation I've found worked with random numbers - not with specific pandas columns):

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.lines as mlines
import matplotlib.animation as anim

...

time = df.monat.unique()    
fig = plt.figure()
i = 1

def update(i):
        plt.clf()
        dft = df[(df.monat == time[i]) & (df.xcol < 4000)]
        plt.scatter(x=dft['xcol'],
                    y=dft['ycol'],
                    s=dft['scol'] / 25,
                    c=dft['clr'],
                    linewidth=0,
                    alpha=0.8)
        plt.title('Title ' + str(time[i]), fontsize=10)
        plt.xlabel('x label', fontsize=9)
        plt.ylabel('y label', fontsize=9)
        plt.xlim(0, 900)  # fixed dimensions x
        plt.ylim(-5, 100) # fixed dimensions y 
        legend1_line2d = list()
        for val in clrdict.values():
            legend1_line2d.append(mlines.Line2D([0], [0],
                    linestyle='none',
                    marker='o',
                    alpha=0.6,
                    markersize=6,
                    markeredgecolor=None,
                    markeredgewidth=0,
                    markerfacecolor=val))
        legend1 = plt.legend(legend1_line2d,
                    names,
                    frameon=False,
                    numpoints=1,
                    fontsize=8,
                    loc='upper right')
        i += 1

ani = anim.FuncAnimation(fig, update, frames=len(time), interval=500)
# plt.show() # this will show the ani over and over
ani.save("test.mp4", dpi=200, fps=1, codec="libx264", bitrate=5000, extra_args=['-pix_fmt', 'yuv420p'])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.