Last active
April 5, 2024 01:40
-
-
Save jjsantos01/c119eb434e8094583700b850f52ffb6e to your computer and use it in GitHub Desktop.
Todos los viajes que hice usando Ecobici (CDMX) en un año. Video de la animación: https://youtu.be/3fNVGx_wksk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Python 3.6.10 |Anaconda, Inc.| (default, Jan 7 2020, 15:18:16) [MSC v.1916 64 bit (AMD64)]\n", | |
"matplotlib 3.2.1\n", | |
"geopandas 0.6.3\n", | |
"pandas 0.24.2\n", | |
"Using matplotlib backend: Qt5Agg\n" | |
] | |
} | |
], | |
"source": [ | |
"import sys\n", | |
"\n", | |
"import matplotlib.animation as animation\n", | |
"import matplotlib.pyplot as plt\n", | |
"import geopandas as gpd\n", | |
"import pandas as pd\n", | |
"\n", | |
"print('Python', sys.version)\n", | |
"print(plt.matplotlib.__name__, plt.matplotlib.__version__)\n", | |
"print(gpd.__name__, gpd.__version__)\n", | |
"print(pd.__name__, pd.__version__)\n", | |
"\n", | |
"%matplotlib" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>fecha_de_inicio</th>\n", | |
" <th>fecha_fin</th>\n", | |
" <th>tiempo</th>\n", | |
" <th>estacion_inicio</th>\n", | |
" <th>estacion_fin</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>16/11/2020 16:43:07351 CALLE 27-AVENIDA REVOLU...</td>\n", | |
" <td>16/11/2020 16:48:50312 AVENIDA 2-CALLE 7</td>\n", | |
" <td>00:05:43</td>\n", | |
" <td>351</td>\n", | |
" <td>312</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1</th>\n", | |
" <td>15/11/2020 06:47:56351 CALLE 27-AVENIDA REVOLU...</td>\n", | |
" <td>15/11/2020 07:01:3184 CHILPANCINGO-TLAXCALA</td>\n", | |
" <td>00:13:35</td>\n", | |
" <td>351</td>\n", | |
" <td>84</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2</th>\n", | |
" <td>14/11/2020 15:58:1077 CHOAPAN-TAMAULIPAS</td>\n", | |
" <td>14/11/2020 16:19:10351 CALLE 27-AVENIDA REVOLU...</td>\n", | |
" <td>00:21:00</td>\n", | |
" <td>77</td>\n", | |
" <td>351</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3</th>\n", | |
" <td>14/11/2020 13:47:17192 RUBEN DARIO-REFORMA</td>\n", | |
" <td>14/11/2020 14:14:1884 CHILPANCINGO-TLAXCALA</td>\n", | |
" <td>00:27:01</td>\n", | |
" <td>192</td>\n", | |
" <td>84</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4</th>\n", | |
" <td>14/11/2020 11:21:49326 EUGENIA-NEBRASKA</td>\n", | |
" <td>14/11/2020 12:15:53218 HEGEL-IBARBOUROU</td>\n", | |
" <td>00:54:04</td>\n", | |
" <td>326</td>\n", | |
" <td>218</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" fecha_de_inicio \\\n", | |
"0 16/11/2020 16:43:07351 CALLE 27-AVENIDA REVOLU... \n", | |
"1 15/11/2020 06:47:56351 CALLE 27-AVENIDA REVOLU... \n", | |
"2 14/11/2020 15:58:1077 CHOAPAN-TAMAULIPAS \n", | |
"3 14/11/2020 13:47:17192 RUBEN DARIO-REFORMA \n", | |
"4 14/11/2020 11:21:49326 EUGENIA-NEBRASKA \n", | |
"\n", | |
" fecha_fin tiempo \\\n", | |
"0 16/11/2020 16:48:50312 AVENIDA 2-CALLE 7 00:05:43 \n", | |
"1 15/11/2020 07:01:3184 CHILPANCINGO-TLAXCALA 00:13:35 \n", | |
"2 14/11/2020 16:19:10351 CALLE 27-AVENIDA REVOLU... 00:21:00 \n", | |
"3 14/11/2020 14:14:1884 CHILPANCINGO-TLAXCALA 00:27:01 \n", | |
"4 14/11/2020 12:15:53218 HEGEL-IBARBOUROU 00:54:04 \n", | |
"\n", | |
" estacion_inicio estacion_fin \n", | |
"0 351 312 \n", | |
"1 351 84 \n", | |
"2 77 351 \n", | |
"3 192 84 \n", | |
"4 326 218 " | |
] | |
}, | |
"execution_count": 2, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"miuso = pd.read_html('datos/mi_uso_20201117.html')[0]\\\n", | |
" .rename(columns=lambda x: x.lower().replace(' ', '_'))\\\n", | |
" .drop('unnamed:_0', axis=1)\\\n", | |
" .assign(estacion_inicio=lambda x: x['fecha_de_inicio'].str.split().str[1].str[8:].astype(int),\n", | |
" estacion_fin=lambda x: x['fecha_fin'].str.split().str[1].str[8:].astype(int))\n", | |
"miuso.head()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<div>\n", | |
"<style scoped>\n", | |
" .dataframe tbody tr th:only-of-type {\n", | |
" vertical-align: middle;\n", | |
" }\n", | |
"\n", | |
" .dataframe tbody tr th {\n", | |
" vertical-align: top;\n", | |
" }\n", | |
"\n", | |
" .dataframe thead th {\n", | |
" text-align: right;\n", | |
" }\n", | |
"</style>\n", | |
"<table border=\"1\" class=\"dataframe\">\n", | |
" <thead>\n", | |
" <tr style=\"text-align: right;\">\n", | |
" <th></th>\n", | |
" <th>districtcode</th>\n", | |
" <th>nearbystations_0</th>\n", | |
" <th>name</th>\n", | |
" <th>districtname</th>\n", | |
" <th>zipcode</th>\n", | |
" <th>location_lat</th>\n", | |
" <th>addressnumber</th>\n", | |
" <th>stationtype</th>\n", | |
" <th>nearbystations_2</th>\n", | |
" <th>nearbystations_1</th>\n", | |
" <th>location_lon</th>\n", | |
" <th>id</th>\n", | |
" <th>address</th>\n", | |
" <th>nearbystations_3</th>\n", | |
" <th>nearbystations_5</th>\n", | |
" <th>nearbystations_4</th>\n", | |
" <th>geometry</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>CUA</td>\n", | |
" <td>3</td>\n", | |
" <td>1 RIO SENA-RIO BALSAS</td>\n", | |
" <td>Cuauhtémoc</td>\n", | |
" <td>06500</td>\n", | |
" <td>19.433571</td>\n", | |
" <td>S/N</td>\n", | |
" <td>BIKE,TPV</td>\n", | |
" <td>85.0</td>\n", | |
" <td>8.0</td>\n", | |
" <td>-99.167809</td>\n", | |
" <td>1</td>\n", | |
" <td>001 - Río Sena-Río Balsas</td>\n", | |
" <td>NaN</td>\n", | |
" <td>NaN</td>\n", | |
" <td>NaN</td>\n", | |
" <td>POINT (-99.16781 19.43357)</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1</th>\n", | |
" <td>CUA</td>\n", | |
" <td>1</td>\n", | |
" <td>2 RIO GUADALQUIVIR-RIO BALSAS</td>\n", | |
" <td>Cuauhtémoc</td>\n", | |
" <td>06500</td>\n", | |
" <td>19.431386</td>\n", | |
" <td>S/N</td>\n", | |
" <td>BIKE</td>\n", | |
" <td>NaN</td>\n", | |
" <td>5.0</td>\n", | |
" <td>-99.171695</td>\n", | |
" <td>2</td>\n", | |
" <td>002 - Río Guadalquivir - Río Balsas</td>\n", | |
" <td>NaN</td>\n", | |
" <td>NaN</td>\n", | |
" <td>NaN</td>\n", | |
" <td>POINT (-99.17169 19.43139)</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2</th>\n", | |
" <td>1</td>\n", | |
" <td>8</td>\n", | |
" <td>3 REFORMA-INSURGENTES</td>\n", | |
" <td>Ampliación Granada</td>\n", | |
" <td>06500</td>\n", | |
" <td>19.431655</td>\n", | |
" <td>S/N</td>\n", | |
" <td>BIKE,TPV</td>\n", | |
" <td>86.0</td>\n", | |
" <td>20.0</td>\n", | |
" <td>-99.158668</td>\n", | |
" <td>3</td>\n", | |
" <td>003 - Reforma - Insurgentes</td>\n", | |
" <td>NaN</td>\n", | |
" <td>NaN</td>\n", | |
" <td>NaN</td>\n", | |
" <td>POINT (-99.15867 19.43165)</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" districtcode nearbystations_0 name \\\n", | |
"0 CUA 3 1 RIO SENA-RIO BALSAS \n", | |
"1 CUA 1 2 RIO GUADALQUIVIR-RIO BALSAS \n", | |
"2 1 8 3 REFORMA-INSURGENTES \n", | |
"\n", | |
" districtname zipcode location_lat addressnumber stationtype \\\n", | |
"0 Cuauhtémoc 06500 19.433571 S/N BIKE,TPV \n", | |
"1 Cuauhtémoc 06500 19.431386 S/N BIKE \n", | |
"2 Ampliación Granada 06500 19.431655 S/N BIKE,TPV \n", | |
"\n", | |
" nearbystations_2 nearbystations_1 location_lon id \\\n", | |
"0 85.0 8.0 -99.167809 1 \n", | |
"1 NaN 5.0 -99.171695 2 \n", | |
"2 86.0 20.0 -99.158668 3 \n", | |
"\n", | |
" address nearbystations_3 nearbystations_5 \\\n", | |
"0 001 - Río Sena-Río Balsas NaN NaN \n", | |
"1 002 - Río Guadalquivir - Río Balsas NaN NaN \n", | |
"2 003 - Reforma - Insurgentes NaN NaN \n", | |
"\n", | |
" nearbystations_4 geometry \n", | |
"0 NaN POINT (-99.16781 19.43357) \n", | |
"1 NaN POINT (-99.17169 19.43139) \n", | |
"2 NaN POINT (-99.15867 19.43165) " | |
] | |
}, | |
"execution_count": 13, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"estaciones = gpd.read_file('datos/estaciones_ecobici.geojson')\n", | |
"dicc_puntos_estaciones = estaciones.set_index('id').geometry.apply(lambda p: (p.x, p.y)).to_dict()\n", | |
"estaciones.head(3)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"colonias = gpd.read_file('datos/colonias_ecobici_bordes.geojson')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"fig, ax = plt.subplots(1, 1, figsize=(10, 10))\n", | |
"estaciones.plot(markersize=0.5, ax=ax)\n", | |
"colonias.plot(linewidth=0.25, color='green', ax=ax)\n", | |
"anotaciones = []\n", | |
"tt = plt.annotate(s='.', xy=dicc_puntos_estaciones[1], arrowprops={'facecolor': 'black', 'width': 0.5, 'headwidth': 4})\n", | |
"ax.set_axis_off()\n", | |
"titulo = ax.set_title('')\n", | |
"\n", | |
"def animate(frame):\n", | |
" row = miuso.loc[frame]\n", | |
" if anotaciones:\n", | |
" anotaciones[-1].arrow_patch.set(color='gray', alpha=0.5)\n", | |
" anotaciones[-1].set(color='gray', alpha=0.5)\n", | |
" tt = ax.annotate(\n", | |
" s=row['estacion_inicio'],\n", | |
" xy=dicc_puntos_estaciones[row['estacion_inicio']],\n", | |
" xytext=dicc_puntos_estaciones[row['estacion_fin']],\n", | |
" arrowprops={'facecolor': 'black', 'width': 0.5, 'headwidth': 4, 'alpha': 0.8}\n", | |
" )\n", | |
" titulo.set_text(f'Viaje {frame}\\n de estación {row[\"estacion_inicio\"]} a {row[\"estacion_fin\"]}')\n", | |
" anotaciones.append(tt)\n", | |
"\n", | |
"frames = list(range(len(miuso)))[:]\n", | |
"ani = animation.FuncAnimation(fig, animate, frames=frames, blit=False, interval=400)\n", | |
"ani.save(\"mi_uso_de_ecobici.mp4\")\n", | |
"#plt.show()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"hide_input": false, | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.6.10" | |
}, | |
"toc": { | |
"base_numbering": 1, | |
"nav_menu": {}, | |
"number_sections": true, | |
"sideBar": true, | |
"skip_h1_title": false, | |
"title_cell": "Table of Contents", | |
"title_sidebar": "Contents", | |
"toc_cell": false, | |
"toc_position": {}, | |
"toc_section_display": true, | |
"toc_window_display": false | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment