Análisis geoespacial con pandas y Folium

Patricia Carmona
6 min readMay 13, 2020

--

Folium es una de las librerías más asequibles para análisis y representación geoespacial, por la sencillez de la sintaxis.

Una de las características que más atrae es que no necesita convertir el DataFrame en un GeoDataFrame. Solo teniendo una serie con la latitud y otra serie con la longitud del punto espacial, es suficiente para que Folium lo represente en un mapa.

Para ponerlo en práctica, utilizo un dataset de casos de COVID — 19 en Italia a principios de año 2020, que puedes encontrar en Kaggle.

💻 El código completo del desarrollo puedes encontrarlo en mi repositorio de GitHub de este proyecto.

Conocer el dataset

Como siempre, es importante conocer el dataset, qué datos almacena y cómo los registra antes de comenzar un análisis. De esta forma podrás enfocar correctamente el análisis.

Peculiaridades de este dataset que marcan el análisis. En el DataFrame los registros se han realizado en forma de actualización, es decir, cada registro en el set no es un caso de COVID-19, si no la actualización de número de casos que hay. Esto marcará la forma en que se representa.

Al tener el número de casos nuevos en una serie y no como registro único, debemos hacer uso de mapas donde la representación tenga en cuenta el peso de esta serie.

En el repositorio de este proyecto puedes ver todo el proceso de Data Wrangling previo al análisis geoespacial de casos de COVID-19 en Italia. Uno de los primeros pasos fue reducir el dataset a una localización de Italia, para trabajar con menor cantidad de datos.

Seleccionando solo la región de Lombardía
df_lom = df_it[(df_it['region'] == 'Lombardia')]

Cómo representar un dataset en un mapa

La estructura para la representación de un mapa es muy similar entre librerías:

  1. Se traza un mapa base centrándolo en una latitud y una longitud
  2. Se añaden capas de información sobre el mapa base

Estas capas de información pueden ser en formato de puntos o markers, figuras de calor, polígonos, etc.

Representación geoespacial con Folium

Con la librería Folium realizo dos tipos de representaciones:

  • Mapa con marcadores, solo indica el punto donde hay un caso de COVID-19, independientemente del número de casos. Este mapa me permite identificar en qué puntos ha habido casos de coronavirus.
  • Mapa Choropleth (o mapa cloroplético), representa las diferentes provincias de una región o de un país sombreadas en función del número de casos de COVID-19. Este análisis permite comparar las diferentes provincias y conocer en cuáles ha habido mayor número de casos de coronavirus.

Mapa base

En cualquiera de las representaciones con Folium el primer paso es desarrollar el mapa sobre el que se va a pintar el resto de la información. Para ello, hay que centrarlo en un punto con latitud y longitud.

Folium utiliza por defecto como tipo de mapa base OpenStreetMap, pero hay otras opciones (es el parámetro que corresponde a “tiles”).

Normalmente, se selecciona el primer registro del dataset como referencia del centro del mapa.

Representar el mapa basemap_ = folium.Map(location=[df_lom.iloc[0]['lat'], df_lom.iloc[0]['long']], 
tiles='OpenStreetMap',
zoom_start = 11)
Visualizar el mapamap_
Mapa base del dataset de la región de Lombardía

Añadir marcadores al mapa de Folium

El siguiente paso es añadir al mapa la información que queremos representar. Este proceso se realiza por capas, añadiendo capas al mapa, al igual que se trabaja en diseño.

Para añadir marcadores que representen cada punto de Lombardía donde hay un caso de COVID-19, itero sobre el DataFrame, creando una tupla (latitud, longitud) que añadir al mapa.

for index, row in df_lom.iterrows():
Marker((row['lat'], row['long']),
icon=folium.Icon(color='red')).add_to(map_)
Mapa con los puntos de Lombardía donde hay casos de COVID-19

Enriquecer y personalizar el mapa de Folium

Para personalizar la información que se despliega en el mapa, junto al marcador, añado un popup para que al pasar el ratón por encima, aparezca el nombre de la provincia. Se define el método tooltip como la serie provincia a la que corresponde, cada vez que se itera por el DataFrame y se añade junto a popup.

Por último, Folium permite personalizar el marcador en cuanto a color e icono que representa. En este caso yo he utilizado un diseño que he encontrado en la red.

Icono para customizar el marcador
icon = 'https://img.icons8.com/ios/50/000000/virus.png'
Iterando sobre el DataFrame de Lombardía, tooltip corresponde a la provincia en cada caso y selecciono las series 'lat' y 'long' de cada registro para añadir al mapafor index, row in df_lom.iterrows():
tooltip = row['province']
icon = folium.features.CustomIcon(icon_url,icon_size=(28, 30))
Marker((row['lat'], row['long']),
popup=row['province'],
tooltip=tooltip,
icon=icon).add_to(map_)
Visualizar el mapa
map_
Mapa de Lombardía con los puntos representados como virus

💡 Recomendación: tipos de mapas que pueden representarse con Folium.

Es un primer paso para la representación de información en un mapa y solo se necesita una serie con la latitud y otra con la longitud a la que corresponde cada registro.

Lo cierto es que el mapa aportaría más información si cada punto indicara el volumen de casos. En este caso, un heatmap es la opción ideal, el problema es que Folium tiene un bug con este tipo de representaciones, cuando se trata de series que representan un peso.

Una representación con Folium que salva este bug es un mapa choropleth. Te recomiendo un post de Amanda Iglesias sobre Folium — Choropleth.

Folium Choropleth

Un mapa choropleth (coroplético) es una representación espacial de regiones geográficas, donde las áreas se sombrean en diferentes colores en función de una variable. En un mapa choropleth se representan las latitudes y longitudes del dataset sobre un mapa de regiones, que se indican en el método choropleth.

En este repositorio puedes acceder a las regiones de todos los continentes y países en formato geojson.

La idea es que la serie del DataFrame que contiene las regiones, sea sustituida por los nombres que aparecen en el geojson. Aunque no suele haber muchas variaciones, puede haber alguna variación en cuestión de tildes.

Represento el mapa de Italia completo, ya que al pintar un mapa de datos agregados, es un DataFrame más reducido. De esta forma puede analizarse qué regiones han sido las más afectadas por COVID-19.

Agrupar el DataFrame por regiones, latitud y longitud para calcular el total de casos en cada regióndf_gr = df_it.groupby(['province', 'lat', 'long']).agg({'total_cases':'sum'}).reset_index()

A continuación represento el mapa de Italia. En primer lugar, pinto un mapa base y después le añado la capa choropleth. En la función choropleth se integran las dos capas de datos geo:

  • ‘geo_data’ : listado geojson de regiones
  • ‘data’: información de DataFrame
Representar el mapa basechoromap_ = folium.Map(location=[df_gr.iloc[0]['lat'], df_gr.iloc[0]['long']], zoom_start=3)Crear el listado de regiones de Italiacommunities_geo = r'italy-provinces.geojson'Representar el mapa choropleth con número de casos por provinciachoromap_.choropleth(
geo_data=communities_geo,
data=df_gr,
columns=['province', 'total_cases'],
key_on='feature.properties.name',
fill_color='BuPu',
fill_opacity=1,
line_opacity=1,
legend_name='COVID-19 Italy',
smooth_factor=0)
Visualizar el mapachoromap_
Mapa de las provincias de Italia en función del número de casos de COVID — 19

Para que el análisis geoespacial cobre más sentido, puede incorporarse al mapa choropleth los cuartiles del recuento de casos para facilitar la comparativa entre provincias.

Mapa de las provincias de Italia representadas en función del cuartil en el que se encuadra

💻 El código completo del desarrollo puedes encontrarlo en mi repositorio de GitHub de este proyecto, donde también hay algunos ejemplos más con Folium.

Análisis geoespacial con Folium

Folium es una librería muy asequible para el análisis y la representación geoespacial por puntos o incluyendo un nivel más de dificultad, representando regiones en función de una variable.

La librería permite personalizar numerosas variables de los mapas, para que el diseño se adapte a lo que necesitas y puedas representar un análisis completo del dataset. La documentación es sencilla y hay muchas contribuciones sobre desarrollo con Folium.

Conclusiones del análisis geoespacial con Folium

Gracias a la representación geoespacial con Folium, pueden reconocerse fácilmente las provincias con mayor número de casos de COVID-19 frente a las que tienen menor número de casos en base al cuartil al que pertenecen cada una. Destaca la provincia de Milán con el mayor registro de coronavirus del dataset.

--

--