You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

  1. Mismatched Function Names
    You defined make_data() but tried to call make_dataset() inside your update function—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.

  2. 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.

  3. Undefined ids Variable
    Your RangeSlider uses ids[0], ids[100], etc., but there's no definition for ids in your code. This would cause an error when initializing the slider, meaning it might not render at all—so no callback triggers.

  4. Date Formatting
    The dateTime() 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.

  5. Callback Parameter Usage
    While you can access range_select.value directly, using the new parameter 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.csv has columns named date and capi exactly as referenced.
  • If you're running this in a Jupyter notebook, replace show(tabs) with output_notebook() followed by show(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

火山引擎 最新活动