How to fill null values with other color in choropleth_mapbox?

Hey Plotly-Community,
I am trying to plot a map of Germany with the choropleth_mapbox.

Problem that I have. At the Data not all parts are filled and I want to give this areas another color then the areas where a value is present.

The missing values can’t be filled with the min or max value, else the color of the other areas are changing as well. If I use the theoretical min or max value the colors in the plot come closer together and the color difference does not have much contrast.

What I tried so far:

fig = px.choropleth_mapbox(df,
                           geojson=geodf.geometry,
                           locations=df.index,
                           color=variable,
                           title=variable,
                           mapbox_style="white-bg",
                           zoom=6,
                           center = {"lat": 51.325691, "lon": 10.451526},
                           color_continuous_scale=["white", "blue", "red"]
                           range_color=(np.unique(df[variable])[1], np.max(df[variable])),
                           hover_data=[variable, df.index],
                          )

variable is one variable out of the df.

i tried to add another choroplethmapbox fig.add_choroplethmapbox with the entrys that are not filled in the df. so I created a mask and filtered these frames. But the colors changed to another scale and the colorscale from the added choroplethmapbox weren’t used at all.

Now I Created a minimal Example:

from shapely.geometry import Polygon
import geopandas as gpd
import numpy as np
import json
import plotly.express as px

geometry = gpd.GeoSeries([Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]), Polygon([(1, 1), (2, 1), (2, 2), (1, 2)]), Polygon([(1, 0), (2, 0), (2, 1), (1, 1)]), Polygon([(0, 1), (1, 1), (1, 2), (0, 2)])])
geoDf = gpd.GeoDataFrame(data={"Name":["a","b","c","d"], "geometry": geometry}, geometry="geometry")
dataDf = pd.DataFrame(data={"Data":[1,1.5,2,np.nan]})


fig = px.choropleth_mapbox(dataDf,
                           geojson=geoDf.geometry,
                           locations=dataDf.index,
                           color="Data",
                           title="Data",
                           mapbox_style="white-bg",
                           center = {"lat": 1, "lon": 1},
                           zoom=6.5,
                           color_continuous_scale=["white", "red"],
                           #range_color=(np.unique(df[variable])[1], np.max(df[variable])),
                           hover_name="Data",
                          )


fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
fig.show()

What I want is that the top left corner is filled with another color out of the color_range

complete Solution:

from shapely.geometry import Polygon
import geopandas as gpd
import numpy as np
import json
import plotly.express as px

def generateColorScale(colors, naColor):
    colorArray=[]
    colorArray.append([0,naColor])
    for grenze, color in zip(np.linspace(0.01,1,len(colors)), colors):
        colorArray.append([grenze, color])
    return colorArray

geometry = gpd.GeoSeries([Polygon([(0, 0), (1, 0), (1, 1), (0, 1)]), Polygon([(1, 1), (2, 1), (2, 2), (1, 2)]), Polygon([(1, 0), (2, 0), (2, 1), (1, 1)]), Polygon([(0, 1), (1, 1), (1, 2), (0, 2)])])
geoDf = gpd.GeoDataFrame(data={"Name":["a","b","c","d"], "geometry": geometry}, geometry="geometry")
dataDf = pd.DataFrame(data={"Data":[1.0,1.5,2,np.nan]}).fillna(-1)


fig = px.choropleth_mapbox(dataDf,
                           geojson=geoDf.geometry,
                           locations=dataDf.index,
                           color="Data",
                           title="Data",
                           mapbox_style="white-bg",
                           center = {"lat": 1, "lon": 1},
                           zoom=6,
                           color_continuous_scale=generateColorScale(colors=["white","red"], naColor="gray"),
                           range_color=(np.unique(dataDf["Data"])[1]*0.99, np.max(dataDf["Data"])),
                           hover_name="Data",
                          )


fig.update_layout(margin={"r": 0, "t": 0, "l": 0, "b": 0})
fig.show()

I got inspired by this redirecting to this post.

  • you need to change the minimum of range_color, else your lowest value is in the naColor as well
  • fill the missing values with a value lower then all values in the Data

hope that does help some other plotly users