Hello all,
I’m plotting patches from a GeoJSONDataSource source and I would like to update what I am displaying based on a Select widget. It seems like I am able to update and change the data source but it is not displaying in the patches plot (patches plot still shows the original GeoJSONDataSource even though I have updated it to only be a subset of the data).
The following code is a simplified version of what I’m trying to do: I have created 4 shapes in geoJSON data format, have created a GeoJSONDataSource object from this, and have a a Select Widget which allows me to chose between the 4 different shapes. If any one of those shapes is selected in the Select Widget, I would like to only show that shape being plotted.
import pandas as pd
import geopandas as gpd
import numpy as np
import json
from bokeh import events
from bokeh.models import (Select, Column, Row, ColumnDataSource, HoverTool,
GeoJSONDataSource)
from bokeh.plotting import figure
from bokeh.io import curdoc
def make_geo_plot(src):
# function to create the spatial plot with polygons
p = figure(width=300, height=300, title="Select area", tools=['tap', 'pan', 'box_zoom', 'wheel_zoom','reset'])
layer = p.patches('xs', 'ys', fill_alpha=0.2, fill_color='black',
line_color='black', line_width=0.5, source=src)
return p, layer
def update_goe_plot_from_select(attrname, old, new):
# Callback for the dropdown menu which updates the geo chart
new_geo_src_data = get_source_data(geojson_pd, area_select.value)
new_geo_src_stack = new_geo_src_data.stack()
geo_source.geojson = new_geo_src_stack.to_json(default_handler=str)
layer.update(data_source=geo_source)
def get_source_data(df, fieldid):
# function to get a subset of the multi-hierarchical DataFrame
geojson_pd_filter = df[df.key==fieldid]
return geojson_pd_filter
#example polygons
geojson = """{"type":"FeatureCollection",
"crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:OGC:1.3:CRS84"}},
"features":[
{"type":"Feature","properties":{"key":"area_a"},"geometry":{"type":"MultiPolygon","coordinates":
[[[[-108.8,42.7],[-104.5,42.0],[-108.3,39.3],[-108.8,42.7]]]]}},
{"type":"Feature","properties":{"key":"area_b"},"geometry":{"type":"MultiPolygon","coordinates":
[[[[-106.3,44.0],[-106.2,42.6],[-103.3,42.6],[-103.4,44.0],[-106.3,44.0]]]]}},
{"type":"Feature","properties":{"key":"area_d"},"geometry":{"type":"MultiPolygon","coordinates":
[[[[-104.3,41.0],[-101.5,41.0],[-102.9,37.8],[-104.3,41.0]]]]}},
{"type":"Feature","properties":{"key":"area_c"},"geometry":{"type":"MultiPolygon","coordinates":
[[[[-105.8,40.3],[-108.3,37.7],[-104.0,37.4],[-105.8,40.3]]]]}}]}"""
#following to act as dataframe for easy filtering
geojson_json = json.loads(geojson)
geojson_pd = gpd.GeoDataFrame.from_features(geojson_json["features"])
#crearting the geo source for plotting the shapes as patches:
geo_source = GeoJSONDataSource(geojson=geojson)
#creating the select widget:
area_ids = ['area_a', 'area_b', 'area_c', 'area_d']
area_select = Select(value=area_ids[0], title='Select area', options=area_ids)
area_select.on_change('value', update_goe_plot_from_select)
p_geo, layer = make_geo_plot(geo_source)
# add to document
curdoc().add_root(Row(Column(area_select), p_geo))
I am new to Bokeh and I’d be greatly appreciative if someone could send me in the right direction to solve this. thank you so much.