6
votes

I am trying to create choropleth maps. Below is an example that works:

df = px.data.gapminder().query("year==2007")

fig = go.Figure(data=go.Choropleth(
    locations=happy['iso'], # Spatial coordinates
    z = happy['Happiness'].astype(float), # Data to be color-coded
    colorbar_title = "Happiness Score",
))

fig.update_layout(
    title_text = 'Life Expectancy in 2007'
)

fig.show()

However, I would like to create a dropdown menu that will change the plotted values between different variables (e.g., Life Expectancy, GDP, Population). I believe that this is possible but have not seen any tutorial online. Most of them just uses other kind of barcharts or scatterplots.

Here is what I have gotten so far:

# Initialize figure
fig = go.Figure()

# Add Traces
fig.add_trace(go.Figure(data=go.Choropleth(
    locations=df['iso_alpha'], # Spatial coordinates
    z = df['lifeExp'].astype(float), # Data to be color-coded
    colorbar_title = "Life Expectancy")))

fig.add_trace(go.Figure(data=go.Choropleth(
    locations=df['iso_alpha'], # Spatial coordinates
    z = df['gdpPercap'].astype(float), # Data to be color-coded
    colorbar_title = "GDP per capita")))

But I am not sure how to proceed from here. Do I need to update the layout of the figure via fig.update_layout or something?

1
Do you want to do it on dash or on plain plotly?rpanai
My goal is to do it on plotly first to learn and then port to dash!TYL
@rpanai Why not both? I'd love to see some examples on this =)vestland
@westland as you wish :Drpanai
@rpanai Nicely done!vestland

1 Answers

6
votes

There are two ways to solve this

Dash

# save this as app.py
import pandas as pd
import plotly.graph_objs as go
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html

# Data
df = px.data.gapminder().query("year==2007")

df = df.rename(columns=dict(pop="Population",
                            gdpPercap="GDP per Capita",
                            lifeExp="Life Expectancy"))

cols_dd = ["Population", "GDP per Capita", "Life Expectancy"]

app = dash.Dash()
app.layout = html.Div([
    dcc.Dropdown(
        id='demo-dropdown',
        options=[{'label': k, 'value': k} for k in cols_dd],
        value=cols_dd[0]
    ),

    html.Hr(),
    dcc.Graph(id='display-selected-values'),

])

@app.callback(
    dash.dependencies.Output('display-selected-values', 'figure'),
    [dash.dependencies.Input('demo-dropdown', 'value')])
def update_output(value):
    fig = go.Figure()
    fig.add_trace(go.Choropleth(
       locations=df['iso_alpha'], # Spatial coordinates
        z=df[value].astype(float), # Data to be color-coded
        colorbar_title=value))
    fig.update_layout(title=f"<b>{value}</b>", title_x=0.5)
    return fig

if __name__ == '__main__':
    app.run_server()

run this as python app.py and go to http://127.0.0.1:8050

Plotly

In this case we need to play with visibility of different traces and create buttons in a way they show one traces and hide all the others.

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

# Data
df = px.data.gapminder().query("year==2007")
df = df.rename(columns=dict(pop="Population",
                            gdpPercap="GDP per Capita",
                            lifeExp="Life Expectancy"))
cols_dd = ["Population", "GDP per Capita", "Life Expectancy"]
# we need to add this to select which trace 
# is going to be visible
visible = np.array(cols_dd)

# define traces and buttons at once
traces = []
buttons = []
for value in cols_dd:
    traces.append(go.Choropleth(
       locations=df['iso_alpha'], # Spatial coordinates
        z=df[value].astype(float), # Data to be color-coded
        colorbar_title=value,
        visible= True if value==cols_dd[0] else False))

    buttons.append(dict(label=value,
                        method="update",
                        args=[{"visible":list(visible==value)},
                              {"title":f"<b>{value}</b>"}]))

updatemenus = [{"active":0,
                "buttons":buttons,
               }]


# Show figure
fig = go.Figure(data=traces,
                layout=dict(updatemenus=updatemenus))
# This is in order to get the first title displayed correctly
first_title = cols_dd[0]
fig.update_layout(title=f"<b>{first_title}</b>",title_x=0.5)
fig.show()