Right now it doesn't seem like we can make a categorical choropleth by adding multiple traces with the same color and having legend items appear for them: https://codepen.io/nicolaskruchten/pen/MLwyOZ?editors=0010
Ideally I'd want to be able to:
marker.color, instead of doing a dance with z and colorscaleSo that I could easily switch between choropleth and scattergeo like with this one: https://codepen.io/nicolaskruchten/pen/QYbNax?editors=0010
That's correct. choropleth don't support legend items.
You _can_ shrink down the colorbars (one for each trace) to do something like:

from https://nbviewer.jupyter.org/github/etpinard/plotly-misc-nbs/blob/master/geo-maps/discrete-choropleths.ipynb#Suggestion-2:-split-data-into-several-choropleth-traces
- set the color directly, like with
marker.color, instead of doing a dance withzandcolorscale
So, you want z (that should have been called value, by the way) and marker.color to do the exact same thing? I can't say I'm a fan. It would be weird (to me) to have a "primary" data array (i.e. you need it to see stuff) stuck insider marker.
So that I could easily switch between
choroplethandscattergeolike with this one:
By a similar argument, should we rename the pie data arrays x and y so that we can easily switch from bar <--> pie? I doubt it.
Now, I'm not saying we shouldn't try to make trace-to-trace correspondences easier. This has been discussed during previous work on relayout. The last item of https://github.com/plotly/plotly.js/issues/2025 is:
add a way to declare correspondence between attributes of different name across trace types (e.g. to generalize type edits involving pie traces, scattergeo lon/lat should correspond to x/y, ...)
Maybe we can find a way to declare those correspondence in the plot-schema. Thoughts?
X and Y are terrible attribute names for pie, in just the same way as Z is a much worse attribute name than color for controlling the color of a choropleth marker, so no, obviously I would not favour those for pie!
However, since you bring it up, pie’s label/value would be a great fit for bar, since they would not require transposition to swap orientation, as x and y currently do.
Straw man aside: yes I would favour grandfathering in z as a legacy way of specifying marker.color if we added it to choropleth.
The problem with playing discretization tricks with the colorbar is that it doesn’t have the same behaviour as the legend with respect to clicking to hide etc, so it’s inconsistent with the rest of the traces. This is a problem with parcats, parcoords etc as well.
Maybe we can find a way to declare those correspondence in the plot-schema.
So this :arrow_double_up: isn't good enough?
My main goal is to be able to specify the color of the country directly like we can specify the color of a marker in scatterX. Z doesn’t permit this atm, so no, declaring a correspondence doesn’t help :)
Conversely, allowing CSS color names in an array called Z seems awkward.
We could make z accept color names (and omit colorscale).
We could, yes. And we could allow traces to be added to the legend. That would indeed allow me to make the figures I want.
Thinking about this again maybe marker.color for color names + legend items would be best.
That way, user that inputs z gets a colorscale and a colorbar, user that inputs marker.color gets a legend item. There wouldn't be any marker.colorscale and marker.color items couldn't be numeric (not a true "data" array, that makes me :smile: ). It will be arrayOk though.
Heh ok that might work also. OTOH I could also see an argument that a true choropleth by definition expresses continuous values and that we should have a new trace type called indicatormap or something that accepts only categorical colors.
Also: choropleth has a “showlegend” attribute atm that doesn’t do anything, which initially led me down this path ;)
Right, all traces have a showlegend attribute even though some (or most?) of them don't support legends
Related:
For reference, BTW, this is the kind of figure I'm aiming at:



Just to drill in a bit on the z vs marker.color thing... @etpinard you said
It would be weird (to me) to have a "primary" data array (i.e. you need it to see stuff) stuck insider marker.
OK, but how is this different from something like scattergeo? If you omit marker.color then all the markers are the same default color. We could do the same thing for choropleth such that if you only pass in location then all the countries (or whatever) are the same color. That's not a useless thing: as an indicator map, it's like "here are all the places where X".
I think it would be quite weird to have choropleth be the one trace where marker.color accepts only colors and not continuous values.
but how is this different from something like
scattergeo?
I'd say the "primary" data arrays for scattergeo are lon and lat. locations (which is what I suspect you're using) is just a shortcut for lon and lat.
I think it would be quite weird to have
choroplethbe the one trace wheremarker.coloraccepts only colors and not continuous values.
True, but it would also be _weird_ to have z and marker.color do the EXACT same thing.
Like I said, z would be a backwards-compatible way to set marker.color's default value, and would be ignored if marker.color was set. So yeah, a bit odd, but there for legacy reasons.
I'd say the "primary" data arrays for scattergeo are lon and lat. locations (which is what I suspect you're using) is just a shortcut for lon and lat.
OK, so then the primary data array for choropleth is locations. I'm not sure why z has to be primary.
Voting for keeping z!
I'm not advocating for getting rid of z... I would just like to also have marker.color that behaves the same way as the other traces for both absent, continuous and CSS-valued data :)
OK, then should heatmap also have a marker.color?
All in all, this whole debate comes down to:
Is choropleth more like a heatmap or more like a scattergeo trace? I think it's more like a heatmap, @nicolaskruchten probably thinks it's more like scattergeo. Not sure who will win out :racehorse:
OK, then should heatmap also have a marker.color?
I would not oppose this. I think z is a sub-optimal choice of name for something which controls only color and not something in a spatial dimension like the z we have in 3d (which does control something in a spatial dimension properly called z).
All in all, this whole debate comes down to: Is choropleth more like a heatmap or more like a scattergeo trace?
Not really: I think attributes which control color should be called color no matter where they are :)
I think attributes which control color should be called
color
I'd argue that z for choropleth is more than just _color_, it's a primary data array. A choropleth trace w/o a z doesn't show anything. A scattergeo trace w/o marker.color still shows points.
As I said above re choropleth traces without z:
OK, but how is this different from something like scattergeo? If you omit marker.color then all the markers are the same default color. We could do the same thing for choropleth such that if you only pass in location then all the countries (or whatever) are the same color. That's not a useless thing: as an indicator map, it's like "here are all the places where X".
Slipping in @nicolaskruchten 's creation

for everyone's enjoyment :smile:
It looks like px.choropleth z field still does not support categorical legend items? I'm not sure where this discussion ended, but at present setting z to a categorical series simply produces a blank map. Thanks!
That’s right, z still supports only continuous color but you can now add multiple single-color choropleth traces with legend items to get the same effect. See https://plot.ly/python/choropleth-maps/ for an example with Plotly Express in Python.
Hi! Thanks for getting back to me. Which section should I be looking at? The figure under "Discrete Colors" is essentially what I am aiming to create. However, the example code provided no longer runs.
It definitely runs but it requires version 4.5.0 of Plotly.py which came out a couple of weeks ago.
That’s right, z still supports only continuous color but you can now add multiple single-color choropleth traces with legend items to get the same effect. See https://plot.ly/python/choropleth-maps/ for an example with Plotly Express in Python.
Hi, I want to know how to reorder the legeng items. Because sometimes these legends may have order meaning, for example bins, 1-10, 1-20, 21-30...
Legend order depends on trace order in the data array.
@nicolaskruchten I saw that this topic was closed and included in #4386 but I still don't understand how to achieve a categorical choropleth using the documentation . My data is a Pandas DataFrame with two columns: the country name and the cluster it belongs in. I want to color the world map based on the cluster of each country - very similar to your examples. I had tried coloring a map by cluster in the past and this is as close as I was able to get using plotly.graph_objects. The issue with this is that the legend was still a continuous color scale, not a list of categories(i.e. cluster labels).
This is example in the Plotly documentation is the closest to what I'm trying to achieve but my data is not in geojson format. Would appreciate any advice. Thank you!
@ahertel if you're looking for information on how to do this in Python I would recommend opening an issue in the Plotly.py repo, but for completeness, here's a PX example without GeoJSON for categorically-coloring statewise choropleths... it's basically the same as the one here https://plotly.com/python/choropleth-maps/#using-builtin-country-and-state-geometries but with categorical instead of continuous color:
import plotly.express as px
fig = px.choropleth(locations=["CA", "TX", "NY", "AK"],
color=["yes", "no", "yes", "no"],
scope="usa", locationmode="USA-states")
fig.show()
@nicolaskruchten Ah right, I forgot this was the JS page. Thank you so much for responding so quickly and taking the time to write the example code! It worked and it's so much simpler than all the stuff I was playing around with. Here's the result.
Most helpful comment
Slipping in @nicolaskruchten 's creation
for everyone's enjoyment :smile: