Generar gráficos animados de burbuja a lo Gapminer con Python.

En febrero de 2013 creé un artículo sobre cómo hacer gráficos de burbujas con matplotlib, la idea era ver como se generaba una gráfica al estilo de la presentación de Hans Rosling (por cierto, murió en Febrero de 2017).

A continuación el vídeo que explica la historia de 200 países en 200 años, la experanza de vida y calida de vida.

O su charla TED sobre sobre las mejores estadísticas que nunca haz visto:

En el artículo que menciono se uso el conjunto de datos de la rata de criminalidad por estado de Estados Unidos del año 2005. Pero sólo mostraba la información y no la variación en el tiempo.

Este artículo se basa en el siguiente tutorial Python Gapminer Animation.

A continuación se muestra el código del script vía notebook de jupyter:

https://python-graph-gallery.com/341-python-gapminder-animation/

In [1]:

#Se importa las librerias matplitlib, numpy, pandas, seaborn
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
sns.set_style("white")
import pandas as pd
my_dpi=96

In [2]:

# Se obtiene los datos en formato csv  y se convierte en un dataframe
url = 'https://python-graph-gallery.com/wp-content/uploads/gapminderData.csv'
data = pd.read_csv(url)

In [3]:

#Se muestra el data frame
data.head()

Out[3]:

Tiene las columnas países, año, población, contienen, experanza de vida y pib percapita

In [4]:

#Se revisa los tipos de datos de las columnas
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1704 entries, 0 to 1703
Data columns (total 6 columns):
country 1704 non-null object
year 1704 non-null int64
pop 1704 non-null float64
continent 1704 non-null object
lifeExp 1704 non-null float64
gdpPercap 1704 non-null float64
dtypes: float64(3), int64(1), object(2)
memory usage: 80.0+ KB

Se observa que la columna continente es del tipo objeto. Se necesita convertir en un tipo categoria.

In [5]:

# Transformar los datos de la columna continente a categoria.
data['continent']=pd.Categorical(data['continent'])
data.head()

Out[5]:

In [6]:

#Se vuelve a revisar los tipos de las columnas y ahora se tiene que contienen es categoria
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1704 entries, 0 to 1703
Data columns (total 6 columns):
country 1704 non-null object
year 1704 non-null int64
pop 1704 non-null float64
continent 1704 non-null category
lifeExp 1704 non-null float64
gdpPercap 1704 non-null float64
dtypes: category(1), float64(3), int64(1), object(1)
memory usage: 68.5+ KB

Ahora se generará las gráficas por año de experanza de vida y PIB por año, cada gráfica se almacena con su nombre y año a fin de que luego con Image Magick se convierta en un gif animado

In [7]:

# Por cada año
for i in data.year.unique():
# inicializa la figura
fig = plt.figure(figsize=(680/my_dpi, 480/my_dpi), dpi=my_dpi)
# se cambia de color con c y alpha, se mapea el color del eje X.
tmp=data[ data.year == i ]
plt.scatter(tmp['lifeExp'], tmp['gdpPercap'] , s=tmp['pop']/200000 , c=tmp['continent'].cat.codes, cmap="Accent", alpha=0.6, edgecolors="white", linewidth=2)
# Se agrega el título, y los ejes.
plt.yscale('log')
plt.xlabel("Experanza de vida")
plt.ylabel("PIB per capita")
plt.title("Año: "+str(i) )
plt.ylim(0,100000)
plt.xlim(30, 90)

# Se salva el archivo como png, cada archivo por año.
filename='Gapminder_step'+str(i)+'.png'
plt.savefig(filename, dpi=96)
plt.gca()

Se muestra una imagen de las generadas:

Para convertir las imágenes generadas en gif se ejecuta el siguiente comando de image magick:

convert -delay 80 Gapminder*.png animated_gapminder.gif

El gif resultante se muestra a continuación: