Callback to change a Choropleth mapbox

Hello
I am triying to do a callback but the map is not working.
The process is the follow:

  1. If you select in the check box “Poblacion” you should to see the choropleth map (This is not working)
  2. If you select in the check box “Ingreso” you should to see a bar (This is ok)

However when you select “Poblacion” nothing appear in the graph. I was trying many things for a couple weeks but without succesful.

Thanks

    html.Div(
        className='row app-body', 
        children=[
        dcc.Checklist(
            id = 'MapFilter',
            options=[
                {'label': 'Poblacion', 'value': 'Poblacion'},
                {'label': 'IngresosPromedio', 'value': 'IngresosPromedio'}
            ],
            value=['Poblacion'],
            labelStyle={'display': 'inline-block'}
        ),           
    ]),
    html.Div([
        html.Div([
            
            dcc.Graph(
                id='MapPlot',
                style={
                    "height":"900px",
                    "width":"110%"
                },    

            ),
            
        ],className="six columns"),
@app.callback(
    dash.dependencies.Output('MapPlot', 'figure'),
    [dash.dependencies.Input('MapFilter', 'value')])


def update_image_src2(selector):
    
    data = []
    if 'Poblacion' in selector:
        data.append({'type': 'Choroplethmapbox','geojson': 'counties','locations': dfPobMap.Name_Dpto, 'z': dfPobMap.fex_c_2011_x,'colorscal':'Viridis','colorbar_title': 'Población'})
    if 'IngresosPromedio' in selector:
        data.append({'x': dfIncomeAverage2["Name_Dpto"], 'y': dfIncomeAverage2["INGLABO"], 'type': 'bar', 'name': '2019'})


    figure={ 
        'data': data,
        'layout': go.Layout(
                mapbox_style="carto-positron",
                mapbox_accesstoken=token,
                mapbox_zoom=4.3,
                mapbox_center = {"lat": 4.208112, "lon": -72.739072},
            )
    }
    return figure

Hi @salascorp
If you share your data, I can try to run it on my computer and help. Mientras tanto, this tutorial I created might be helpful.

1 Like

Hello Adam,
I am new to this right now I have a problem similar to the one proposed in this topic. I have a layer of several points and when I click on any of them I want to show some figure (histogram for example) and the title of the point I select.
What is the possibility that you can guide me? I could share with you the code and the data

hi @Adrian593_gis
:wave: Welcome to the community.
For sure. I’d be happy to help.

Please share your code and data here. If your code is very long, just create a simpler/smaller version that can be executed with some data.

thank you very much @adamaschroeder , I have checked but I have no success. could you guide me this is the code, I do not understand why I get the error. I have a layer of several points and when I click on any of them I want to show some figure (histogram for example) and the title of the point I select.

import dash
import dash_html_components as html 
import plotly.graph_objects as go
import plotly.express as px
from dash import Dash, dcc, html, Output, Input, State, callback
import dash_core_components as dcc
import pandas as pd
import json                 

app = dash.Dash()

df = pd.read_csv(r'https://estrategis-ec.com/data_dash/data.csv', delimiter=';',encoding = 'ISO-8859-1')

 def fig_map(df):
fig= px.scatter_mapbox(df, lat="lat", lon="lon",
    height=600,width=900,
                color="Empresas",size="Empresas",size_max=75,animation_frame = 'year', 
                color_continuous_scale='viridis',
         mapbox_style="carto-positron",zoom=5.5,  hover_name="City",
                                  center = {"lat": -2, "lon": -79.01})

return fig


app.layout = html.Div([
     
        html.Div([
            dcc.Graph(id = 'map_plot1', figure = fig_map(df))],
            style = {'width':'75%','display':'inline-block'}),
           
      html.Div([ 
          dcc.Graph(figure={}, id='my-graph', 
                    style = {'width':'25%','display':'inline-block'})
            ]) ]) 

           ##calback
@callback(
Output(component_id='my-graph', component_property='figure'),
Input(component_id='map_plot1', component_property='clickData'))   

def update_graph(clickData):
city = clickData['points'][0]['pointNumber'][0]
dff = df[df['City'] == city]
title = '<b>{}</b><br>{}'.format(city)
fig = px.line(dff, x='year', y='Empresas', title=f'{title}')
return fig

 if __name__ == '__main__': 
app.run_server(debug=True, use_reloader=False,port=8059)

@adamschroeder

hi @Adrian593_gis

Can you please share your data.csv file. That will allow us to run your code.

What error message do you get?

Also what happens if you put in a print statement on the second line under the callback function?

def update_graph(clickData):
city = clickData['points'][0]['pointNumber'][0]
print(city)
dff = df[df['City'] == city]

hi @adamschroeder
the data are in this link : https://estrategis-ec.com/data_dash/data.csv

the error I get is that : TypeError: ‘int’ object is not subscriptable

hi @Adrian593_gis

Try this:

import dash
import dash_html_components as html
import plotly.graph_objects as go
import plotly.express as px
from dash import Dash, dcc, html, Output, Input, State, callback, no_update
import dash_core_components as dcc
import pandas as pd
import json

app = dash.Dash()

df = pd.read_csv('data1.csv')

def fig_map(df):
    fig = px.scatter_mapbox(df, lat="lat", lon="lon",
                            height=600, width=900,
                            color="Empresas", size="Empresas", size_max=75, animation_frame='year',
                            color_continuous_scale='viridis',
                            mapbox_style="carto-positron", zoom=5.5, hover_name="City",
                            center={"lat": -2, "lon": -79.01})

    return fig

app.layout = html.Div([

    html.Div([
        dcc.Graph(id='map_plot1', figure=fig_map(df))],
        style={'width': '75%', 'display': 'inline-block'}),

    html.Div(style={'width': '25%', 'display': 'inline-block'}, id='my-graph-container')
])


##calback
@callback(
    Output(component_id='my-graph-container', component_property='children'),
    Input(component_id='map_plot1', component_property='clickData'))
def update_graph(clickData):
    if clickData:
        city = clickData['points'][0]['hovertext']
        print(city)

        dff = df[df['City'] == city]
        print(dff.head())
        fig1 = px.line(dff, x='year', y='Empresas', title=city)
        return dcc.Graph(figure=fig1)
    else:
        no_update


if __name__ == '__main__':
    app.run_server(debug=True, use_reloader=False, port=8059)

Another option to find the city is to use the lat/lon combo to figure out with city the user clicked on. This could be more reliable than the hovertext.

1 Like

Great, I am very grateful to you @adamschroeder
I have a lot to learn and this feedback and material is very useful.

1 Like