Skip to content

Categorical choropleths with legends #3468

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
nicolaskruchten opened this issue Jan 23, 2019 · 34 comments · Fixed by #4386
Closed

Categorical choropleths with legends #3468

nicolaskruchten opened this issue Jan 23, 2019 · 34 comments · Fixed by #4386
Assignees
Labels
feature something new
Milestone

Comments

@nicolaskruchten
Copy link
Contributor

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:

  1. set the color directly, like with marker.color, instead of doing a dance with z and colorscale
  2. have legend entries appear

So that I could easily switch between choropleth and scattergeo like with this one: https://codepen.io/nicolaskruchten/pen/QYbNax?editors=0010

@etpinard
Copy link
Contributor

That's correct. choropleth don't support legend items.

@etpinard
Copy link
Contributor

etpinard commented Jan 23, 2019

@etpinard
Copy link
Contributor

  1. set the color directly, like with marker.color, instead of doing a dance with z and colorscale

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 choropleth and scattergeo like 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 #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?

@nicolaskruchten
Copy link
Contributor Author

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.

@nicolaskruchten
Copy link
Contributor Author

nicolaskruchten commented Jan 24, 2019

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.

@etpinard
Copy link
Contributor

Maybe we can find a way to declare those correspondence in the plot-schema.

So this ⏫ isn't good enough?

@nicolaskruchten
Copy link
Contributor Author

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.

@etpinard
Copy link
Contributor

We could make z accept color names (and omit colorscale).

@nicolaskruchten
Copy link
Contributor Author

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.

@etpinard
Copy link
Contributor

etpinard commented Jan 24, 2019

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 😄 ). It will be arrayOk though.

@etpinard etpinard added the feature something new label Jan 24, 2019
@nicolaskruchten
Copy link
Contributor Author

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 ;)

@etpinard
Copy link
Contributor

etpinard commented Jan 24, 2019

Right, all traces have a showlegend attribute even though some (or most?) of them don't support legends

Related:

@nicolaskruchten
Copy link
Contributor Author

For reference, BTW, this is the kind of figure I'm aiming at:

image

image

image

@nicolaskruchten
Copy link
Contributor Author

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.

@etpinard
Copy link
Contributor

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 choropleth be the one trace where marker.color accepts only colors and not continuous values.

True, but it would also be weird to have z and marker.color do the EXACT same thing.

@nicolaskruchten
Copy link
Contributor Author

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.

@nicolaskruchten
Copy link
Contributor Author

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.

@etpinard
Copy link
Contributor

Voting for keeping z!

@nicolaskruchten
Copy link
Contributor Author

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 :)

@etpinard
Copy link
Contributor

OK, then should heatmap also have a marker.color?

@etpinard
Copy link
Contributor

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 🐎

@nicolaskruchten
Copy link
Contributor Author

nicolaskruchten commented Jan 24, 2019

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 :)

@etpinard
Copy link
Contributor

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.

@nicolaskruchten
Copy link
Contributor Author

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".

@etpinard
Copy link
Contributor

Slipping in @nicolaskruchten 's creation

image

for everyone's enjoyment 😄

@TJ-Tubi
Copy link

TJ-Tubi commented Feb 2, 2020

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!

@nicolaskruchten
Copy link
Contributor Author

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.

@TJ-Tubi
Copy link

TJ-Tubi commented Feb 2, 2020

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.

@nicolaskruchten
Copy link
Contributor Author

It definitely runs but it requires version 4.5.0 of Plotly.py which came out a couple of weeks ago.

@secsilm
Copy link

secsilm commented Feb 22, 2020

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...

@nicolaskruchten
Copy link
Contributor Author

Legend order depends on trace order in the data array.

@ahertel
Copy link

ahertel commented May 11, 2020

@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!

@nicolaskruchten
Copy link
Contributor Author

@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()

@ahertel
Copy link

ahertel commented May 12, 2020

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants