如何创建Bokeh DataTable DateTime格式化程序?

时间:2016-12-02 23:04:27

标签: python bokeh

Bokeh提供了bokeh.models.DateFormatter()来显示列中的日期(请参阅class DateFormatter(**kwargs))。有没有办法创建一个格式化程序,也显示时间HH:MM:SS,也可能是毫秒?在表格中编辑(双击日期)时,可以看到纪元毫秒。我可以使用另一组数据创建另一列,其中包含一天中的几秒钟,并使用格式为“00:00:00”的class NumberFormatter(**kwargs)和另一列具有毫秒数的列,但我无法编辑这些列并将其反映出来在图形字形上,除非我以某种方式将日期数据连续地与日期时间值相关联(有没有办法这样做?)。所以我希望有一种方法可以使用Formatter来显示散景DataTable中日期时间数据的时间。

from datetime import datetime
import bokeh, bokeh.plotting

data = dict(dates=[datetime(2016, 12, 2,15,30,0,123456),
                   datetime(2016, 12, 2,15,30,5,250500),
                   datetime(2016, 12, 2,15,30,10,756050)],
            altitude=[100.,150.,125.])

source = bokeh.models.ColumnDataSource(data)

columns = [bokeh.models.TableColumn(field="dates", title="Date",
           formatter=bokeh.models.DateFormatter()),
           bokeh.models.TableColumn(field="altitude", title="altitude")]

data_table = bokeh.models.DataTable(source=source, columns=columns,
                   row_headers=False,width=500, height=150, editable=True)

p = bokeh.plotting.figure(width=400,height=200,x_axis_type="datetime", 
                          background_fill_color="lightgray")
p.circle(x="dates",y="altitude",source=source, size=10)
bokeh.io.output_notebook()
bokeh.io.show(bokeh.io.gridplot([[p],[data_table]]))

enter image description here

更新

解决方法是创建另一个列,其时间为HH:MM:SS(不过毫秒。对于@Julian解决方案,效果最佳)。但是编辑该值不会反映在图表中。编辑日期毫秒会更新图表,但不会更新时间列。可能有一种方法可以将时间列与日期列连接到一些自定义CustomJS。我必须评论一下bokeh github中有一个工作进度功能:Updating dates in datatable可能会对此有所帮助。

from datetime import datetime
import bokeh, bokeh.plotting

t1 = datetime(2016, 12, 2,15,30,0,123456)
t2 = datetime(2016, 12, 2,15,30,5,250500)
t3 = datetime(2016, 12, 2,15,30,10,756050)

data = dict(dates = [t1,t2,t3],
            times = [t1.hour*3600 + t1.minute*60 + t1.second,
                    t2.hour*3600 + t2.minute*60 + t2.second,
                    t3.hour*3600 + t3.minute*60 + t3.second],
            altitude=[100.,150.,125.])

source = bokeh.models.ColumnDataSource(data)

tfmt = bokeh.models.NumberFormatter(format="00:00:00")
datefmt = bokeh.models.DateFormatter(format="ddMyy")
hfmt = bokeh.models.NumberFormatter(format="0.00")
columns = [bokeh.models.TableColumn(field="dates", title="Date",formatter=datefmt),
           bokeh.models.TableColumn(field="times", title="time", formatter=tfmt, editor=None),
           bokeh.models.TableColumn(field="altitude", title="altitude (km)", formatter=hfmt)]

data_table = bokeh.models.DataTable(source=source, columns=columns,
                   row_headers=False,width=500, height=150, editable=True)

p = bokeh.plotting.figure(width=400,height=200,x_axis_type="datetime", 
                          background_fill_color="lightgray")
p.circle(x="dates",y="altitude",source=source, size=10)
bokeh.io.output_notebook()
bokeh.io.show(bokeh.io.gridplot([[p],[data_table]]))

enter image description here

更新04/13/2018

Bokeh版本0.12.16dev允许DataTable拥有支持时间信息的DateFormatter

bokeh.models.DateFormatter(format="%m/%d/%Y %H:%M:%S")

对于所有可能性,请参阅class DateFormatter(**kwargs)

enter image description here

1 个答案:

答案 0 :(得分:1)

一个部分解决方案是分离表和绘图的数据源。然后,您可以以日期时间格式保留绘图的x数据,并将表的日期数据转换为字符串。原因是,表中的编辑没有反映在情节中。也许使用回调函数,您可以链接两个数据源。

from datetime import datetime
import bokeh, bokeh.plotting

datetime_dates=[datetime(2016, 12, 2,15,30,0,123456),
                   datetime(2016, 12, 2,15,30,5,250500),
                   datetime(2016, 12, 2,15,30,10,756050)]
string_dates = []
for i in datetime_dates: string_dates.append(i.strftime("%Y-%m-%d %H:%M:%S.%f"))

data_plt = dict(dates=datetime_dates,
                     altitude=[100.,150.,125.])
data_tbl = dict(dates=string_dates,
                     altitude=[100.,150.,125.])

source_plot  = bokeh.models.ColumnDataSource(data_plt)
source_table = bokeh.models.ColumnDataSource(data_tbl)

columns = [bokeh.models.TableColumn(field="dates", title="Date"),
           bokeh.models.TableColumn(field="altitude", title="altitude")]

data_table = bokeh.models.DataTable(source=source_table, columns=columns,
                   row_headers=False,width=500, height=150, editable=True)

p = bokeh.plotting.figure(width=400,height=200,x_axis_type="datetime", 
                          background_fill_color="lightgray")
p.circle(x="dates",y="altitude",source=source_plot, size=10)
bokeh.io.output_notebook()
bokeh.io.show(bokeh.io.gridplot([[p],[data_table]]))

enter image description here