Bokeh图表RangeSlider的on_change事件无响应问题求助
Hey there! Let's troubleshoot why your RangeSlider's update function isn't working as expected. I went through your code and spotted several key issues that are likely causing the problem. Here's a breakdown of the fixes and explanations:
Key Issues & Fixes
Mismatched Function Names
You definedmake_data()but tried to callmake_dataset()inside yourupdatefunction—this is a straightforward typo that would throw an error and stop the callback dead in its tracks. Fix this by keeping the function name consistent everywhere.Redundant Data Loading
Loading your CSV file every time the slider updates is inefficient and can introduce unexpected behavior. Instead, load your data once at the start, outside the update function, and reuse it.Undefined
idsVariable
Your RangeSlider usesids[0],ids[100], etc., but there's no definition foridsin your code. This would cause an error when initializing the slider, meaning it might not render at all—so no callback triggers.Date Formatting
ThedateTime()function you used isn't a standard Bokeh/Pandas utility. You need to convert your date strings to proper datetime objects that Bokeh can recognize for the datetime axis.Callback Parameter Usage
While you can accessrange_select.valuedirectly, using thenewparameter passed to the update callback is the more reliable, idiomatic way to get the slider's new value.
Corrected Code Example
Here's your code with all the fixes applied:
import pandas as pd from bokeh.models import ColumnDataSource, RangeSlider, WidgetBox, Panel, Tabs, DatetimeTickFormatter from bokeh.plotting import figure, show from bokeh.layouts import column # Load data ONCE globally to avoid repeated CSV reads df = pd.read_csv("main_data.csv", index_col=None) df['ID'] = range(1, len(df) + 1) ids = df['ID'].tolist() # Define ids for the RangeSlider def make_data(df, start, end): # Filter data using a single mask for cleaner code mask = (df['ID'] >= start) & (df['ID'] <= end) df1 = df[mask] # Convert date strings to datetime objects Bokeh understands date = pd.to_datetime(df1['date']).tolist() capi = df1['capi'].tolist() return ColumnDataSource(data={'x': date, 'y': capi}) def update(attr, old, new): # Use the `new` parameter to get the slider's new range values start, end = new new_src = make_data(df, start, end) source.data.update(new_src.data) def make_plot(source): p1 = figure(x_axis_type="datetime", title="Stock Closing Prices") p1.grid.grid_line_alpha = 0.3 p1.xaxis.axis_label = 'Date' p1.yaxis.axis_label = 'Price' p1.line('x', 'y', source=source, color='#A6CEE3', legend='capi') # Optional: Format date axis for better readability p1.xaxis.formatter = DatetimeTickFormatter( days=["%Y-%m-%d"], months=["%Y-%m"], years=["%Y"] ) return p1 # Initialize slider and plot range_select = RangeSlider( title="Date range", value=(ids[0], ids[100]), start=ids[0], end=ids[-1], step=1 ) range_select.on_change('value', update) source = make_data(df, 1, 1000) p = make_plot(source) controls = WidgetBox(range_select) layout = column(controls, p) tab = Panel(child=layout, title='Stock Prices') tabs = Tabs(tabs=[tab]) show(tabs)
Additional Checks
- Make sure your
main_data.csvhas columns nameddateandcapiexactly as referenced. - If you're running this in a Jupyter notebook, replace
show(tabs)withoutput_notebook()followed byshow(tabs). - Check your browser's developer console (F12) for any JavaScript errors—Bokeh callbacks sometimes surface issues there that don't show up in Python.
内容的提问来源于stack exchange,提问作者usama aslam




