简体   繁体   English

Python,Bokeh:如何更改日期时间轴的范围

[英]Python, Bokeh: How to change range of datetime axis

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)

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. 我在运行Bokeh服务器的终端窗口以及Chrome网络浏览器的控制台输出中都没有出现任何错误。

You find the entire code below. 您可以在下面找到完整的代码。 I'm grateful for any advice. 我很感激任何建议。

Thanks, 谢谢,

Julian 朱利安

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

I figured out the solution. 我找到了解决方案。 First off all, I used the Datepicker widget, which is much more elegant than three Select widgets. 首先,我使用了Datepicker小部件,它比三个Select小部件更优雅。 Then, you have to convert the datetime value from the DatePicker into a float/integer value, which represents the seconds elapsed wrt a reference date, ie Jan 1, 1970. Unix calculates this in seconds, Java Script needs this value in milliseconds, hence the multiplication by 1000. Here is the code: 然后,您必须将datePicker中的datetime值转换为浮点/整数值,该值表示参考日期(即1970年1月1日)经过的秒数.Unix以秒为单位计算,Java Script需要此值,以毫秒为单位,因此乘以1000.这是代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM