Link Bokeh DatetimePicker with plot

Hello, I am new to Bokeh and programming in general and I apologize in advance for any rookie mistakes. (I am using Bokeh server and I have Bokeh version 3.1.0.)

Here is my problem. I have two DatetimePicker widgets (for start and end of plot range) and I want to link it with my plot x axis. I haven’t found any example to show how to do this/if it is even possible?

I would like to link DatetimePicker with plot so when I change date and time in DatetimePicker the plot ranges updates. I found workaround to update plot range on button click, but I believe there are more elegant ways. If possible I would also like to link plot with DatetimePicker, so that date and time changes in widget when I move plot with Pan tool.

I tried to link it like DaterangeSlider, but it didn’t work:

range_slider.js_link("value", p.x_range, "start", attr_selector=0)
range_slider.js_link("value", p.x_range, "end", attr_selector=1)

Here is a reproducible example:

from bokeh.plotting import figure, ColumnDataSource, curdoc
from bokeh.models import DatetimePicker, Button
import pandas as pd
from bokeh.layouts import column, row
from datetime import datetime

# Create dummy data
data = {'time_stamp':  ['2023-03-01 10:00:00', '2023-03-01 11:00:00', '2023-03-01 12:00:00', '2023-03-01 13:00:00', 
                        '2023-03-01 14:00:00', '2023-03-01 15:00:00', '2023-03-01 16:00:00', '2023-03-01 17:00:00', 
                        '2023-03-01 18:00:00', '2023-03-01 19:00:00', '2023-03-01 20:00:00', '2023-03-01 21:00:00', 
                        '2023-03-01 22:00:00', '2023-03-01 23:00:00', '2023-03-02 00:00:00', '2023-03-02 01:00:00'],
        'temperature': ['20', '22', '24', '31', '19', '11', '28', '15', '12', '22', '27', '35', '12', '36', '40', '10']
        }

df = pd.DataFrame(data)
df['time_stamp'] = pd.to_datetime(df['time_stamp'])

source = ColumnDataSource(df)

# Draw plot
p = figure(height=775, width=1800, x_axis_type="datetime")
p.line(x='time_stamp', y='temperature', line_width=2, source=source)

# Create DatetimePicker widgets
datetime_picker_min = DatetimePicker(
    title="Pick min date",
    min_date="2023-01-01T00:00:00",
    max_date="2023-03-18T00:00:00",
    value="2023-03-01T10:00:00"
)

datetime_picker_max = DatetimePicker(
    title="Pick max date",
    min_date="2023-01-01T00:00:00",
    max_date="2023-03-18T00:00:00",
    value="2023-03-01T18:00:00"
)

# Function to update plot range to DatetimePicker values
def update_plot_stats():
    start = datetime_picker_min.value/1000
    start_readable = datetime.utcfromtimestamp(start).strftime('%Y-%m-%d %H:%M:%S')
    end = datetime_picker_max.value/1000
    end_readable = datetime.utcfromtimestamp(end).strftime('%Y-%m-%d %H:%M:%S')

    start_koncen = pd.to_datetime(start_readable, format = '%Y-%m-%d %H:%M:%S')
    end_koncen = pd.to_datetime(end_readable, format = '%Y-%m-%d %H:%M:%S')
    
    p.x_range.start = start_koncen 
    p.x_range.end = end_koncen

buttonUpdatePlt = Button(label="Update plot for stats", button_type="success", width=200, height=50, styles={"font-size": "20px"})
buttonUpdatePlt.on_click(update_plot_stats)

curdoc().add_root(column(p, row(datetime_picker_min, datetime_picker_max, buttonUpdatePlt)))

I was also trying to use DatetimeRangePicker, but I encounter problems when trying to select range within the same day but different hours. I used this link as an example for DatetimeRangePicker:

You are making things more complicated than they are. :slight_smile: The date picker values are already the correct units to set the range, and you can add callbacks on those values to avoid the button. The following works for me:

datetime_picker_min.on_change("value", 
                              lambda attr, old, new: update_plot_stats())
datetime_picker_max.on_change("value", 
                              lambda attr, old, new: update_plot_stats())

def update_plot_stats():
    p.x_range.start = datetime_picker_min.value
    p.x_range.end = datetime_picker_max.value

Note that there isn’t much actual data (only around March 1st) so most dates result in a “blank” plot since there is not data between the new range start and end.

Bryan thank you for your fast response!

Your solution fixed one part of my problem, but I still don’t understand how to link plot to DatetimePicker (I want DatetimePicker to update values, when I move plot with Pan tool) if this is even possible?

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.