Como crear un gráfico de mapa en Python
Un tutorial para principiantes en Python en el manejo y visulización de datos.
P ython es un lenguaje muy versatil que permite manejar datos y hacer visualizaciones de todo tipo. Si eres nuevo te recomiendo descargar el paquete de Anaconda y utilizar Jupyter como procesador de texto para ir viendo las gráficas a medida vas escribiendo el código.
Preparando las librerías y las datos a utilizar
Primero importaremos las librerías que necesitamos para trabajar la información. Utilizaremos Pandas que es una librería para manejar datos, especialmente dataframes y series. Esta librería viene integrada con Anaconda.
La segunda librería que utilizaremos es Geopandas, esta nos permite trabajar archivos llamados shapefile, que contienen las formas y georeferencias que se utilizaremos para graficar los mapas. La ventaja de Geopandas que integra las funciones de Pandas.
import pandas as pd
import geopandas as gpd
Usualmente esta librería no viene integrada al instalar Anaconda. Sin embargo, puede ser fácilmente instalada con tan solo correr en una celda de Jupyter el siguiente código:
¡pip install geopandas
Descargaremos el shapefile (el mapa) de la página oficial del gobierno de El Salvador que contiene los limites políticos de los municipios . Para este ejercicio podemos usar tanto el archivo Lambert o WGS.
Abriremos el archivo en Jupyter:
shapefile = gpd.read_file(direccion+'\LIM_MUNICIPAL.shp')
shapefile.head(5)
Abriremos luego los datos para colorear el mapa, para este ejemplo he descargado el número de accidentes viales por municipio de esta página web: Portal de Transparencia de la Policía Nacional Civil .
acc_auto = pd.read_csv(direccion+r'\accidentes_auto.csv',encoding='utf-8')
acc_auto.head(5)
Luego se debe unir la información a través de un merge. Al observar la información notamos que las llaves será el nombre del municipio (parte importante sería preparar la información para asegurarnos que los municipios tienen los mismos nombres, en el ejercicio asumiremos que sí).
acc_auto = acc_auto[acc_auto['Año']==2019]
shapefile = shapefile.merge(
right = acc_auto,
left_on = 'NA2',
right_on = 'Municipio',
how = 'left'
)
Utilizando Geopandas
Usar Geopandas es sumamente fácil y está bastante bien integrado con Matplotlib. Necesitamos para hacer un simple mapa escribir .plot(column = ‘variable’).
shapefile.plot(column = 'CHOQUE')
Añadiendo legenda
Podemos continuar añadir atributos al mapa para que se vea mejor como una legenda horizontal y con una barra de color de distintos niveles de Naranjas (‘Oranges’).
shapefile.plot(
column = 'CHOQUE',
legend = True,
legend_kwds = {
'label': "Número de choques de vehiculos",
'orientation': "horizontal"
},
cmap = 'Oranges'
)
Debido a que gran parte de los choques se concentran en algunas zonas específicas los colores más intensos se encuentran en unos pocos municipios mientras no se logra ver diferencia en el resto. Una idea para cambiar esto, es recodificar la variable como su logaritmo.
import numpy as np
shapefile['CHOQUE'] = shapefile['CHOQUE'].fillna(1)
shapefile['CHOQUE_log'] = np.log10(shapefile['CHOQUE'])
#replazando valores inf, -inf resultados de log(0)
shapefile['CHOQUE_log'] = shapefile['CHOQUE_log'].replace([np.inf,-np.inf],0)
Al correr nuevamente nuestro código anterior tendríamos un gráfico como el siguiente:
shapefile.plot(
column = 'CHOQUE_log',
legend = True,
legend_kwds = {
'label': "Número de choques de vehiculos",
'orientation': "horizontal"
},
cmap = 'Oranges'
)
Utilizando matplotlib
Para mejorar muchas de las características del mapa se puede usar matplotlib. Esto nos permitirá ajustar mejor la barra de color, el tamaño del mapa, modificar ejes, entre otras cosas.
Si continuamos con el ejemplo, matplotlib nos permite ajustar la barra de color para que la legenda muestre una escala logarítmica.
import matplotlib.pyplot as plt
import matplotlib.colors as mplc
import matplotlib.ticker as ticker
#creando una figura en matplotlib y ajustando el tamaño deseado
fig , ax = plt.subplots(1 ,figsize = (14,8))
shapefile.plot(
column = 'CHOQUE',
legend = False,
cmap ='Oranges',
ax = ax,
norm = mplc.LogNorm(), #utilizando el logaritmo de la variable
linewidth = 1, #ajustando el grosor de las lineas del mapa
edgecolor ='black' #color de las lineas del mapa
)
vmin = shapefile.CHOQUE.min()
vmax = shapefile.CHOQUE.max()
#agregando barra de color atraves de matplotlib
#ajsutando posición y dimensiones de la barra
cax = fig.add_axes([0.9, 0.2, 0.01, 0.6])
#atributos de la barra de color
sm = plt.cm.ScalarMappable(
cmap = 'Oranges',
norm = mplc.LogNorm(vmin = vmin, vmax = vmax)
)
sm._A = []
#OPCIONAL
#formateando los números a absultos de lo contrario salieran a base 10
formatter = ticker.LogFormatter(10, labelOnlyBase=False)
cbr = fig.colorbar(
sm,
cax = cax,
format = formatter,
ticks = [1,10,100]
)
ax.set_title('Número de choques en El Salvador', fontsize = 25)
cbr.ax.tick_params(labelsize = 15) #tamaño de letra de las legendas
ax.axis('off') #desactivando los ejes de posicionamiento
plt.show()
Generando un mapa con variables categóricas
En algunos casos nos interesaría colorear el mapa con valores categóricos. Para ello, dividiremos nuestra variable ‘CHOQUE’ en cuartiles a través de pandas.cut:
labels = ['Cuartil_1', 'Cuartil_2','Cuartil_3','Cuartil_4']
#creando columna con variables categoricas a partir de 'CHOQUE'
shapefile['CHOQUE_Cuartiles'] = pd.cut(
x = shapefile['CHOQUE_log'],
bins = 4,
labels = labels
)
#utilizando matplotlib nuevamente
fig , ax = plt.subplots(1, figsize = (14,8))
#definiendo caracteristicas del mapa (categorical = True)
shapefile.plot(
column = 'CHOQUE_Cuartiles',
categorical = True,
legend = True,
cmap = 'Oranges',
ax = ax,
linewidth = 1,
edgecolor = 'black',
)
ax.axis('off')
fig.show()