Davis Buls Davis Buls - 8 months ago 368
Python Question

Getting the desired datetime value from x axis in bokeh

I have read the documentation and have searched Google and StackOverflow for answers but none the wiser yet.

I have a bokeh graph with circle glyphs for two variables 'score' and 'stress', and a third variable 'date' as a datetime x axis (picture here). I want the users to be able to click on the circles and be taken to a URL showing a detailed view of that particular data point which is identified by its corresponding date.

I have enabled a tap tool with openURL callback which appends the datetime value at the end of the URL. The problem is that once a data point is clicked, the datetime value passed is not in the desired format:

. What I get instead is the following value: '1468969200000'. So, the user gets re-directed to 'url/1468969200000/' instead of 'url/2016-07-20/'.

Is there a way to change the format of the date value that gets passed once a data point is clicked?

Here is my code (run in jupyter notebook):

import datetime
from bokeh.plotting import figure, output_notebook, show
from bokeh.models import Range1d, OpenURL, TapTool, HoverTool, ColumnDataSource, DatetimeTickFormatter

data = {'score': [4.33, 2.66, 4.66, 2.66, 2.66, 1.66, 1.0, 4.33],
'stress': [3.66, 3.0, 3.0, 1.33, 3.66, 3.33, 1.0, 4.33],
'date': [
datetime.date(2016, 7, 17),
datetime.date(2016, 7, 18),
datetime.date(2016, 7, 19),
datetime.date(2016, 7, 20),
datetime.date(2016, 7, 21),
datetime.date(2016, 7, 22),
datetime.date(2016, 7, 23),
datetime.date(2016, 7, 24)

source = ColumnDataSource(data=data)

TOOLS = ['hover', 'pan', 'tap']

plot = figure(x_axis_type='datetime', plot_height=250, tools=TOOLS)

plot.circle('date', 'score', legend='score', size=15, color='red', source=source)
plot.circle('date', 'stress', legend='stress', size=10, color='orange', source=source)
plot.y_range = Range1d(1, 5, bounds=(1,5))
plot.x_range = Range1d(datetime.date(2016, 7, 17), datetime.date(2016, 7, 23))

hover = plot.select(type=HoverTool)
hover.tooltips = [
("score", "@score"),
("stress", "@stress"),
("date", "@date")

url = 'url/@date/'
taptool = plot.select(type=TapTool)
taptool.callback = OpenURL(url=url)



A simple workaround would be to provide date in string format in addition.

dateStr= {'dateStr': [x.isoformat() for x in data['date']]}

then, you can use dateStr in your hover.tooltips and to generate the url

hover.tooltips = [
    ("score", "@score"),
    ("stress", "@stress"),
    ("date", "@dateStr")

url = 'url/@dateStr/'