Hi @Bryan, thank you for your reply. I will appreciate it if you can guide me if some usage improvements are needed or if it is the library limits. Please refer to the MRE tested on the bokeh server. I am facing exactly the same behavior with my bokeh server app that I face with this.
You will see that when you will:
-
Use the xpan tool, the response of the plots in adjusting the xaxis/xrange will be too slow, and a similar behavior when using xbox_zoom or other tools
-
Drag the highlighted-box/selected-range (green box) of the rangetool below each main plot, the response of the plots will be too slow.
Thank you so much.
Ps: Ignore the dummy data part in the following MRE.
import pandas as pd
import numpy as np
import random
from bokeh.plotting import figure
from bokeh.models import Button, ColumnDataSource, RangeTool
from bokeh.layouts import layout
from bokeh.io import curdoc
# =============================================================================
# Dummy data
# =============================================================================
direction = []
for i in range(int(105120/144)):
x = random.randint(0, 360)
j = [random.randint(1,2) for i in range(144)]
for k in j:
xj = x+k
direction.append(xj)
speed = []
for i in range(int(105120/144)):
x = random.randint(1, 25)
j = [random.randint(1,2) for i in range(144)]
for k in j:
xj = x+k
speed.append(xj)
ts = [pd.to_datetime('01-01-2022')+pd.Timedelta(x,
"T") for x in np.arange(0,
1051200,
10)]
my_dict = {'Time' : ts,
'speed1' : speed,
'speed2' : [i+np.round(random.uniform(1,2),2) for i in speed],
'direction1' : direction,
'direction2' : [i+random.randint(1,3) for i in direction]}
my_df = pd.DataFrame.from_dict(my_dict)
my_df.set_index('Time', inplace=True, drop=True)
# =============================================================================
# =============================================================================
# Function to make plot silimar to www.docs.bokeh.org/en/2.4.3/docs/gallery/range_tool.html
# =============================================================================
def plot(df, xrange):
source = ColumnDataSource(data=df)
tools = ['xpan', 'xwheel_zoom', 'xbox_zoom', 'xzoom_in',
'yzoom_out', 'undo', 'reset']
p = figure(width=768, height=360, x_axis_type='datetime',
tools=tools, toolbar_location="right", x_range=xrange)
for i,c in zip(df.columns, ['red', 'black']):
# if the columns are direction then scatter/dot plot else line plot
if i in ['direction1', 'direction2']:
p.dot(x='Time', y=i, width=10, size=10, source=source,
legend_label=i, color=c)
p.title.text = "Directions Plot"
else:
p.line(x='Time', y=i, width=2, source=source, legend_label=i,
color=c)
p.title.text = "Speeds Plot"
p.legend.click_policy="hide"
# Range tool plot below the main plot
range_tool = RangeTool(x_range=p.x_range)
range_tool.overlay.fill_color = "green"
range_tool.overlay.fill_alpha = 0.35
s = figure(height=120, width=768, x_axis_type="datetime",
y_axis_type=None, tools='', toolbar_location=None)
for i,c in zip(df.columns, ['red', 'black']):
# if the columns are direction then scatter/dot plot else line plot
if i in ['direction1', 'direction2']:
s.dot(x='Time', y=i, width=10, size=10, source=source, color=c)
else:
s.line(x='Time', y=i, width=2, source=source, color=c)
s.add_tools(range_tool)
s.toolbar.active_multi = range_tool
return p,s
# =============================================================================
# x_range to show last six weeks of data in plot and in rangetool plot
xrange = (my_df.index.max()-pd.Timedelta(6, "W"), my_df.index.max())
# Speed plot with rangetool plot
p1,s1 = plot(my_df[['speed1', 'speed2']], xrange=xrange)
# Direction plot with range tool plot and having xrange of speed plot (p1)
p2,s2 = plot(my_df[['direction1', 'direction2']], xrange=p1.x_range)
# Button to show plots
button1 = Button(label="Show plots", button_type="success")
# Call back function to show plots on button click
def bc1():
lt.children = [p1, s1, p2, s2]
# Button callback
button1.on_click(bc1)
lt = layout(children=[button1])
curdoc().add_root(lt)