python - Bokeh Python : Select dropdown is updating ColumnDataSource but not updating the graph

标签 python select dropdown bokeh linegraph

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

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

使用打印语句,我可以看到当用户更改“选择”菜单中的值时,ColumnDataSource 正在更新。但是,它没有更新图表。我认为我的“make_plot”函数做错了。另外,我使用 Bokeh 服务器运行它(bokehserve --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))

感谢您的帮助!

最佳答案

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

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

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

关于python - Bokeh Python : Select dropdown is updating ColumnDataSource but not updating the graph,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58238699/

相关文章:

python - 如果以非贪婪方式使用,python 正则表达式中量词 {m,n} 中的第二个限制有什么用?

mysql - 在 mysql 中使用 JOIN 和子查询

mysql - 如何组合查询?

Android 边距弹出下拉微调器

javascript - 使用其他下拉列表选项禁用下拉列表选项

python - 在 pandas Dataframe 中查找倒数行

python - pymongo 默认数据库连接

Android 5.0 在 webview 中选择标签为空

css - 向右浮动导航问题

python - 没有素数列表理解