Mapa de coropletas en plotly

La función choropleth_mapbox de plotly

Si quieres crear un mapa de coropletas en Python y plotly, puedes utilizar la función choropleth_mapbox de plotly express, que toma como base mapas de Mapbox. Esta función es un poco compleja al principio, ya que tendrás que pasar las geometrías y existen varias formas de hacerlo. Las más comunes son a través de un geojson para las geometrías y un data frame que relaciona las geometrías con valores y la otra es utilizar un shapefile que tiene todos los datos guardados (geometrías y valores).

Datos desde un geojson

Si tus geometrías están guardadas en un archivo geojson tendrás que importarlo y también tendrás que importar un data frame que contenga al menos un identificador y los valores. Tras importar tus datos, tendrás que pasar el data frame a data_frame y la geometría a geojson. También tendrás que pasar a featureidkey el identificador del geojson (por defecto es id y en otro caso toma la forma properties.<key>) que relaciona el nombre de columna pasado a locations. Por último, tendrás que pasar el nombre de la columna del data frame que representa valores a color.

Los demás argumentos se han utilizado para establecer el estilo de mapa, el punto central del mapa y el nivel de zoom.

from urllib.request import urlopen
import json
import pandas as pd
import plotly.express as px

# Geojson
with urlopen('https://github.com/R-CoderDotCom/data/blob/main/shapefile_spain/spain.geojson?raw=true') as response:
    ccaa = json.load(response)

# Datos
unemp_rates = pd.read_csv("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/unemployment_rates.csv",
                   dtype = {"ccaa_id": str}, encoding = 'latin-1')

fig = px.choropleth_mapbox(
    data_frame = unemp_rates,            # Data frame con valores
    geojson = ccaa,                      # Geojson con geometrías
    featureidkey = 'properties.ccaa_id', # Key del geojson key que relaciona el achivo con los datos del data frame
    locations = 'ccaa_id',               # Nombre de la columna del data frame data frame que se relaciona con featureidkey
    color = 'unemp_rate',                # Nombre de la columna del data frame con los datos a ser representados
    mapbox_style = 'open-street-map',
    center = dict(lat = 40.0, lon = -3.72),
    zoom = 4)

fig.show()

Mapa de coropletas en Python con plotly a partir de un geojson y un data frame

El estilo por defecto de Mapbox necesita un API token para funcionar, por lo que si no tienes uno tendrás que especificar alguno de los estilos que no requieren de una, que son ‘open-street-map’, ‘white-bg’, ‘carto-positron’, ‘carto-darkmatter’, ‘stamen-terrain’, ‘stamen-toner’ y ‘stamen-watercolor’. Si tienes un token, puedes emplear la función plotly.express.set_mapbox_access_token() para establecerlo. Los estilos que requieren de un token se llaman: ‘basic’ (por defecto), ‘streets’, ‘outdoors’, ‘light’, ‘dark’, ‘satellite’ y ‘satellite-streets’.

Datos desde un shapefile

Si tus datos provienen de un shapefile tendrás que leerlos con geopandas o una librería similar. Luego, tendrás que pasar tus datos a la función como en el ejemplo siguiente.

import geopandas
import plotly.express as px

# Sahpefile
shp = geopandas.read_file("https://github.com/R-CoderDotCom/data/blob/main/shapefile_spain/spain.zip?raw=true")
shp = shp.to_crs("WGS84")

fig = px.choropleth_mapbox(
    data_frame = shp.set_index("ccaa_id"), # Usar el ID como índice de los datos
    geojson = shp.geometry,                # La geometría
    locations = shp.index,                 # El índice de los datos
    color = 'unemp_rate',
    mapbox_style = 'open-street-map',
    center = dict(lat = 40.0, lon = -3.72),
    zoom = 4)

fig.show()

Mapa de coropletas en plotly a partir de un shapefile y geopandas

Datos al pasar el ratón por encima

Si pasas el ratón sobre una región de España podrás ver el identificador y la tasa de paro correspondiente. Sin embargo, también puedes pasar el nombre de una columna a hover_name, de modo que esa variable también aparecerá cuando pases el ratón por encima. En el ejemplo siguiente pasamos el nombre de cada comunidad autónoma.

from urllib.request import urlopen
import json
import pandas as pd
import plotly.express as px

# Geojson
with urlopen('https://github.com/R-CoderDotCom/data/blob/main/shapefile_spain/spain.geojson?raw=true') as response:
    ccaa = json.load(response)

# Datos
unemp_rates = pd.read_csv("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/unemployment_rates.csv",
                   dtype = {"ccaa_id": str}, encoding = 'latin-1')

fig = px.choropleth_mapbox(
    data_frame = unemp_rates,
    geojson = ccaa,
    featureidkey = 'properties.ccaa_id',
    locations = 'ccaa_id',
    color = 'unemp_rate',
    hover_name = 'name',
    mapbox_style = 'open-street-map',
    center = dict(lat = 40.0, lon = -3.72),
    zoom = 4)

fig.show()

Texto de un mapa de coropletas en plotly al pasar el ratón por encima

Paleta de colores

Es posible personalizar la paleta de colores utilizada en las coropletas pasando una lsita de colores o el nombre de una paleta de colores de plotly a color_continuous_scale. Ten en cuenta que también puedes personalizar el nivel de transparencia con opacity, que te permitirá ver lo que hay debajo.

from urllib.request import urlopen
import json
import pandas as pd
import plotly.express as px

# Geojson
with urlopen('https://github.com/R-CoderDotCom/data/blob/main/shapefile_spain/spain.geojson?raw=true') as response:
    ccaa = json.load(response)

# Datos
unemp_rates = pd.read_csv("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/unemployment_rates.csv",
                   dtype = {"ccaa_id": str}, encoding = 'latin-1')

fig = px.choropleth_mapbox(
    data_frame = unemp_rates,
    geojson = ccaa,
    featureidkey = 'properties.ccaa_id',
    locations = 'ccaa_id',
    color = 'unemp_rate',
    color_continuous_scale = 'viridis',
    opacity = 0.5,
    mapbox_style = 'open-street-map',
    center = dict(lat = 40.0, lon = -3.72),
    zoom = 4)

fig.show()

Paleta de colores de un mapa de coropletas en plotly Python

Estilo de los bordes

Por defecto, los bordes de las geometrías tienen un color grisáceo. Sin embargo, puedes sobrescribir el color e incluso el grosor de las líneas con los argumentos marker_line_width y marker_line_color de la función update_traces.

from urllib.request import urlopen
import json
import pandas as pd
import plotly.express as px

# Geojson
with urlopen('https://github.com/R-CoderDotCom/data/blob/main/shapefile_spain/spain.geojson?raw=true') as response:
    ccaa = json.load(response)

# Datos
unemp_rates = pd.read_csv("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/unemployment_rates.csv",
                   dtype = {"ccaa_id": str}, encoding = 'latin-1')

fig = px.choropleth_mapbox(
    data_frame = unemp_rates,
    geojson = ccaa,
    featureidkey = 'properties.ccaa_id',
    locations = 'ccaa_id',
    color = 'unemp_rate',
    color_continuous_scale = 'viridis',
    mapbox_style = 'open-street-map',
    center = dict(lat = 40.0, lon = -3.72),
    zoom = 4)

fig.update_traces(marker_line_width = 2, marker_line_color = 'white')

fig.show()

Color de borde de los polígonos de un mapa de coropletas en Python

Tipo de mapa

Puedes cambiar el estilo de mapa de Mapbox con el argumento mapbox_style. Existen varios tipos de mapa disponibles, pero algunos requieren un API token de Mapbox mientras que otros no.

from urllib.request import urlopen
import json
import pandas as pd
import plotly.express as px

# Geojson
with urlopen('https://github.com/R-CoderDotCom/data/blob/main/shapefile_spain/spain.geojson?raw=true') as response:
    ccaa = json.load(response)

# Datos
unemp_rates = pd.read_csv("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/unemployment_rates.csv",
                   dtype = {"ccaa_id": str}, encoding = 'latin-1')

fig = px.choropleth_mapbox(
    data_frame = unemp_rates,
    geojson = ccaa,
    featureidkey = 'properties.ccaa_id',
    locations = 'ccaa_id',
    color = 'unemp_rate',
    color_continuous_scale = 'viridis',
    mapbox_style = 'stamen-terrain',
    center = dict(lat = 40.0, lon = -3.72),
    zoom = 4)

fig.show()

Estilo de mapa de Mapbox de un mapa de coropletas en Python con choropleth_mapbox

La función choropleth

La función choropleth de plotly express es una alternativa a choropleth_mapbox que no depende de Mapbox. Ambas funciones son muy parecidas pero al utilizar choropleth tendrás que establecer un ámbito geográfico (por defecto, scope = 'world') y tendrás que elegir el nivel de zoom con update_layout. Ten en cuenta que también tendrás que establecer una proyección cartográfica con projection, cuyo valor por defecto depende del ámbito elegido. Aquí encontrarás la lista de ámbitos y proyecciones disponibles.

La función choropleth de plotly express

from urllib.request import urlopen
import json
import pandas as pd
import plotly.express as px

# Geojson
with urlopen('https://github.com/R-CoderDotCom/data/blob/main/shapefile_spain/spain.geojson?raw=true') as response:
    ccaa = json.load(response)

# Datos
unemp_rates = pd.read_csv("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/unemployment_rates.csv",
                   dtype = {"ccaa_id": str}, encoding = 'latin-1')

fig = px.choropleth(
    data_frame = unemp_rates,
    geojson = ccaa,
    featureidkey = 'properties.ccaa_id',
    locations = 'ccaa_id',
    color = 'unemp_rate',
    color_continuous_scale = 'viridis',
    scope = 'europe',
    center = dict(lat = 40.0, lon = -3.72))

fig.update_layout(autosize = True, geo = dict(projection_scale = 5))

fig.show()

Visibilidad del mapa base

Ten en cuenta que esta función permite ocultar el mapa base estableciendo basemap_visible = False.

Visibilidad del mapa base de un mapa de coropletas en Python

from urllib.request import urlopen
import json
import pandas as pd
import plotly.express as px

# Geojson
with urlopen('https://github.com/R-CoderDotCom/data/blob/main/shapefile_spain/spain.geojson?raw=true') as response:
    ccaa = json.load(response)

# Datos
unemp_rates = pd.read_csv("https://raw.githubusercontent.com/R-CoderDotCom/data/main/shapefile_spain/unemployment_rates.csv",
                   dtype = {"ccaa_id": str}, encoding = 'latin-1')

fig = px.choropleth(
    data_frame = unemp_rates,
    geojson = ccaa,
    featureidkey = 'properties.ccaa_id',
    locations = 'ccaa_id',
    color = 'unemp_rate',
    color_continuous_scale = 'viridis',
    scope = 'europe',
    center = dict(lat = 40.0, lon = -3.72),
    basemap_visible = False)

fig.update_layout(autosize = True, geo = dict(projection_scale = 5))

fig.show()
Better Data Visualizations

A Guide for Scholars, Researchers, and Wonks

Comprar en Amazon
Data Sketches

A journey of imagination, exploration, and beautiful data visualizations

Comprar en Amazon

También te puede interesar