Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Bokeh hover date time

Tags:

python

bokeh

I am trying to get a line plot via Bokeh in Python. I am new to Bokeh and I am trying to apply hover tool tips over the plot. The x-axis of the plot has Timestamp values which are converted into epoch string. I've reviewed some same problems here and tried to use the workaround for my case but it doesn't seem to work. On the plot it gives ??? where the time should show up.

Any suggestions for my code?

Timestamp is in format 2016-12-29 02:49:12

Also can someone tell how do I format x-axis ticks to show up vertically ?

p = figure(width=1100,height=300,tools='resize,pan,wheel_zoom,box_zoom,reset,previewsave,hover',logo=None)
p.title.text = "Time Series for Price in Euros"
p.grid.grid_line_alpha = 0
p.xaxis.axis_label = "Day"
p.yaxis.axis_label = "Euros"
p.ygrid.band_fill_color = "olive"
p.ygrid.band_fill_alpha = 0.1
p.circle(df['DateTime'],df['EuP'], size=4, legend='close',
  color='darkgrey', alpha=0.2)
p.xaxis.formatter = DatetimeTickFormatter(formats=dict(
hours=["%d %B %Y"],
days=["%d %B %Y"],
months=["%d %B %Y"],
years=["%d %B %Y"],
))

source = ColumnDataSource(data=dict(time=[x.strftime("%Y-%m-%d %H:%M:%S")for x in df['DateTime']]))
hover = p.select(dict(type=HoverTool))
hover.tooltips = {"time":'@time', "y":"$y"}
hover.mode = 'mouse'
p.line(df['DateTime'],df['EuP'],legend='Price',color='navy',alpha=0.7)
like image 992
Yasir Azeem Avatar asked Dec 29 '16 13:12

Yasir Azeem


1 Answers

Since this answer was originally posted, new work has gone into Bokeh to make things simpler. A datetime field can be formatted as a datetime directly by the hover tool, by specifying a formatter, e.g.:

HoverTool(tooltips=[('date', '@DateTime{%F}')],
          formatters={'@DateTime': 'datetime'})

It is no longer necessary to pre-format date fields in the data source as below. For more information see Formatting Tooltip Fields


OLD ANSWER:

The problem with your tooltip is you created a source with the string representation of the dates, but the p.line() call is unaware of it. So you have to pass in a columndatasource that has the tooltip, the x and y values.

Here is a working variant of your code:

from bokeh.plotting import figure, show
from bokeh.models.formatters import DatetimeTickFormatter
from bokeh.models import ColumnDataSource
from bokeh.models.tools import HoverTool
import pandas as pd
import numpy as np

data = {
    'DateTime' : pd.Series(
        ['2016-12-29 02:49:12',
        '2016-12-30 02:49:12',
        '2016-12-31 02:49:12'],
        dtype='datetime64[ns]'),
    'EuP' : [20,40,15]
}
df = pd.DataFrame(data)
df['tooltip'] = [x.strftime("%Y-%m-%d %H:%M:%S") for x in df['DateTime']]
p = figure(width=1100,height=300,tools='resize,pan,wheel_zoom,box_zoom,reset,previewsave,hover',logo=None)
p.title.text = "Time Series for Price in Euros"
p.grid.grid_line_alpha = 0
p.xaxis.axis_label = "Day"
p.yaxis.axis_label = "Euros"
p.ygrid.band_fill_color = "olive"
p.ygrid.band_fill_alpha = 0.1
p.circle(df['DateTime'],df['EuP'], size=4, legend='close',
  color='darkgrey', alpha=0.2)
p.xaxis.formatter = DatetimeTickFormatter(formats=dict(
 hours=["%d %B %Y"],
 days=["%d %B %Y"],
 months=["%d %B %Y"],
 years=["%d %B %Y"],
))
hover = p.select(dict(type=HoverTool))
tips = [('when','@tooltip'), ('y','$y')]
hover.tooltips = tips
hover.mode = 'mouse'
p.line(x='DateTime', y='EuP', source=ColumnDataSource(df),
       legend='Price',color='navy',alpha=0.7)
show(p)

Also note there is an open issue about the lack of formatting options in the bokeh tooltip. There might be an easier way to not have to format the datestrings as a separate column:

https://github.com/bokeh/bokeh/issues/1239

Also can someone tell how do I format x-axis ticks to show up vertically ?

They look fine to me, sorry I cannot help on that one.

Hope this helps!

PS it would be better next time if you posted a working script with import statements, and a mocked up dataframe to make it possible to test. It took some time to sort it all out. But I am learning Bokeh so that is fine :)

like image 126
Alex G Rice Avatar answered Oct 25 '22 20:10

Alex G Rice