✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Add geojson polygons seaborn colored by specific feature

How does one add geojson polygons colored by a chose feature? For example, a county boundary map that is filled in shaded according to population density. I want to achieve this with the seaborn palette. May I please get some guidance?

You could use either Plotly,

Or Dash Leaflet,

https://dash-leaflet.herokuapp.com/#us_states

@encyclopediabrown

With a seaborn palette you should define a discrete colorscale.
This means that your geographical feature encoded by numerical values between [vmin, vmax] should be divided in a few categories (intervals), and each value in an interval will be mapped to a color in the chosen palette.

Let us suppose that your data are read from a dataframe column df['2019'],
and df['2019'].min(), df['2019'].max() are respectively 25, 60.

Now you decide that each value in the subintervals defined by:

cat_vals= [25, 30, 35, 40, 45, 50, 55, 60] #category values 

to be mapped to a color of a sns palette:

import seaborn as sns

palette = np.array(sns.color_palette("hls", len(cat_vals)-1))
sns_colors = (palette*255+0.5).astype(int)   
sns_colors = [ f'rgb{(C[0], C[1], C[2])}' for C in sns_colors]

From cat_vals and sns_colors you’ll get a Plotly discrete colorscale for a choropleth/choroplethmapbox, by calling this function:

def discrete_colorscale(bvals, colors):
    """
    bvals - list of values bounding intervals/ranges of interest
    colors - list of rgb or hex colorcodes for values in [bvals[k], bvals[k+1]],0<=k < len(bvals)-1
    returns the plotly  discrete colorscale
    """
    if len(bvals) != len(colors)+1:
        raise ValueError('len(boundary values) should be equal to  len(colors)+1')
    bvals = sorted(bvals)     
    nvals = [(v-bvals[0])/(bvals[-1]-bvals[0]) for v in bvals]  #normalized values
    
    dcolorscale = [] #discrete colorscale
    for k in range(len(colors)):
        dcolorscale.extend([[nvals[k], colors[k]], [nvals[k+1], colors[k]]])
    return dcolorscale  

namely
sns_colorscale = discrete_colorscale(cat_vals, sns_colors)

Thanks you @empet, I tried using that method but now I am not getting anything on the map without any errors

@empet Also, something might be wrong with your function that it creates two colors for the same number. Is that why nothing is showing up?

@encyclopediabrown

This is a typical definition of a discrete colorscale with repeating inner values of the scale. If they are non-repeating plotly.js interpolates the colors and you’ll not get a colorbar that shows the sns colors.

Your choroplethmapbox is empty because something is wrong in its definition.

Please read here the steps for reading a geojson file and extracting data for the choroplethmapbox:
https://chart-studio.plotly.com/~empet/15238.

Thanks @empet, I was able to get it to plot. The problem now is that this creates an entire different map. I wanted to overlay as a layer this cholorpleth geojson over a scattermapbox i already have plotted .

Is there a way to make this work with what I have or is it an entirely different process?.

thanks again.

It works fine when you add the two in an jupyter notebook but when I put it in dash it breaks.

I have trace1= scattermapbox()
trace2 = choroplethmapbox()
layout = go.Layout()

return go.Figure(

    data=[trace1, trace2],

    layout=layout

)

then it spits out my geojson like this…

}),)]

The 'data' property is a tuple of trace instances
that may be specified as:
  - A list or tuple of trace instances
    (e.g. [Scatter(...), Bar(...)])
  - A single trace instance
    (e.g. Scatter(...), Bar(...), etc.)
  - A list or tuple of dicts of string/value properties where:
    - The 'type' property specifies the trace type
        One of: ['area', 'bar', 'barpolar', 'box',
                 'candlestick', 'carpet', 'choropleth',
                 'choroplethmapbox', 'cone', 'contour',
                 'contourcarpet', 'densitymapbox', 'funnel',
                 'funnelarea', 'heatmap', 'heatmapgl',
                 'histogram', 'histogram2d',
                 'histogram2dcontour', 'image', 'indicator',
                 'isosurface', 'mesh3d', 'ohlc', 'parcats',

@encyclopediabrown

define first:

fig = go.Figure(go.Scattermapbox(...))
#and then:
fig.add_choroplethmapbox(...)

Thank You! this worked out fine! I really appreciate the help.