Reputation: 109
I have a data-set that contains the income and life expectancy per country across time. In the year 1800, it looks like this:
I would like to make an animated chart that shows how life expectancy and income evolve over time (from 1800 until 2019). Here's my code so far for a static plot:
import matplotlib
fig, ax = plt.subplots(figsize=(12, 7))
chart = sns.scatterplot(x="Income",
y="Life Expectancy",
size="Population",
data=gapminder_df[gapminder_df["Year"]==1800],
hue="Region",
ax=ax,
alpha=.7,
sizes=(50, 3000)
)
ax.set_xscale('log')
ax.set_ylim(25, 90)
ax.set_xlim(100, 100000)
scatters = [c for c in ax.collections if isinstance(c, matplotlib.collections.PathCollection)]
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[:5], labels[:5])
def animate(i):
data = gapminder_df[gapminder_df["Year"]==i+1800]
for c in scatters:
# do whatever do get the new data to plot
x = data["Income"]
y = data["Life Expectancy"]
xy = np.hstack([x,y])
# update PathCollection offsets
c.set_offsets(xy)
c.set_sizes(data["Population"])
c.set_array(data["Region"])
return scatters
ani = matplotlib.animation.FuncAnimation(fig, animate, frames=10, blit=True)
ani.save("test.mp4")
Here's the link to the data: https://github.com/abdennouraissaoui/Animated-bubble-chart
Thank you!
Upvotes: 3
Views: 2697
Reputation: 12496
You can loop over years of your data through the i
counter, which increases by 1 at each loop (at each frame). You can define a year
variable, that depends on i
, then filter your data by this year
and plot the filtered dataframe. At each loop you have to erase the previous scatterplot with ax.cla()
. Finally, I choose 220 frames in order to have a frame for each year, from 1800 to 2019.
Check this code as a reference:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.animation import FuncAnimation
gapminder_df = pd.read_csv('data.csv')
fig, ax = plt.subplots(figsize = (12, 7))
def animate(i):
ax.cla()
year = 1800 + i
sns.scatterplot(x = 'Income',
y = 'Life Expectancy',
size = 'Population',
data = gapminder_df[gapminder_df['Year'] == year],
hue = 'Region',
ax = ax,
alpha = 0.7,
sizes = (50, 3000))
ax.set_title(f'Year {year}')
ax.set_xscale('log')
ax.set_ylim(25, 90)
ax.set_xlim(100, 100000)
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[:5], labels[:5], loc = 'upper left')
ani = FuncAnimation(fig = fig, func = animate, frames = 220, interval = 100)
plt.show()
which reproduce this animation:
(I cut the above animation in order to have a lighter file, less than 2 MB, in fact the data increases at a step of 5 years. However the code above reproduces the complete animation, with a step of 1 year)
Upvotes: 4