Skip to content

Instantly share code, notes, and snippets.

@jjsantos01
Last active April 18, 2023 19:17
Show Gist options
  • Save jjsantos01/070a01ca777359328f3cbd83cc728747 to your computer and use it in GitHub Desktop.
Save jjsantos01/070a01ca777359328f3cbd83cc728747 to your computer and use it in GitHub Desktop.
animation of all trips in the Mexico City public bike sharing system during one day https://www.youtube.com/shorts/k1Or2olVLPo
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import geopandas as gpd
data = pd.read_csv('datos/rutas_ecobici_test.csv')
estaciones = gpd.read_file('datos/estaciones_ecobici.geojson')
colonias = gpd.read_file('datos/colonias_ecobici_bordes.geojson')
centros = gpd.read_file('datos/colonias_ecobici_centros.geojson')
x, y = data['lon'], data['lat']
fig, ax = plt.subplots(figsize=(8, 8))
line, = ax.plot(x, y, marker='$😊$', linewidth=0, ms=15, mew=0.1)
estaciones.plot(ax=ax, markersize=0.5, color='gray')
colonias.plot(ax=ax, color='k', linewidth=0.08)
titulo = fig.suptitle('Viajes de Ecobici CDMX en un día', fontsize=14, y=0.9)
text_hora = ax.text(s='', x=0.5, y=1, fontsize=14, transform=ax.transAxes, ha='center')
n_ciclistas = ax.set_title('', color='gray', fontsize=12, y=0.93, ha='center')
n_total = ax.text(s='', x=0.5, y=-0.05, color='gray', fontsize=12, transform=ax.transAxes, ha='center')
fuente = ax.text(s='Elaborado por @jjsantoso con datos abierto de Ecobici', x=0.5, y=-0.1, color='gray',
fontsize=8, transform=ax.transAxes, ha='center')
ax.set(aspect='equal', yticks=[], xticks=[])
n_viajes = []
for i, row in centros.iterrows():
ax.text(x=row['lon'], y=row['lat'], s=row['nombre'].title(), fontsize=4, color='k', alpha=0.7, ha='center')
for s in ax.spines.values():
s.set_visible(False)
def init(): # only required for blitting to give a clean slate.
line.set_ydata([pd.np.nan] * len(x))
line.set_color('#789b73')
def animate(frame):
minuto_dia = 300 + frame
data_up = data.query(f'minuto_dia=={minuto_dia}')
line.set_data(data_up['lon'], data_up['lat'])
hora, minuto = divmod(minuto_dia, 60)
n_viajes.append(data_up.query('step==1').shape[0])
text_hora.set_text(s=f'{hora:02d}:{minuto:02d}')
n_ciclistas.set_text(f'{data_up.shape[0]} ciclistas')
n_total.set_text(f'Total de viajes: {sum(n_viajes)}')
frames = data.minuto_dia.max() - 300
ani = animation.FuncAnimation(fig, animate, init_func=init, frames=frames, blit=False, interval=50)
# ani.save("ecobici.mp4")
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment