Karol Zlot
Karol Zlot

Reputation: 4035

How to add static labels to plotly express `choropleth_mapbox`?

With current code I get hover tooltips, however those are not visible on PNG export. I need to have static label on each polygon.

plotly choropleth_mapbox

import plotly.express as px

df = px.data.election()
geojson = px.data.election_geojson()

fig = px.choropleth_mapbox(df, geojson=geojson, color="Bergeron",
                           locations="district", featureidkey="properties.district",
                           center={"lat": 45.5517, "lon": -73.7073},
                           mapbox_style="carto-positron", zoom=9)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()

Solutions which I found are not working, they work only for choropleth but not for choropleth_mapbox which I want to use. List of them:

https://community.plotly.com/t/labels-inside-counties-for-a-map/13953

https://community.plotly.com/t/annotations-on-plotly-choropleth/36219

https://community.plotly.com/t/how-can-i-change-the-hover-labels-into-static-labels/4690/2

Upvotes: 1

Views: 4468

Answers (1)

Rob Raymond
Rob Raymond

Reputation: 31206

  • the obvious answer is add a Scattermapbox layer with text that you want. This is complicated by this bug. I did not find an clear replacement for carto-positron as a replacement on https://www.mapbox.com so the map style has changed
  • create an account on https://account.mapbox.com to get a token, create a base map on https://studio.mapbox.com to create a base map
  • also tried using plotly annotations. However I could not find a way of getting bounding box of map to be able to transform lat/lot co-ords onto domain co-ords (0-1)
mapboxtoken="****"
mapboxstyle="mapbox://styles/***"
  • use geopandas for simple access to centroid of geometries
import plotly.express as px
import plotly.graph_objects as go
import geopandas as gpd

df = px.data.election()
geojson = px.data.election_geojson()
gdf = (
    gpd.GeoDataFrame.from_features(geojson)
    .merge(df, on="district")
    .assign(lat=lambda d: d.geometry.centroid.y, lon=lambda d: d.geometry.centroid.x)
    .set_index("district", drop=False)
)

# for convenience of rebuilding and adding traces...
def basemap():
    fig = px.choropleth_mapbox(
        df,
        geojson=geojson,
        color="Bergeron",
        locations="district",
        featureidkey="properties.district",
        center={"lat": 45.5517, "lon": -73.7073},
        mapbox_style=mapboxstyle,
#         mapbox_style="carto-positron",
        zoom=9,
    )
    fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0},
                      mapbox={"accesstoken":mapboxtoken}
                     )
    return fig


pull it all together

texttrace = go.Scattermapbox(
        lat=gdf.geometry.centroid.y,
        lon=gdf.geometry.centroid.x,
        text=gdf["Bergeron"].astype(str),
        textfont={"color":"white","size":20, "family":"Courier New"},
        mode="text",
        name="Bergeron"
    )

basemap().add_trace(texttrace)

output

enter image description here

Upvotes: 3

Related Questions