I'm hoping to include a dropdown bar with a callback function that allows the user to display specific points within smaller areas. Initially, I want to use all point geometry data as a default. I'm then aiming to include a dropdown bar and callback function that returns smaller subsets from this main df. This is accomplished by merging the point data within a specific polygon area.
Using below, the default df is labelled gdf_all. This contains point data across a large region. The smaller polygon files are subset from gdf_poly. These include African and European continents. These are used within a function to only return point data if it intersects within the polygon shape.
I've hard-coded the outputs below. 1) uses gdf_all and 2) uses a subset from African contintent.
Ideally, the dropdown bar will be used to input the desired point data to be visualised within the figures.
import geopandas as gpd
import plotly.express as px
import dash
from dash import dcc
from dash import html
import dash_bootstrap_components as dbc
# point data
gdf_all = gpd.read_file(gpd.datasets.get_path("naturalearth_cities"))
# 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 = 'left').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)
# function to return selected df for plotting
def update_dataset(df):
if df == 'gdf_Africa':
gdf = gdf_Africa
elif df == 'gdf_Europe':
gdf = gdf_Europe
else:
gdf = gdf_all
return gdf
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
),
])
# output 1
df = gdf_all
# output 2
#df = gdf_Africa
scatter = px.scatter_mapbox(data_frame = df,
lat = 'LAT',
lon = 'LON',
zoom = 2,
mapbox_style = 'carto-positron',
)
count = df['name'].value_counts()
bar = px.bar(x = count.index,
y = count.values,
color = count.index,
)
app.layout = dbc.Container([
dbc.Row([
dbc.Col(html.Div(nav_bar), width=2),
dbc.Col([
dbc.Row([
dbc.Col(dcc.Graph(figure = scatter))
]),
dbc.Row([
dbc.Col(dcc.Graph(figure = bar))
]),
], width=5),
dbc.Col([
], width=5),
])
], fluid=True)
if __name__ == '__main__':
app.run_server(debug=True, port = 8051)
Output 1:
Output 2:
from Callback to subset geometry data - dash Plotly


No comments:
Post a Comment