如何在 Bokeh BoxAnnotation 上使用日期时间限制的 X 轴?

5

我希望在具有日期时间x轴的图形中添加BoxAnnotation。如何将BoxAnnotation的左右限制设置为日期时间或日期对象。这就是我的目标,但它不起作用。

from bokeh.sampledata.glucose import data
from bokeh.models import BoxAnnotation
from datetime import *

# output_file("box_annotation.html", title="box_annotation.py example")

TOOLS = "pan,wheel_zoom,box_zoom,reset,save"

#reduce data size
data = data.ix['2010-10-06':'2010-10-13']

p = figure(x_axis_type="datetime", tools=TOOLS)

p.line(data.index.to_series(), data['glucose'],
       line_color="gray", line_width=1, legend="glucose")

left_box = BoxAnnotation(plot=p, right=date(2010,10,7), fill_alpha=0.1, fill_color='blue')
mid_box = BoxAnnotation(plot=p, left=date(2010,10,8), right=date(2010,10,9), fill_alpha=0.1, fill_color='yellow')
right_box = BoxAnnotation(plot=p, left=date(2010,10,10), fill_alpha=0.1, fill_color='blue')

p.renderers.extend([left_box, mid_box, right_box])

p.title = "Glucose Range"
p.xgrid[0].grid_line_color=None
p.ygrid[0].grid_line_alpha=0.5
p.xaxis.axis_label = 'Time'
p.yaxis.axis_label = 'Value'

show(p)
2个回答

6

当前的BoxAnnotation实现只接受NumberSpec类型(浮点数和整数)作为输入。当前的解决方法是将你的datetime对象转换为时间戳(并乘以1e3,因为Bokeh内部使用微秒精度,而不是毫秒)

所以它看起来像这样:(使用python3 datetime.timestamp 方法)

from datetime import datetime as dt

...
left_box = BoxAnnotation(plot=p, right=dt(2010,10,7).timestamp()*1000, fill_alpha=0.1,   fill_color='blue')
mid_box = BoxAnnotation(plot=p, left=date(2010,10,8).timestamp()*1000,   right=date(2010,10,9).timestamp()*1000, fill_alpha=0.1, fill_color='yellow')
right_box = BoxAnnotation(plot=p, left=date(2010,10,10).timestamp()*1000, fill_alpha=0.1, fill_color='blue')

p.renderers.extend([left_box, mid_box, right_box])
...

似乎添加支持日期时间对象作为参数是一个有价值的功能。我已经打开了一个Github问题,您可以在其中发表评论/关注:

https://github.com/bokeh/bokeh/issues/2944


谢谢Luke,您给了我正确的指引。但是由于我使用的是Python 2.7,所以我不得不使用一个小技巧来获取时间戳(在这里找到它:https://dev59.com/hWoy5IYBdhLWcg3wF6ML)`from __future__ import division from datetime import datetime, timedelta def totimestamp(dt, epoch=datetime(1970,1,1)): td = dt - epoch # return td.total_seconds() return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6` - DrJMcAuliffe

3

Bokeh 现在支持时间戳的框注释!

import pandas as pd
...
left_box = BoxAnnotation(plot = p, right = pd.to_datetime('2010-10-07'), fill_alpha=0.1,   fill_color='blue')
...

这个可以在bokeh 0.12.9和Python版本>2.7下工作。


目前看起来似乎有些问题(这里是使用BokehJS版本3.0.2)?例如,我得到了以下错误信息:ValueError: failed to validate BoxAnnotation(id='p5934', ...).left: expected an element of either Null, Float or Factor(Either(String, Tuple(String, String), Tuple(String, String, String))), got (Timestamp('1944-06-06 00:00:00'),) - Nikos Alexandris
支持在3.1中重新添加,参见:https://discourse.bokeh.org/t/does-boxannotation-not-support-timestamps/9799/2?u=nikosalexandris - Nikos Alexandris

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