代码之家  ›  专栏  ›  技术社区  ›  Piotrek

Bokeh日期范围滑块

  •  1
  • Piotrek  · 技术社区  · 6 年前

    我最近开始在博凯工作,完成了一些关于数据营的快速课程,我被困在创建日期范围滑块上。在我看来,滑块本身看起来没问题,更改滑块上的值是可行的,但我无法使其更改绘图。

    不知道我遗漏了什么,因为我找不到关于使用这个特定工具的适当教程/信息,所以对此的任何帮助都将非常感谢。

    代码如下:

    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,在打印新的数据后,我得到一个dict:

    dict image

    我还在代码的第二部分添加了一个Select小部件,data_selected的格式与DateRangeSlider中的格式相同(参见:图片)奇怪的是select工作得很好,而datarangeslider每次单击它都会使绘图消失。

    1 回复  |  直到 6 年前
        1
  •  1
  •   bigreddot    6 年前

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

    data.loc[1451606400000].periodFrom
    

    这是有明显原因的。

    基于名字 yr ,似乎要用年值为数据帧编制索引?然后,您需要将时间戳值转换为实际日期时间,并在一年中进行额外的转换:

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

    作为旁白,没有理由使用或调用 show 在bokeh服务器应用程序中。