How can I edit the legend of a chloropleth map?

43 Views Asked by At

I am working on a map showing the minimum wage across the states in the US.

My code generates a map that looks good, but the legend is unordered, which is awkward. I would like it to be in ascending order (ie $7.25-8, $8-9,...). Along with this, the legend title currently just says "color" and I would like to be able to change this to be more descriptive. How can I do this?

Here is my current code:


import plotly.express as px


fig = px.choropleth(locations=df['state'], 
                    locationmode='USA-states',
                    color=df['wage_cat'],
                    color_discrete_map={ '$7.25-8':'#e0e6f6',
 '$8-9':'#c1ccee',
 '$9-10':'#a2b3e5',
    '$10-11':'#8399dd',
 '$11-12':'#6480d4',
 '$12-13':'#4566cb',
 '$13-14':'#3353b7',
 '$14-15':'#2a4598',
 '$15-16':'#223779',
 '$17-18':'#19295A',
                                       'No state minimum wage':'#f9fafd'}
    )

fig.update_layout(
    title_text='State Minimum Wage as of 1-1-24',
    
    geo = dict(
        scope='usa',
        projection=go.layout.geo.Projection(type = 'albers usa'),
        showlakes=True, # lakes
        lakecolor='rgb(255, 255, 255)'),
)
                   
fig.show()
1

There are 1 best solutions below

2
Derek O On BEST ANSWER

You can make the wage_cat column a CategoricalDtype (see documentation here), then sort df by wage_cat before passing it to px.choropleth. To update the legend title, you can use the legend_title_text argument in fig.update_layout.

Something like the following:

all_wage_categories = ['$7.25-8',
 '$8-9',
 '$9-10',
 '$10-11',
 '$11-12',
 '$12-13',
 '$13-14',
 '$14-15',
 '$15-16',
 '$17-18',
 'No state minimum wage']

df['wage_cat'] = pd.Categorical(df['wage_cat'], 
                      categories=all_wage_categories,
                      ordered=True)
df = df.sort_values(by=['wage_cat'])

Using some sample data, here is a fully reproducible example:

import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px

states = [ 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
           'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
           'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
           'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
           'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']

np.random.seed(42)
all_wage_categories = ['$7.25-8',
 '$8-9',
 '$9-10',
 '$10-11',
 '$11-12',
 '$12-13',
 '$13-14',
 '$14-15',
 '$15-16',
 '$17-18',
 'No state minimum wage']

wages = np.random.choice(all_wage_categories, size=51)
df = pd.DataFrame({
    'state': states,
    'wage_cat': wages
})

df['wage_cat'] = pd.Categorical(df['wage_cat'], 
                      categories=all_wage_categories,
                      ordered=True)
df = df.sort_values(by=['wage_cat'])

fig = px.choropleth(locations=df['state'], 
                    locationmode='USA-states',
                    color=df['wage_cat'],
                    color_discrete_map={ '$7.25-8':'#e0e6f6',
 '$8-9':'#c1ccee',
 '$9-10':'#a2b3e5',
    '$10-11':'#8399dd',
 '$11-12':'#6480d4',
 '$12-13':'#4566cb',
 '$13-14':'#3353b7',
 '$14-15':'#2a4598',
 '$15-16':'#223779',
 '$17-18':'#19295A',
                                       'No state minimum wage':'#f9fafd'}
    )

fig.update_layout(
    title_text='State Minimum Wage as of 1-1-24',
    legend_title_text='Wage Category',
    
    geo = dict(
        scope='usa',
        projection=go.layout.geo.Projection(type = 'albers usa'),
        showlakes=True, # lakes
        lakecolor='rgb(255, 255, 255)'),
)
                   
fig.show()

enter image description here