Interactively Change A Point Plot In Bokeh Using Rangeslider To Select Columns In A Pandas Dataframe
I have a pandas dataframe df where the first two columns represent x, y coordinates and the remaining columns represent time slices (t0,...tn) where the presence(1) or absence(0) o
Solution 1:
There are a number of issues in the code above:
- It is
cb_obj
notcb.obj
- Use modern
js_on_change
, not very old ad-hoccallback
parameters - You are assigning to a local variable
data
and then throwing away the result— need to literally assign tosource.data
at some point for there to be any effect. - To do this by updating data sources you would need two data sources, on that always has the complete data that you pull from, and another that you only use to hold the subset. If you only have one data source and you subset it, you've now thrown away data you can never get back. (Future subsets will be against the current subset, not the whole)
- So, better to use
CDSView
for this, which lets you express an update-able subset view to apply to a constant data source. - JS does not have Pandas-like operations, you just have to do all the nested looping to check every row to determine the subset indices
- Just guessing, but you will probably want to fix x/y ranges if you intend to maintain the same spatial extent for comparison, as the slider moves.
Here is a simplified working example:
from bokeh.layouts import column
from bokeh.plotting import figure, show
from bokeh.models import CustomJS, ColumnDataSource, RangeSlider, CDSView, IndexFilter
source = ColumnDataSource(data=dict(
x=[1,2,3,4],
y=[1,1,1,1],
t0=[1,1,0,0],
t1=[0,1,0,0],
t2=[0,1,1,0],
t3=[0,0,1,1],
t4=[0,0,0,1],
t5=[0,0,0,0],
))
p = figure(plot_height=500, x_range=(0,5), y_range=(0,2))
view = CDSView(source=source, filters=[IndexFilter([0, 1])])
p.circle('x', 'y', size=10, color="navy", alpha=0.8,
source=source, view=view)
callback = CustomJS(args=dict(source=source, view=view), code="""
const start = cb_obj.value[0]
const end = cb_obj.value[1]
const indices = []
for (var i=0; i < source.get_length(); i++) {
for (var j=start; j<=end; j++) {
if (source.data["t" + j][i]==1) {
indices.push(i)
break
}
}
}
view.indices = indices
""")
ti_slider = RangeSlider(start=0, end=5, value=(0,1), step=1, title="Time Period")
ti_slider.js_on_change('value', callback)
show(column(ti_slider, p))
Post a Comment for "Interactively Change A Point Plot In Bokeh Using Rangeslider To Select Columns In A Pandas Dataframe"