Python,Bokeh:如何更改日期时间轴的范围 [英] Python, Bokeh: How to change range of datetime axis

查看:139
本文介绍了Python,Bokeh:如何更改日期时间轴的范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用按钮设置日期时间轴的范围.但是,命令

I would like to set the range of a datetime axis using a button. However, the command

f.x_range = Range1d(start=start_date, end=end_date)

不起作用.当单击按钮时,没有任何反应.我既没有运行Bokeh服务器的终端窗口也没有任何错误,也没有在我的Chrome网络浏览器的控制台输出中得到任何错误.

doesn't work. When clicking the button nothing happens. I don't get any errors, neither in the terminal windows running the Bokeh server, nor in the console output of my Chrome web browser.

您可以在下面找到完整的代码.感谢您的任何建议.

You find the entire code below. I'm grateful for any advice.

谢谢

朱利安

# Import libraries
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, DatetimeTickFormatter, Select, Range1d
from bokeh.models.widgets import Button
from bokeh.layouts import layout
from bokeh.plotting import figure
from datetime import datetime, timedelta
from math import radians


# Create figure
f=figure(x_axis_type='datetime')

# Create sample datetime data
date_time = [datetime(2017,1,1) + timedelta(days=x) for x in range(0,365)]

# Create ColumnDataSource
source = ColumnDataSource(dict(datetime=date_time,parameter=range(0,365)))

# Create Line
f.line(x='datetime',y='parameter',color='olive',line_color='black',source=source)

# Update xaxis function
def update_xaxis():
    start_date = datetime(year=int(select_start_year.value), month=int(select_start_month.value), day=int(select_start_day.value))
    end_date   = datetime(year=int(select_end_year.value), month=int(select_end_month.value), day=int(select_end_day.value))    
    f.x_range = Range1d(start=start_date, end=end_date)

# Set date format for x axis
f.xaxis.formatter=DatetimeTickFormatter(formats=dict(
    seconds=["%Y-%m-%d %H:%M:%S"],
    minsec=["%Y-%m-%d %H:%M:%S"],
    minutes=["%Y-%m-%d %H:%M:%S"],
    hourmin=["%Y-%m-%d %H:%M:%S"],
    hours=["%Y-%m-%d %H:%M:%S"],
    days=["%Y-%m-%d %H:%M:%S"],
    months=["%Y-%m-%d %H:%M:%S"],
    years=["%Y-%m-%d %H:%M:%S"],
    ))
f.xaxis.major_label_orientation=radians(90)

# Create Select and Button widgets
options=[("2015","2015"),("2016","2016"),("2017","2017")]
select_start_year=Select(title="Start Year",value="2017",options=options)
options=[("01","01"),("02","02"),("03","03"),("04","04"),("05","05"),("06","06"),("07","07"),("08","08"),("09","09"),("10","10"),("11","11"),("12","12")]
select_start_month=Select(title="Start Month",value="01",options=options)
options=[("01","01"),("02","02"),("03","03"),("04","04"),("05","05"),("06","06"),("07","07"),("08","08"),("09","09"),("10","10"),("11","11"),("12","12"),("13","13"),("14","14"),("15","15"),("16","16"),("17","17"),("18","18"),("19","19"),("20","20"),("21","21"),("22","22"),("23","23"),("24","25"),("25","26"),("27","27"),("28","28"),("29","29"),("30","30"),("31","31")]
select_start_day=Select(title="Start Day",value="01",options=options)
options=[("2015","2015"),("2016","2016"),("2017","2017")]
select_end_year=Select(title="End Year",value="2017",options=options)
options=[("01","01"),("02","02"),("03","03"),("04","04"),("05","05"),("06","06"),("07","07"),("08","08"),("09","09"),("10","10"),("11","11"),("12","12")]
select_end_month=Select(title="End Month",value="06",options=options)
options=[("01","01"),("02","02"),("03","03"),("04","04"),("05","05"),("06","06"),("07","07"),("08","08"),("09","09"),("10","10"),("11","11"),("12","12"),("13","13"),("14","14"),("15","15"),("16","16"),("17","17"),("18","18"),("19","19"),("20","20"),("21","21"),("22","22"),("23","23"),("24","25"),("25","26"),("27","27"),("28","28"),("29","29"),("30","30"),("31","31")]
select_end_day=Select(title="End Day",value="01",options=options)
button = Button(label='Set Date')

# Update x axis range on click
button.on_click(update_xaxis)

# Add elements to curdoc 
lay_out=layout([[f],[select_start_year],[select_start_month],[select_start_day],[select_end_year],[select_end_month],[select_end_day],[button]])
curdoc().add_root(lay_out)

推荐答案

我想出了解决方案.首先,我使用了Datepicker小部件,它比三个Select小部件优雅得多.然后,您必须将DateTime值从DatePicker转换为float/integer值,该值表示w.r.t所经过的秒数.一个参考日期,即1970年1月1日.Unix以秒为单位计算该值,Java Script需要以毫秒为单位的值,因此需要乘以1000.这是代码:

I figured out the solution. First off all, I used the Datepicker widget, which is much more elegant than three Select widgets. Then, you have to convert the datetime value from the DatePicker into a float/integer value, which represents the seconds elapsed w.r.t. a reference date, i.e. Jan 1, 1970. Unix calculates this in seconds, Java Script needs this value in milliseconds, hence the multiplication by 1000. Here is the code:

# Import libraries
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, DatetimeTickFormatter, DatePicker
from bokeh.models.widgets import Button
from bokeh.layouts import layout, column, row
from bokeh.plotting import figure
from datetime import datetime, timedelta
from math import radians


# Create figure
f=figure(x_axis_type='datetime')

# Create sample datetime data
date_time = [datetime(2017,1,1) + timedelta(days=x) for x in range(0,365)]

# Create ColumnDataSource
source = ColumnDataSource(dict(datetime=date_time,parameter=range(0,365)))

# Create Line
f.line(x='datetime',y='parameter',color='olive',line_color='black',source=source)

# Update xaxis function
def update_xaxis():
    # Calculate time delta from reference time in seconds
    timestamp_start = (datetime.combine(datepicker_start.value, datetime.min.time())
                        - datetime(1970, 1, 1)) / timedelta(seconds=1)
    timestamp_end = (datetime.combine(datepicker_end.value, datetime.min.time())
                        - datetime(1970, 1, 1)) / timedelta(seconds=1)
    f.x_range.start = int(timestamp_start)*1e3  # Multiply by 1e3 as JS timestamp is in milliseconds
    f.x_range.end   = int(timestamp_end)*1e3  # Multiply by 1e3 as JS timestamp is in milliseconds

# Set date format for x axis
f.xaxis.formatter=DatetimeTickFormatter(formats=dict(
    seconds=["%Y-%m-%d %H:%M:%S"],
    minsec=["%Y-%m-%d %H:%M:%S"],
    minutes=["%Y-%m-%d %H:%M:%S"],
    hourmin=["%Y-%m-%d %H:%M:%S"],
    hours=["%Y-%m-%d %H:%M:%S"],
    days=["%Y-%m-%d %H:%M:%S"],
    months=["%Y-%m-%d %H:%M:%S"],
    years=["%Y-%m-%d %H:%M:%S"],
    ))
f.xaxis.major_label_orientation=radians(90)

# Create Datepicker and Button widgets
datepicker_start = DatePicker(title='Start Date')
datepicker_end = DatePicker(title='End Date')
button = Button(label='Set Date')

# Update x axis range on click
button.on_click(update_xaxis)

# Add elements to curdoc 
lay_out=layout([[row(f,
                     column(button,
                            row(datepicker_start,datepicker_end)))]])
curdoc().add_root(lay_out)

这篇关于Python,Bokeh:如何更改日期时间轴的范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆