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

使用Pandas datetime索引的Bokeh滑块

  •  1
  • Bisbot  · 技术社区  · 7 年前

    我试图通过Bokeh向我的绘图添加一个滑块,该绘图连接到熊猫数据帧。

    该图使用datetime指数来显示一年内的空气质量指数。

    我能够找到以下代码,但绘图是用随机数据生成的。这段代码的输出正是我想要做的,但使用的是时间序列数据。

    from bokeh.io import output_notebook, show, vform
    from bokeh.plotting import figure, Figure
    from bokeh.models import ColumnDataSource, Slider, CustomJS
    import numpy as np
    
    output_notebook()
    
    x = np.sort(np.random.uniform(0, 100, 2000))
    
    y = np.sin(x*10) + np.random.normal(scale=0.1, size=2000)
    fig = Figure(plot_height=400, x_range=(0, 2))
    
    source = ColumnDataSource(data={"x":x, "y":y})
    
    line = fig.line(x="x", y="y", source=source)
    callback = CustomJS(args=dict(x_range=fig.x_range), code="""
    var start = cb_obj.get("value");
    x_range.set("start", start);
    x_range.set("end", start+2);
    """)
    
    slider = Slider(start=0, end=100, step=2, callback=callback)
    show(vform(slider, fig))
    

    我还找到了制作这种滑块的源代码(如下所示)/ linked here )但我不确定如何实施它。正如你可能知道的那样,我对博克相当陌生。请帮忙!

    class DateRangeSlider(AbstractSlider):
    """ Slider-based date range selection widget. """
    
    @property
    def value_as_datetime(self):
        ''' Convenience property to retrieve the value tuple as a tuple of
        datetime objects.
    
        '''
        if self.value is None:
            return None
        v1, v2 = self.value
        if isinstance(v1, numbers.Number):
            d1 = datetime.utcfromtimestamp(v1 / 1000)
        else:
            d1 = v1
        if isinstance(v2, numbers.Number):
            d2 = datetime.utcfromtimestamp(v2 / 1000)
        else:
            d2 = v2
        return d1, d2
    
    value = Tuple(Date, Date, help="""
    Initial or selected range.
    """)
    
    start = Date(help="""
    The minimum allowable value.
    """)
    
    end = Date(help="""
    The maximum allowable value.
    """)
    
    step = Int(default=1, help="""
    The step between consecutive values.
    """)
    
    format = Override(default="%d %b %G")
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Samuel Miller    6 年前

    在您的示例中,回调函数是用Javascript编写的。我使用了示例Iain引用中的代码,但我必须为panda数据帧做一个小的变通方法。在下面的示例中,数据是熊猫数据帧的列表。

    def callback(attrname, old, new):
        month = slider.value
        source.data = ColumnDataSource(data[month]).data
    

    这将使用来自不同数据帧的数据替换图形的当前数据。如果像我一样,您的所有数据都在一个数据帧中,您也可以进行一些pandas过滤以返回您想要显示的数据。

    data_to_use = data[data['Month'] == month[slider.value]]
    

    同样,当我这样做时,我必须将data_to_use转换为ColumnDataSource,然后替换。我的图形的源的数据属性。

        2
  •  0
  •   Iain D    6 年前

    Bokeh gallery中的Gapminder示例使用了数年的时间来实现这一点,对于您的数据集,类似的方法应该可以工作数月。由于您只担心几个月,所以不需要使用datetime索引,只需将其作为列表。

    gapminder