【问题标题】:Bokeh Python: Select dropdown is updating ColumnDataSource but not updating the graphBokeh Python:选择下拉列表正在更新 ColumnDataSource 但不更新图表
【发布时间】:2020-02-02 22:16:13
【问题描述】:

我是 Bokeh 的新手,我正在尝试创建一个交互式天气数据图。有两种选择菜单,一种用于传感器 ID(132、133...),另一种用于变量(温度、露点...)。当用户更改任一值时,图表应该使用所选数据进行更新。

我使用的数据位于 Panda Dataframe 中,其中有一列“dt”包含一分钟间隔的日期时间对象,数据位于遵循命名约定“Temp132”、“Temp 133”的列中'、'Dew132'、'Dew133' 等。理想情况下,用户从“选择”菜单中选择的值将组合成一个字符串,该字符串可用于从 df 中提取数据系列(“Temp”+“132”将用于调用 df['Temp132'])。

使用 print 语句,我可以看到当用户更改 Select 菜单中的值时,ColumnDataSource 正在更新。但是,它不会更新图表。我认为我在“make_plot”函数上做错了。另外,我正在使用 Bokeh 服务器 (bokeh serve --show bokeh_test.py) 运行它。

以下是我的代码摘录:

from math import pi
import pandas as pd
from bokeh.io import curdoc
from bokeh.plotting import figure
from bokeh.layouts import row, column
from bokeh.models.widgets import Select
from bokeh.models import DatetimeTickFormatter, ColumnDataSource
import datetime

def get_dataset(src, height, var, dt):
    var_str = var_z[var]['var']
    z_str   = var_z[height]['z']
    df_sub =src[[var_str+z_str]].copy()
    df_sub['dt'] = dt
    df_sub = pd.DataFrame(data=df_sub.values, columns=[var_str+height, 'dt'])
    return ColumnDataSource(data=df_sub)

def make_plot(in_source, y_label_var):
    var = variable_select.value
    z   = height_select.value
    var_str = var_z[var]['var']
    plot = figure(plot_width=800, plot_height=800, title="Data ", x_axis_label = 'Date and Time', y_axis_label = y_label_var)
    plot.line('dt', var_str+z, line_width=2, source=in_source)
    plot.xaxis.formatter=DatetimeTickFormatter( days=["%m/%d/%Y %H:%M"],
        months=["%m/%d/%Y %H:%M"],
        hours=["%m/%d/%Y %H:%M"],
        minutes=["%m/%d/%Y %H:%M"])
    plot.xaxis.major_label_orientation = pi/4

    return plot

def update_plot(attr, old, new):
    var = variable_select.value
    z   = height_select.value
    plot.title.text = var_z[var]['title'] + " " + var_z[z]['title']
    src = get_dataset(df, var_z[z]['z'], var_z[var]['title'], dt)

    print(source.data)
    source.data = src.data
    print(source.data)

#-----------------------------------------------------------------------------

init_height = '132'
init_var    = 'Temperature'

var_z = {'Temperature'        : {'var': 'Temp',         'title': 'Temperature',},
         'Dew Point'          : {'var': 'Dew',          'title': 'Dew Point',},
         'Mean Wind Direction': {'var': 'MeanWindDir',  'title': 'Mean Wind Direction',},
         'Mean Wind Speed'    : {'var': 'MeanWindSpeed','title': 'Mean Wind Speed',},
         'Peak Wind Speed'    : {'var': 'PeakWindSpeed','title': 'Peak Wind Speed',},
         'Peak Wind Direction': {'var': 'PeakWindDir',  'title': 'Peak Wind Direction',},
         'Relative Humidity'  : {'var': 'RH',           'title': 'Relative Humidity',},
         '132' : {'z': '132', 'title': '132',},
         '133' : {'z': '133', 'title': '133',},
         '134' : {'z': '134', 'title': '134',},
         '257' : {'z': '257', 'title': '257',},
         '258' : {'z': '258', 'title': '258',},
         '259' : {'z': '259', 'title': '259',},
         '382' : {'z': '382', 'title': '382',},
         '383' : {'z': '383', 'title': '383',},
         '384' : {'z': '384', 'title': '384',},
         '457' : {'z': '457', 'title': '457',},
         '458' : {'z': '458', 'title': '458',},
         '459' : {'z': '459', 'title': '459',}}

height_select  = Select(value=init_height, title='Height', options = ["132","133","134","257","258","259","382","383","384","457","458","459"])
variable_select= Select(value=init_var, title = 'Variable', options = ["Temperature", "Dew Point", "Mean Wind Direction", "Mean Wind Speed", "Peak Wind Speed", "Peak Wind Direction", "Relative Humidity"] )

df = pd.read_csv('My/File/Path')
dt = df['dt'].to_list()
source = get_dataset(df, init_height, init_var, dt)
plot = make_plot(source, var_z[init_var]['var'])

height_select.on_change('value', update_plot)
variable_select.on_change('value', update_plot)

controls = column(height_select, variable_select)

curdoc().add_root(row(plot,controls))

感谢您的帮助!

【问题讨论】:

    标签: python select dropdown bokeh linegraph


    【解决方案1】:

    您不应将.data 从一个 CDS 分配给另一个 CDS。在即将推出的 Bokeh 2.0 中尝试这样做会引发明确的错误消息。尽管它的行为类似于dict,但事实并非如此。为了支持 Python 和 JS 之间的所有自动同步,CDS .data 实际上是一种非常专业的数据结构,它与许多其他事物有链接,并且不支持将它们从一个 CDS 重新定位到另一个。您应该只从 plain python dict

    分配给 .data
    source.data = { ... } # plain python dict
    

    如果您需要调整 DataFrame,CDS 上有一个 .from_df 方法,该方法将创建适当的普通 python dict 结构,您可以使用它来分配。

    【讨论】:

    • 谢谢!当我改用 dict 时,它修复了它。很高兴知道这将在 2.0 版中引发错误消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 2021-06-04
    • 1970-01-01
    • 1970-01-01
    • 2019-11-14
    • 2019-07-08
    • 1970-01-01
    相关资源
    最近更新 更多