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

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

使用打印语句,我可以看到,当用户在“选择”菜单中更改值时,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))


谢谢您的帮助!

最佳答案

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

source.data = { ... } # plain python dict


如果您需要调整DataFrame,则CDS上有一个.from_df方法,该方法将创建可用于分配的适当的纯python dict结构。

关于python - 散景Python:“选择”下拉列表将更新ColumnDataSource,但不会更新图形,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58238699/

10-13 06:26
查看更多