我想运行一个带有交互式Widget的Bokeh应用程序,但无法让它完全正常工作。
我的代码demo.py
:
# imports
import pandas as pd
from bokeh.io import curdoc
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, Dropdown
from bokeh.plotting import figure
from bokeh.sampledata.iris import flowers
# Data
df = pd.DataFrame({'x': flowers['sepal_length'], 'y': flowers['sepal_width'], 'species': flowers['species']})
# Source
SPECIES = 'versicolor'
source = ColumnDataSource(df.loc[df.species == SPECIES])
# Create plots and widgets
plot = figure()
plot.circle(x= 'x', y='y', source=source)
menu = [("setosa", "setosa"), ("versicolor", "versicolor"), None, ("virginica", "virginica")]
dropdown = Dropdown(label="Dropdown species", button_type="warning", menu=menu)
# Add callback to widgets
def callback(attr, old, new):
SPECIES = dropdown.value
source.data=ColumnDataSource(df.loc[df.species == SPECIES])
dropdown.on_change('value', callback)
# Arrange plots and widgets in layouts
layout = column(dropdown, plot)
curdoc().add_root(layout)
当我从命令行界面使用bokeh serve --show demo.py
运行此应用程序时,它返回带有绘图的HTML页面。下拉列表似乎有效,但从下拉列表中选择值时,图表不会更改。
有任何建议如何解决这个问题?
您没有为source.data
指定正确的值。该值必须是一个常规的Python dict,它将列名映射到列表/数据数组。在文档和示例中演示了多种方法,但一种好方法是使用CDS的from_df
类方法生成正确类型的dict:
source.data = ColumnDataSource.from_df(df.loc[df.species == SPECIES])
该行使您的代码按预期工作。
作为FYI,您的代码在服务器控制台输出中生成错误(应该是预期的):
错误处理消息消息'PATCH-DOC'(修订版1):ValueError(“期望ColumnData的一个元素(String,Seq(Any)),得到ColumnDataSource(id = '44e09b5e-133b-4c1b-987b-cbf80b803401',... )”)
作为一个温和的建议,在SO问题中包含这些错误总是一个好主意。