Bokeh日期范围滑块

3

我最近开始在Bokeh上工作,完成了一些数据营的快速课程,但我卡在了创建一个DateRangeSlider上。滑块本身看起来还不错,可以更改滑块上的值,但我无法使其更改图表。

我不确定我错过了什么,因为我找不到有关使用此特定工具的适当教程/信息,因此对此的任何帮助将不胜感激。

这是代码:

data['periodFrom'] = pd.to_datetime(data['periodFrom']).dt.date
data = data.rename(columns={'MWh/h' : 'MWH'})
source = ColumnDataSource(data={
    'x'       : data.periodFrom,
    'y'       : data.MWH,
    'point'      : data.pointLabel,
    'direction'      : data.directionKey
})
xmin, xmax = min(data.periodFrom), max(data.periodFrom)
ymin, ymax = min(data['MWH']), max(data['MWH'])

plot = figure(title='Gas renomination', plot_height=400, plot_width=700,
              x_range=(xmin, xmax), y_range=(ymin, ymax))

plot.line(x='x', y='y', source=source)

plot.xaxis.axis_label ='Date'
plot.yaxis.axis_label = 'MWh/h'

def update_plot(attr, old, new):
    yr = slider.value
    new_data = {
    'x'       : data.loc[yr[0]:yr[1]].periodFrom,
    'y'       : data.loc[yr[0]:yr[1]].MWH,
    'point'      : data.loc[yr[0]:yr[1]].pointLabel,
    'direction'      : data.loc[yr[0]:yr[1]].directionKey
    }
    source.data = new_data

slider = DateRangeSlider(start=date(2016,1,1), end=date.today(), step=1, 
         value=(date(2016,1,1),date(2016,2,1)), title='Date', width=1000)

slider.on_change('value', update_plot)

curdoc().add_root(plot)
curdoc().add_root(slider)
show(plot)

每次我改变滑块的值时,命令提示符中都会显示以下错误信息:

2018-07-19 11:56:55,387 error handling message Message 'PATCH-DOC' (revision 1): KeyError(1451606400000,)

您好,Piotrek:

编辑:

我对滑块进行了一些修复,现在不会再出现任何错误,但是当我向任何方向移动滑块时,绘图会消失。单独过滤工作得很好(即当我将“data[data.index> yr[0]].periodFrom”放入控制台时),但似乎更新绘图的新值时出现了问题。

data['periodFrom'] = pd.to_datetime(data['periodFrom'])
data.index = data['periodFrom'].astype(np.int64) // 10 ** 9
data.index = data.index.astype(np.float)

data = data.rename(columns={'MWh/h' : 'MWH'})
source = ColumnDataSource(data={
    'x'       : data.periodFrom,
    'y'       : data.MWH,
    'point'      : data.pointLabel,
    'direction'      : data.directionKey
})

xmin, xmax = min(data.periodFrom), max(data.periodFrom)
ymin, ymax = min(data['MWH']), max(data['MWH'])

# Create the figure: plot
plot = figure(title='Gas renomination', plot_height=400, plot_width=700,
              x_range=(xmin, xmax), y_range=(ymin, ymax))

plot.line(x='x', y='y', source=source)

plot.xaxis.axis_label ='Date'
plot.yaxis.axis_label = 'MWh/h'

#slider
def update_plot(attr, old, new):
    yr = slider.value
    yr=list(yr)
    [float(i) for i in yr]
    new_data = {
        'x' : data[(data.index > yr[0]) & (data.index < yr[1])].periodFrom,
        'y' : data[(data.index > yr[0]) & (data.index < yr[1])].MWH,
        'point' : data[(data.index > yr[0]) & (data.index < yr[1])].pointLabel,
        'direction' : data[(data.index > yr[0]) & (data.index < yr[1])].directionKey}

print(new_data)
source.data = new_data

slider = DateRangeSlider(start=datetime(2016,1,2).timestamp(), 
end=datetime.today().timestamp(), step=1, value= 
(datetime(2016,2,2).timestamp(),datetime(2016,3,3).timestamp()), title='Date', 
width=1000)
slider.on_change('value', update_plot)

#dropdown

def update_dropdown(attr, old, new):
    point_select = select.value
    data_selected ={
        'x' : data[data['pointLabel'] == point_select].periodFrom,
        'y' : data[data['pointLabel'] == point_select].MWH,
        'point' : data[data['pointLabel'] == point_select].pointLabel,
        'direction' : data[data['pointLabel'] == point_select].directionKey}

    source.data=data_selected

select = Select(title="Point", options=pointlabels, value='Kondratki')
select.on_change('value', update_dropdown)

curdoc().add_root(select)
curdoc().add_root(plot)
curdoc().add_root(slider)

我的原始数据框为40639 x 6,在打印new_data后,我得到了一个字典:

dict image

我还在代码的第二部分添加了一个“选择”小部件,data_selected的格式与DateRangeSlider相同(请参见:图像)。对我来说很奇怪的是,选择器运行良好,但每次我点击DataRangeSlider时绘图就会消失。

2个回答

3

尽管为了方便,滑块可以使用日期时间对象进行初始化,但滑块值实际上是表示为浮点时间戳的,具体来说,是自纪元以来的毫秒数。这意味着您直接使用该值对数据框进行索引的尝试大致相当于:

data.loc[1451606400000].periodFrom

这种方法无法成功是因为显然存在问题。

根据名称yr,看起来您想使用年份的值对数据框进行索引?那么,您需要将时间戳值转换为真正的日期时间并提取年份:

In [6]: from datetime import datetime

In [7]: datetime.fromtimestamp(1451606400000/1000).year
Out[7]: 2015

作为旁注,Bokeh 服务器应用程序中不需要使用或调用 show

太好了,非常感谢!实际上我正在使用完整日期进行索引,但我想从现在开始自己处理这个问题。干杯! - Piotrek
请您看一下更新的帖子好吗?您的解决方案已经帮了我很多忙,但我仍然在努力将滑块值与图形连接起来。 - Piotrek
1
如果没有一个完整的运行示例,我真的无法再说什么了。但是我会在回调函数中添加一些打印语句来检查变量值是否符合我的期望(或者如果不符合)。你也可以这样做。 - bigreddot
当然,我添加了一些代码和截图,如果您想要的话,我可以在某个地方发布数据,以便您可以运行示例。在update_plot中的print语句返回4次pandas系列和每个系列后面的“Name: periodFrom, Length: 934, dtype: datetime64[ns]”。 - Piotrek

0

DateRangeSlider有value_as_date属性,可以将元组的元素转换为日期格式,您只需要这样做:

yr = slider.value_as_date

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接