【问题标题】:Bokeh DateRangeSlider散景日期范围滑块
【发布时间】:2018-12-27 10:20:25
【问题描述】:

我最近开始在 Bokeh 工作,完成了一些关于 datacamp 的快速课程,但我一直坚持创建 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,)

最好, 皮奥特雷克

编辑:

我在滑块上做了一些工作,现在没有出现任何错误,但是当我向任何方向移动滑块时,情节就会消失。单独过滤效果很好(即当我将 '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 后我得到一个字典:

我还在代码的第二部分添加了一个 Select 小部件,data_selected 的格式与 DateRangeSlider 中的格式相同(参见:图片)。对我来说奇怪的是 Select 可以完美运行,而 DataRangeSlider 每次单击时都会使情节消失。

【问题讨论】:

    标签: python slider bokeh


    【解决方案1】:

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

    data.loc[1451606400000].periodFrom
    

    由于显而易见的原因,这不起作用。

    根据名称yr,您似乎想用年份值索引您的数据框?然后您需要将时间戳值转换为真实的日期时间和额外的年份:

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

    顺便说一句,没有理由在 Bokeh 服务器应用程序中使用或调用 show

    【讨论】:

    • 太好了,非常感谢!我实际上是用一个完整的日期编制索引,但我想从现在开始我可以自己处理这个问题。干杯!
    • 你能看看更新后的帖子吗?您的解决方案有很大帮助,但我仍在努力将滑块值与情节联系起来。
    • 如果没有完整的示例可以运行,我真的不能说别的。但是我要做的是在回调中添加一些打印语句来检查变量值,看看它们是否符合我的预期(或者如果它们不是),你也可以这样做。
    • 当然,我添加了一些代码和屏幕截图,如果您愿意,我可以将数据发布到某个地方,以便您运行示例。 update_plot 中间的 print 语句在每个系列之后返回 4 次 pandas series 和 'Name: periodFrom, Length: 934, dtype: datetime64[ns]'。
    【解决方案2】:

    DateRangeSlider 具有 value_as_date 属性,它使元组的元素采用日期格式,您只需要做:

    yr = slider.value_as_date
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-30
      • 1970-01-01
      • 1970-01-01
      • 2018-11-21
      相关资源
      最近更新 更多