结合bokeh widgets与pandas_bokeh开发仪表盘报ValueError错误
报错原因
你触发的ValueError核心原因是pandas_bokeh.plot_grid接收的二维布局列表中,每个子元素必须是单个Bokeh可渲染对象(属于LayoutDOM类的子类,比如绘图对象、控件、布局容器),你直接把widgets列表嵌套进了第一行的子列表中,相当于给布局塞了一个列表类型的元素,不符合Bokeh的布局规则。
修复方案
首先调整布局结构,把两个控件先包装为Bokeh的行/列布局容器,再传入plot_grid即可解决空白和报错问题。如果后续需要实现筛选交互的动态更新,再给控件绑定对应的回调函数修改绘图数据源即可。
可直接运行的完整修改后代码
import numpy as np import pandas as pd import pandas_bokeh from bokeh.io import show, curdoc from bokeh.layouts import column, layout, row from bokeh.models import DateRangeSlider, Dropdown #color palette colors=['#FDE724','#D01C8B','#4DAC26'] #define the categorical variable category_a = ['A','B','C'] category_b = ['X','Y','Z'] #set random seed to make the dataset reproducible np.random.seed(42) df_random2 = pd.DataFrame({ 'id': np.arange(0, 30), 'date': pd.date_range(start='1/1/2021', periods=30, freq='D'), 'month':np.random.randint(1, 12, 30), 'sensor_1': np.random.uniform(0, 1,30), 'sensor_2': np.random.uniform(10, 15, 30), 'sensor_3': np.random.randint(0, 20, 30), 'categorya': np.random.choice(category_a, 30, p=[0.2, 0.4, 0.4]), 'categoryb': np.random.choice(category_b, 30, p=[0.6, 0.2, 0.2]), }) #set index to id column df_random2=df_random2.set_index('id') mindate=df_random2['date'].min() maxdate=df_random2['date'].max() menucols = [("Category A", "categorya"),("Category B","categoryb")] date_range_slider = DateRangeSlider(value=(mindate, maxdate), start=mindate, end=maxdate) category_picker = Dropdown(label = "Column select", button_type="default", menu=menucols) # Plot1 - Line plot p_line= df_random2.groupby(['date']).mean().plot_bokeh(kind="line",y="sensor_2",color='#d01c8b',plot_data_points=True,show_figure=False) # Plot2- Barplot p_bar = df_random2.groupby(['date']).mean().plot_bokeh(kind="bar",y='sensor_2', colormap=colors,show_figure=False) # Plot3- stacked bar chart df_sensor=df_random2.drop(['date','month','categorya'],axis=1) p_stack=df_sensor.groupby(['categoryb']).mean().plot_bokeh(kind='barh', stacked=True,colormap=colors,show_figure=False) #Plot4- Scatterplot p_scatter = df_random2.plot_bokeh(kind="scatter", x="month", y="sensor_2",category="categoryb",colormap=colors,show_figure=False) #Plot5- Pie chart p_pie= df_random2.groupby(['categoryb']).mean().plot_bokeh.pie(y='sensor_1',colormap=colors,show_figure=False) #Plot6- Histogram p_hist=df_sensor.plot_bokeh(kind='hist', histogram_type="stacked",bins=6,colormap=colors, show_figure=False) # 修改点:将控件包装为行布局容器,符合LayoutDOM类型要求 widgets_row = row(date_range_slider, category_picker, sizing_mode="stretch_width") # 修改点:布局列表的第一行传入包装好的布局容器,而非嵌套列表 plots=pandas_bokeh.plot_grid([[widgets_row],[p_line, p_bar,p_stack],[p_scatter, p_pie,p_hist]], plot_width=400, show_figure=False) curdoc().add_root(plots) curdoc().title = "layout"
运行方式
保存代码为dashboard.py后,在终端执行以下命令即可启动仪表盘:bokeh serve --show dashboard.py
内容的提问来源于stack exchange,提问作者metaltoaster
相关产品推荐
相关产品推荐

