Search code examples
pythonpandasmatplotlibanimationmatplotlib-animation

Animation of categorical data with matplotlib.animation.FuncAnimation


I try to animate categorical data with matplotlib.animation.FuncAnimation. However, I have not found a way to color the animated x y values according to their categories table. This is my data set DF:

         x      y  time   table
0    150.0  126.0     0  Table3
1    160.0  244.0     0  Table1
2    153.0  126.0     1  Table3
3    159.0  244.0     1  Table1
4    154.0  131.0     2  Table3
5    161.0  243.0     2  Table1
6    149.0  131.0     3  Table3
7    158.0  244.0     3  Table1
8    394.0  247.0     4  Table4
9    150.0  128.0     4  Table3
10   161.0  243.0     4  Table1
11   160.0  244.0     5  Table1
12   154.0  130.0     5  Table3
13   153.0  129.0     6  Table3
14   163.0  237.0     6  Table1
15   134.0  128.0     7  Table3
16   162.0  238.0     7  Table1
17   162.0  237.0     8  Table1
18   162.0  240.0     9  Table1
19   163.0  239.0    10  Table1
20   164.0  239.0    11  Table1
21   165.0  239.0    12  Table1
22   266.0  195.0    13  Table2
23   163.0  240.0    13  Table1
24   165.0  239.0    14  Table1
25   164.0  239.0    15  Table1
26   165.0  239.0    16  Table1
27   165.0  240.0    17  Table1
28   394.0  259.0    17  Table4
29   151.0  129.0    18  Table3

Does anyone have a suggestion how to color the animation according to the table column? I played around with this code but have not found a way. Any help is appreciated!!

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation

title = 'Occ'
x = np.array(df.x)
y = np.array(df.y)
occupancy = pd.DataFrame(y,x)

occupancy.columns = {title}

Writer = animation.writers['ffmpeg']
writer = Writer(fps=20, metadata=dict(artist='Me'), bitrate=1800)

fig = plt.figure(figsize=(12,8))
plt.xlim(0, 500)
plt.ylim(0,500)
plt.xlabel('X',fontsize=20)
plt.ylabel('Y',fontsize=20)
plt.title('Occ',fontsize=20)


def animate(i):
    data = occupancy.iloc[:int(i+1)] #select data range
    p = sns.scatterplot(x=data.time, y=data[title], data=df, color="Blue")
    p.tick_params(labelsize=17)
    plt.setp(p.lines,linewidth=7)
    
ani = matplotlib.animation.FuncAnimation(fig, animate, frames=400, repeat=True)
ani.save('Occ.mp4', writer=writer)

Solution

  • You can use the hue parameter inside sns.scatterplot to plot the points of the same Table with the same color. Check this code:

    import numpy as np
    import pandas as pd
    import seaborn as sns
    import matplotlib
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    
    df = pd.read_csv('data.csv')
    
    title = 'Occ'
    x = np.array(df.x)
    y = np.array(df.y)
    
    Writer = animation.writers['ffmpeg']
    writer = Writer(fps = 20, metadata = dict(artist = 'Me'), bitrate = 1800)
    
    fig = plt.figure(figsize = (12, 8))
    
    def animate(i):
        plt.gca().cla()
        data = df.iloc[:int(i + 1)]  # select data range
        p = sns.scatterplot(x = 'x', y = 'y', hue = 'table', data = data, s = 200, alpha = 0.5)
        p.tick_params(labelsize = 17)
        plt.setp(p.lines, linewidth = 7)
        plt.xlim(0, 500)
        plt.ylim(0, 500)
        plt.xlabel('X', fontsize = 20)
        plt.ylabel('Y', fontsize = 20)
        plt.title('Occ', fontsize = 20)
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames = len(df), repeat = True)
    ani.save('Occ.mp4', writer = writer)
    
    plt.show()
    

    which gives me this animation:

    enter image description here

    I changed a bit your code (I deleted the occupancy dataframe and plottet x and y columns of the original dataframe) in order to run properly the animation. You can just implement the hue = 'table' parameter in you code.