Skip to content

Categorical choropleths with legends #3468

Description

@nicolaskruchten

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

Activity

  1. etpinard commented on Jan 23, 2019

    @etpinard
    Contributor

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

  2. etpinard commented on Jan 23, 2019

    @etpinard
    Contributor
  3. etpinard commented on Jan 24, 2019

    @etpinard
    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?

  4. nicolaskruchten commented on Jan 24, 2019

    @nicolaskruchten
    ContributorAuthor

    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.

  5. nicolaskruchten commented on Jan 24, 2019

    @nicolaskruchten
    ContributorAuthor

    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.

  6. etpinard commented on Jan 24, 2019

    @etpinard
    Contributor

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

    So this ⏫ isn't good enough?

  7. nicolaskruchten commented on Jan 24, 2019

    @nicolaskruchten
    ContributorAuthor

    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.

  8. etpinard commented on Jan 24, 2019

    @etpinard
    Contributor

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

  9. nicolaskruchten commented on Jan 24, 2019

    @nicolaskruchten
    ContributorAuthor

    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.

  10. etpinard commented on Jan 24, 2019

    @etpinard
    Contributor

    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.

  11. nicolaskruchten commented on Jan 24, 2019

    @nicolaskruchten
    ContributorAuthor

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

  12. etpinard commented on Jan 24, 2019

    @etpinard
    Contributor

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

    Related:

  13. nicolaskruchten commented on Jan 24, 2019

    @nicolaskruchten
    ContributorAuthor

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

    image

    image

    image

  14. nicolaskruchten commented on Jan 24, 2019

    @nicolaskruchten
    ContributorAuthor

    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.

  15. 8 remaining items

  16. etpinard commented on Jan 24, 2019

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

  17. nicolaskruchten commented on Jan 24, 2019

    @nicolaskruchten
    ContributorAuthor

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

  18. etpinard commented on Jan 24, 2019

    @etpinard
    Contributor

    Slipping in @nicolaskruchten 's creation

    image

    for everyone's enjoyment 😄

  19. self-assigned this
    on Nov 29, 2019
  20. added this to the v1.52.0 milestone on Nov 29, 2019
  21. TJ-Tubi commented on Feb 2, 2020

    @TJ-Tubi

    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!

  22. nicolaskruchten commented on Feb 2, 2020

    @nicolaskruchten
    ContributorAuthor

    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.

  23. TJ-Tubi commented on Feb 2, 2020

    @TJ-Tubi

    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.

  24. nicolaskruchten commented on Feb 2, 2020

    @nicolaskruchten
    ContributorAuthor

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

  25. secsilm commented on Feb 22, 2020

    @secsilm

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

  26. nicolaskruchten commented on Feb 22, 2020

    @nicolaskruchten
    ContributorAuthor

    Legend order depends on trace order in the data array.

  27. ahertel commented on May 11, 2020

    @ahertel

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

  28. nicolaskruchten commented on May 11, 2020

    @nicolaskruchten
    ContributorAuthor

    @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()
  29. ahertel commented on May 12, 2020

    @ahertel

    @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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions