DASH基于3个Dropdown联动更新地图图表的筛选与缩放问题咨询
问题解决方法
核心问题根因
- 筛选逻辑错误:当前使用
|(或)逻辑拼接筛选条件,导致多维度筛选时只要满足任意一个条件就会被保留,无法实现联合筛选效果 - 地图视图固定:布局中
mapbox的center和zoom参数为硬编码固定值,不会根据筛选后的数据集自动调整视图范围 - 未处理下拉空选/全选场景:没有对下拉未选择、品类全选的特殊情况做兼容,容易触发过滤异常
修正后代码
直接替换原有的回调函数部分即可:
@app.callback(Output('map_graph', 'figure'), [Input('country_dropdown', 'value'), Input('category_dropdown', 'value'), Input('district_dropdown', 'value')]) def update_map_graph(chosen_country, chosen_category, chosen_district): # 初始化筛选掩码,默认全选 mask = [True] * len(df) # 国家维度筛选 if chosen_country and len(chosen_country) > 0: mask &= df['Country'].isin(chosen_country) # 行政区维度筛选 if chosen_district and len(chosen_district) > 0: mask &= df['MainLocation'].isin(chosen_district) # 品类维度筛选,处理全选选项 if chosen_category and len(chosen_category) > 0: if 'all' not in chosen_category: mask &= df['Category'].isin(chosen_category) df_sub = df[mask] # 计算筛选后数据集的中心坐标和适配缩放级别 if len(df_sub) > 0: center_lat = df_sub['Lat'].mean() center_lon = df_sub['Long'].mean() # 计算经纬度范围确定缩放级别,可根据实际需求调整系数 lat_range = df_sub['Lat'].max() - df_sub['Lat'].min() lon_range = df_sub['Long'].max() - df_sub['Long'].min() max_range = max(lat_range, lon_range) # 缩放级别映射,范围越大缩放值越小 if max_range > 50: zoom = 3 elif max_range > 20: zoom = 5 elif max_range > 5: zoom = 8 else: zoom = 11 else: # 无数据时使用默认视图 center_lat = 50.1109 center_lon = 8.6821 zoom = 5 # 创建地图图层 locations = [go.Scattermapbox( lon=df_sub['Long'], lat=df_sub['Lat'], mode='markers', marker={'color': df_sub['Color'], 'size': 13, 'opacity': 0.5}, unselected={'marker': {'opacity': 1}}, selected={'marker': {'opacity': 0.5, 'size': 18}}, hoverinfo='text', hovertext=df_sub['Hover'] )] # 返回图表配置 return { 'data': locations, 'layout': go.Layout( autosize=True, margin=dict(l=0, r=0, t=0, b=0), uirevision='foo', clickmode='event+select', hovermode='closest', hoverdistance=2, mapbox=dict( accesstoken=mapbox_access_token, bearing=0, style='mapbox://styles/mapbox/navigation-night-v1', center=dict( lat=center_lat, lon=center_lon ), pitch=0, zoom=zoom ), ) }
可选优化方案
如果需要实现行政区下拉联动(选中国家后仅显示对应国家下的行政区选项),可以新增一个回调动态更新行政区下拉的可选值:
@app.callback( Output('district_dropdown', 'options'), Input('country_dropdown', 'value') ) def update_district_options(chosen_country): if not chosen_country or len(chosen_country) == 0: return [{'label': str(d), 'value': d} for d in sorted(df['MainLocation'].unique())] filtered_districts = df[df['Country'].isin(chosen_country)]['MainLocation'].unique() return [{'label': str(d), 'value': d} for d in sorted(filtered_districts)]
内容的提问来源于stack exchange,提问作者Gabriel Bou Karam
相关产品推荐
相关产品推荐

