Question: I'm hoping to include multiple callbacks or combine them to filter data. These functions will be used to visualise graphs. The first callback returns point data if it's within a designated region. It is assigned to a dropdown bar called area-dropdown. The dropdown bar and callback function returns smaller subsets from the main df. This is accomplished by merging the point data within a specific polygon area. The additional callback functions are for a scatter mapbox chart and bar chart. They filter unique values in Code and Cat. At present, I've got the callback functions that filter unique values in Code and Cat operational. This is outlined in the 2nd batch of code. If I comment this section out and use the 1st batch of code, the area dropdown callback is functional. I'm aiming to find a method that combines both these functions together. import geopandas as gpd import plotly.express as px import dash from dash import dcc, html, Input, Output import dash_bootstrap_components as dbc from dash.dependencies import Input, Output import dash_bootstrap_components as dbc import plotly.express as px import plotly.graph_objs as go import plotly.figure_factory as ff import geopandas as gpd from itertools import cycle # point data gdf_all = gpd.read_file(gpd.datasets.get_path("naturalearth_cities")) i = iter(['A', 'B', 'C', 'D']) gdf_all['Cat'] = gdf_all.index.map(dict(zip(gdf_all.index, cycle(i)))) j = iter(['10-20', '20-30', '30-40', '40-50', '60-70']) gdf_all['Code'] = gdf_all.index.map(dict(zip(gdf_all.index, cycle(j)))) # polygon data gdf_poly = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres")) gdf_poly = gdf_poly.drop('name', axis = 1) gdf_all['LON'] = gdf_all['geometry'].x gdf_all['LAT'] = gdf_all['geometry'].y # subset African continent Afr_gdf_area = gdf_poly[gdf_poly['continent'] == 'Africa'].reset_index(drop = True) # subset European continent Eur_gdf_area = gdf_poly[gdf_poly['continent'] == 'Europe'].reset_index(drop = True) # function to merge point data within selected polygon area def merge_withinboundary(gdf1, gdf2): # spatial join data within larger boundary gdf_out = gpd.sjoin(gdf1, gdf2, predicate = 'within', how = 'inner').reset_index(drop = True) return gdf_out gdf_Africa = merge_withinboundary(gdf_all, Afr_gdf_area) gdf_Europe = merge_withinboundary(gdf_all, Eur_gdf_area) external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP] app = dash.Dash(__name__, external_stylesheets = external_stylesheets) nav_bar = html.Div([ html.P("area-dropdown:"), dcc.Dropdown( id = 'data', value = 'data', options = [{'value': 'gdf_all', 'label': 'gdf_all'}, {'value': 'gdf_Africa', 'label': 'gdf_Africa'}, {'value': 'gdf_Europe', 'label': 'gdf_Europe'} ], clearable=False ), html.Label('Code', style = {'paddingTop': '1rem'}), dcc.Checklist( id = 'Code', options = [ {'label': '10-20', 'value': '10-20'}, {'label': '20-30', 'value': '20-30'}, {'label': '30-40', 'value': '30-40'}, {'label': '40-50', 'value': '40-50'}, {'label': '60-70', 'value': '60-70'}, ], value = ['10-20', '20-30', '30-40', '40-50', '60-70'], style = {'display': 'inline', 'margin-right': '50px'} ), html.Label('Cat', style = {'paddingTop': '1rem'}), dcc.Checklist( id = 'Cat', options = [ {'label': 'A', 'value': 'A'}, {'label': 'B', 'value': 'B'}, {'label': 'C', 'value': 'C'}, {'label': 'D', 'value': 'D'}, ], value = ['A', 'B', 'C', 'D'], style = {'display': 'inline', 'margin-right': '50px'} ), html.Label('Spatial Map', style = {'paddingTop': '1rem'}), dcc.RadioItems(['Scatter','Hexbin'],'Scatter', id = 'maps', #labelStyle= {"margin":"1rem"}, style = {'display': 'inline', 'margin-right': '50px'} ), ], className = "vstack gap-2 h-50") app.layout = dbc.Container([ dbc.Row([ dbc.Col(html.Div(nav_bar), className = 'bg-light', width=2), dbc.Col([ dbc.Row([ dbc.Col(dcc.Graph(id = 'spatial-chart')) ]), dbc.Row([ dbc.Col(dcc.Graph(id = 'bar-chart')) ]), ], width = 5), dbc.Col([ ], width = 5), ]) ], fluid = True) df = gdf_all #================ 1st ======================= # function to return selected df for plotting #@app.callback(Output('spatial-chart', 'figure'), # Output('bar-chart', 'figure'), # Input('data', 'value'), # prevent_initial_call=True) # function to return df using smaller areas #def update_dataset(dropdown_selection): # if dropdown_selection == 'gdf_Africa': # gdf = gdf_Africa # zoom = 2 # elif dropdown_selection == 'gdf_Europe': # gdf = gdf_Europe # zoom = 2 # else: # gdf = gdf_all # zoom = 0 # scatter_subset = px.scatter_mapbox(data_frame = gdf, # lat = 'LAT', # lon = 'LON', # zoom = zoom, # mapbox_style = 'carto-positron', # ) # count = gdf['name'].value_counts() # bar_subset = px.bar(x = count.index, # y = count.values, # color = count.index, # ) # return scatter_subset, bar_subset #============================================= #================ 2nd ======================= # function to filter unique Cat/Code for bar chart @app.callback( [Output('bar-chart', 'figure'), ], [Input('Cat','value'), Input('Code','value'), ] ) def date_chart(cat, code): dff = df[df['Cat'].isin(cat)] dff = dff[dff['Code'].isin(code)] count = dff['Cat'].value_counts() data = px.bar(x = count.index, y = count.values, color = count.index, ) fig = [go.Figure(data = data)] return fig # function to filter unique Cat/Code for scatter @app.callback( [Output('spatial-chart', 'figure'), ], [Input('Cat','value'), Input('Code','value'), Input("maps", "value"), ]) def scatter_chart(cat, code, maps): if maps == 'Scatter': dff = df[df['Cat'].isin(cat)] dff = dff[dff['Code'].isin(code)] data = px.scatter_mapbox(data_frame = dff, lat = 'LAT', lon = 'LON', color = 'Cat', opacity = 0.5, zoom = 1, mapbox_style = 'carto-positron', hover_name = 'Cat', ) fig = [go.Figure(data = data)] elif maps == 'Hexbin': dff = df[df['Cat'].isin(cat)] dff = dff[dff['Code'].isin(code)] data = ff.create_hexbin_mapbox(data_frame = dff, lat = "LAT", lon = "LON", nx_hexagon = 100, min_count = 1, ) fig = [go.Figure(data = data)] return fig #============================================= if __name__ == '__main__': app.run_server(debug=True, port = 8051) 

Answer: I combined your callback functions update_dataset, date_chart and scatter_chart into a single callback. This function processes the dropdown selection, both checklists, and the radioitem components and outputs the updated scatter mapbox and bar charts. import geopandas as gpd import plotly.express as px import dash from dash import dcc, html, Input, Output import dash_bootstrap_components as dbc from dash.dependencies import Input, Output import dash_bootstrap_components as dbc import plotly.express as px import plotly.graph_objs as go import plotly.figure_factory as ff import geopandas as gpd from itertools import cycle # point data gdf_all = gpd.read_file(gpd.datasets.get_path("naturalearth_cities")) i = iter(['A', 'B', 'C', 'D']) gdf_all['Cat'] = gdf_all.index.map(dict(zip(gdf_all.index, cycle(i)))) j = iter(['10-20', '20-30', '30-40', '40-50', '60-70']) gdf_all['Code'] = gdf_all.index.map(dict(zip(gdf_all.index, cycle(j)))) # polygon data gdf_poly = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres")) gdf_poly = gdf_poly.drop('name', axis = 1) gdf_all['LON'] = gdf_all['geometry'].x gdf_all['LAT'] = gdf_all['geometry'].y # subset African continent Afr_gdf_area = gdf_poly[gdf_poly['continent'] == 'Africa'].reset_index(drop = True) # subset European continent Eur_gdf_area = gdf_poly[gdf_poly['continent'] == 'Europe'].reset_index(drop = True) # function to merge point data within selected polygon area def merge_withinboundary(gdf1, gdf2): # spatial join data within larger boundary gdf_out = gpd.sjoin(gdf1, gdf2, predicate = 'within', how = 'inner').reset_index(drop = True) return gdf_out gdf_Africa = merge_withinboundary(gdf_all, Afr_gdf_area) gdf_Europe = merge_withinboundary(gdf_all, Eur_gdf_area) external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP] app = dash.Dash(__name__, external_stylesheets = external_stylesheets) nav_bar = html.Div([ html.P("area-dropdown:"), dcc.Dropdown( id = 'data', value = 'data', options = [{'value': 'gdf_all', 'label': 'gdf_all'}, {'value': 'gdf_Africa', 'label': 'gdf_Africa'}, {'value': 'gdf_Europe', 'label': 'gdf_Europe'} ], clearable=False ), html.Label('Code', style = {'paddingTop': '1rem'}), dcc.Checklist( id = 'Code', options = [ {'label': '10-20', 'value': '10-20'}, {'label': '20-30', 'value': '20-30'}, {'label': '30-40', 'value': '30-40'}, {'label': '40-50', 'value': '40-50'}, {'label': '60-70', 'value': '60-70'}, ], value = ['10-20', '20-30', '30-40', '40-50', '60-70'], style = {'display': 'inline', 'margin-right': '50px'} ), html.Label('Cat', style = {'paddingTop': '1rem'}), dcc.Checklist( id = 'Cat', options = [ {'label': 'A', 'value': 'A'}, {'label': 'B', 'value': 'B'}, {'label': 'C', 'value': 'C'}, {'label': 'D', 'value': 'D'}, ], value = ['A', 'B', 'C', 'D'], style = {'display': 'inline', 'margin-right': '50px'} ), html.Label('Spatial Map', style = {'paddingTop': '1rem'}), dcc.RadioItems(['Scatter','Hexbin'],'Scatter', id = 'maps', #labelStyle= {"margin":"1rem"}, style = {'display': 'inline', 'margin-right': '50px'} ), ], className = "vstack gap-2 h-50") app.layout = dbc.Container([ dbc.Row([ dbc.Col(html.Div(nav_bar), className = 'bg-light', width=2), dbc.Col([ dbc.Row([ dbc.Col(dcc.Graph(id = 'spatial-chart')) ]), dbc.Row([ dbc.Col(dcc.Graph(id = 'bar-chart')) ]), ], width = 5), dbc.Col([ ], width = 5), ]) ], fluid = True) df = gdf_all @app.callback( [Output('bar-chart', 'figure'), Output('spatial-chart', 'figure'), ], [Input('data', 'value'), Input('Cat', 'value'), Input('Code','value'), Input('maps', 'value'), ] ) def update_charts(dropdown_selection, cat, code, maps): ## dropdown defines df before the other inputs subset it further if dropdown_selection == 'gdf_Africa': df = gdf_Africa zoom = 2 elif dropdown_selection == 'gdf_Europe': df = gdf_Europe zoom = 2 else: df = gdf_all zoom = 0 dff = df[df['Cat'].isin(cat)] dff = dff[dff['Code'].isin(code)] count = dff['Cat'].value_counts() data = px.bar(x = count.index, y = count.values, color = count.index, ) fig_bar = go.Figure(data = data) if maps == 'Scatter': dff = df[df['Cat'].isin(cat)] dff = dff[dff['Code'].isin(code)] data = px.scatter_mapbox(data_frame = dff, lat = 'LAT', lon = 'LON', color = 'Cat', opacity = 0.5, zoom = 1, mapbox_style = 'carto-positron', hover_name = 'Cat', ) fig_mapbox = go.Figure(data = data) elif maps == 'Hexbin': dff = df[df['Cat'].isin(cat)] dff = dff[dff['Code'].isin(code)] data = ff.create_hexbin_mapbox(data_frame = dff, lat = "LAT", lon = "LON", nx_hexagon = 100, min_count = 1, ) fig_mapbox = go.Figure(data = data) return fig_bar, fig_mapbox if __name__ == '__main__': app.run_server(debug=True, port = 8051)