使用 Pandas 日期时间索引的散景滑块

Bokeh Slider using Pandas datetime index

我正在尝试通过 Bokeh 添加一个滑块到我连接到 pandas 数据框的图中。

该图使用日期时间指数来显示一年内的空气质量指数。

我想为 2016 年 1 月至 12 月的每个月添加一个滑块。 我无法找到一个清晰的示例,其中包含将滑块连接到连接到 pandas 数据框的绘图的代码。请有人帮忙!

我找到了以下代码,但该图是使用随机数据生成的。此代码的输出正是我想要做的,但带有时间序列数据。

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),但我不确定如何实现它。您可能会说,我对 Bokeh 还很陌生。请帮忙!

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")

Bokeh 画廊中的 Gapminder 示例使用年执行此操作,类似的方法应该适用于您的数据集的月。由于您只担心月份,因此不需要使用日期时间索引,只需将其作为列表获取即可。

gapminder

我刚刚在我的项目中遇到过类似情况。我没有使用 pandas 日期时间功能,因为我的日期是混合格式,但一旦我清理了数据,它就很容易更新。重要的部分是让回调函数调整 ColumnDataSource 的 .data 属性。

在你的例子中,回调函数写在Javascript中。我使用了 Iain 参考示例中的代码,但我不得不为熊猫数据帧做一个小的解决方法。在下面的示例中,数据是熊猫数据帧的列表。

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

这会将图形的当前数据替换为来自不同 pandas 数据帧的数据。如果像我一样,您的所有数据都在一个数据框中,您还可以对要显示的数据进行 pandas 过滤 return。

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

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