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?
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?
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',
define first:
fig = go.Figure(go.Scattermapbox(...))
#and then:
fig.add_choroplethmapbox(...)
Thank You! this worked out fine! I really appreciate the help.