Skip to content

Instantly share code, notes, and snippets.

@jjsantos01
Last active April 5, 2024 01:46
Show Gist options
  • Save jjsantos01/af25c02ffa30acde8473385f08baf76f to your computer and use it in GitHub Desktop.
Save jjsantos01/af25c02ffa30acde8473385f08baf76f to your computer and use it in GitHub Desktop.
Urban evolution of Mexico City. Animation video at https://www.youtube.com/watch?v=VoqyihiVzxw
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import time
start = time.time()
dir_datos = 'D:/datos/catastro_cdmx'
centroides = pd.read_pickle(f'{dir_datos}/centroides_completa.pkl')
fig, ax = plt.subplots(figsize=(15, 16.5))
fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=None, hspace=None)
for s in ax.spines.values():
s.set_visible(False)
xlims = (-99.37, -98.92)
ylims = (19.1, 19.6)
def animate(frame):
ax.cla()
year = frame
# plot año y
centroides.query('anio_construccion==@year').plot(markersize=0.1, figsize=(10, 10), color='green', label=str(year), ax=ax)
# plot años anteriores
centroides.query('anio_construccion<@year').plot(markersize=0.001, color='white', label=f'antes de {year}', ax=ax)
# Detalles de la gráfica
ax.set(aspect='equal', yticks=[], xticks=[], ylim=ylims, xlim=xlims, facecolor='k')
# titulo
ax.text(s=str(year), x=0.5, y=0.97, fontsize=20, color='white', transform=ax.transAxes)
# fuente
fuente = ax.text(s='Elaborado por @jjsantoso con datos de ADIP.', x=1, y=0, ha='right', color='white', fontsize=10, transform=ax.transAxes)
# Leyenda
ax.legend(loc='center right')
ley = ax.get_legend()
if ley:
for handle in ley.legendHandles:
handle.set_sizes([15])
print(frame)
frames = list(range(1950, 2020))
duracion = 30 # en segundos
interval = round(1000 * (duracion/len(frames)), 0)
ani = animation.FuncAnimation(fig, animate, frames=frames, blit=False, interval=interval)
ani.save("catastro_cdmx.mp4", dpi=200)
end = time.time()
print(end-start)
# plt.show()
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"Collapsed": "false"
},
"outputs": [],
"source": [
"import pandas as pd\n",
"import geopandas as gpd\n",
"import matplotlib.pyplot as plt\n",
"from shapely.geometry import MultiPolygon, Polygon\n",
"dir_datos = 'D:/datos/catastro_cdmx'\n",
"\n",
"def convierte_multipolygon(x):\n",
" return MultiPolygon([Polygon(p) for P in eval(x)['coordinates'] for p in P])"
]
},
{
"cell_type": "markdown",
"metadata": {
"Collapsed": "false"
},
"source": [
"# Leyendo datos\n",
"* Descargados de: https://sig.cdmx.gob.mx/datos/"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"Collapsed": "false"
},
"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>fid</th>\n",
" <th>geo_shape</th>\n",
" <th>anio_construccion</th>\n",
" <th>alcaldia_cumplimiento</th>\n",
" <th>geometry</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1156094</td>\n",
" <td>{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-99.0...</td>\n",
" <td>1979.0</td>\n",
" <td>XOCHIMILCO</td>\n",
" <td>(POLYGON ((-99.09918847801011 19.2639981760647...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1156091</td>\n",
" <td>{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-99.0...</td>\n",
" <td>1982.0</td>\n",
" <td>XOCHIMILCO</td>\n",
" <td>(POLYGON ((-99.099195807972 19.2639096566576, ...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1156080</td>\n",
" <td>{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-99.0...</td>\n",
" <td>1986.0</td>\n",
" <td>XOCHIMILCO</td>\n",
" <td>(POLYGON ((-99.0992006818359 19.2638508724769,...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1156081</td>\n",
" <td>{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-99.0...</td>\n",
" <td>1979.0</td>\n",
" <td>XOCHIMILCO</td>\n",
" <td>(POLYGON ((-99.09920514478129 19.2637970005209...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1156078</td>\n",
" <td>{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-99.0...</td>\n",
" <td>1970.0</td>\n",
" <td>XOCHIMILCO</td>\n",
" <td>(POLYGON ((-99.099207906649 19.2637636533644, ...</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" fid geo_shape \\\n",
"0 1156094 {\"type\":\"MultiPolygon\",\"coordinates\":[[[[-99.0... \n",
"1 1156091 {\"type\":\"MultiPolygon\",\"coordinates\":[[[[-99.0... \n",
"2 1156080 {\"type\":\"MultiPolygon\",\"coordinates\":[[[[-99.0... \n",
"3 1156081 {\"type\":\"MultiPolygon\",\"coordinates\":[[[[-99.0... \n",
"4 1156078 {\"type\":\"MultiPolygon\",\"coordinates\":[[[[-99.0... \n",
"\n",
" anio_construccion alcaldia_cumplimiento \\\n",
"0 1979.0 XOCHIMILCO \n",
"1 1982.0 XOCHIMILCO \n",
"2 1986.0 XOCHIMILCO \n",
"3 1979.0 XOCHIMILCO \n",
"4 1970.0 XOCHIMILCO \n",
"\n",
" geometry \n",
"0 (POLYGON ((-99.09918847801011 19.2639981760647... \n",
"1 (POLYGON ((-99.099195807972 19.2639096566576, ... \n",
"2 (POLYGON ((-99.0992006818359 19.2638508724769,... \n",
"3 (POLYGON ((-99.09920514478129 19.2637970005209... \n",
"4 (POLYGON ((-99.099207906649 19.2637636533644, ... "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = pd.read_csv(f'{dir_datos}/sig_cdmx_cuentas_06_2020.csv', dtype={'fid': str}, usecols=['fid', 'geo_shape', 'anio_construccion', 'alcaldia_cumplimiento'])\\\n",
" .dropna(subset=['fid', 'geo_shape'])\n",
"df['geometry'] = df['geo_shape'].apply(convierte_multipolygon)\n",
"df.head()"
]
},
{
"cell_type": "markdown",
"metadata": {
"Collapsed": "false"
},
"source": [
"## Calcula centroides"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"Collapsed": "false"
},
"outputs": [],
"source": [
"gdf = gpd.GeoDataFrame(df)\n",
"centroides = gdf[['fid', 'anio_construccion', 'geometry']].copy()\n",
"centroides['geometry'] = centroides['geometry'].centroid\n",
"centroides.to_pickle(f'{dir_datos}/centroides_completa.pkl')"
]
}
],
"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": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment