54

I'm using bokeh with an ipython notebook.

I want to plot a line graph in bokeh using a pandas DataFrame containing datetimes:

import pandas as pd
from datetime import datetime as dt
from bokeh.io import output_notebook
from bokeh.charts import Bar, Line, show

df = pd.DataFrame(data=[1,2,3],
                  index=[dt(2015, 1, 1), dt(2015, 1, 2), dt(2015, 1, 3)],
                  columns=['foo'])

output_notebook()
show(Line(df))

However, bokeh uses microseconds! Why is this? How do I fix it?

bokeh plot of line

Wilfred Hughes
  • 29,846
  • 15
  • 139
  • 192

3 Answers3

138

As of bokeh 0.12.3, you can now do:

p = figure(..., x_axis_type='datetime', ...)
Emmanuel
  • 13,935
  • 12
  • 50
  • 72
  • 2
    It would be great if this were automatically inferred from the pandas column dtype. – Evan Mar 30 '20 at 23:02
  • 1
    Make sure your pandas column is [datetime](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.to_datetime.html) or the chart will be blank :) – gumdropsteve Jan 19 '21 at 09:46
43

is that ok ?

enter image description here

import pandas as pd
from math import pi
from datetime import datetime as dt
from bokeh.io import output_file
from bokeh.charts import show
from bokeh.models import DatetimeTickFormatter
from bokeh.plotting import figure

df = pd.DataFrame(data=[1,2,3],
                  index=[dt(2015, 1, 1), dt(2015, 1, 2), dt(2015, 1, 3)],
                  columns=['foo'])
p = figure(plot_width=400, plot_height=400)
p.line(df.index, df['foo'])
p.xaxis.formatter=DatetimeTickFormatter(
        hours=["%d %B %Y"],
        days=["%d %B %Y"],
        months=["%d %B %Y"],
        years=["%d %B %Y"],
    )
p.xaxis.major_label_orientation = pi/4
output_file('myplot.html')
show(p)
Matthew Finlay
  • 3,354
  • 2
  • 27
  • 32
euri10
  • 2,446
  • 3
  • 24
  • 46
  • 1
    How comes your graph X axis shows 1 January two times, and then 2, and 3 January? – multigoodverse Mar 10 '16 at 10:01
  • @A.S that's b/c all of the possible time resolutions have the same formatter. Chaning those to be more scale-specific should work. – Paul H Mar 17 '16 at 17:08
  • This works pretty fine, thanks. But I wonder wy do we need to define the format for all the different time ranges (hour,day,month,year)? Do you have any idea? – Brandt May 02 '17 at 13:04
  • This helped me realize that if you want a specific format to consistently be used as you zoom in/out, you should set the format for each. This was not obvious to me at first. – Steven C. Howell Feb 14 '20 at 21:32
6

FWIW, the default behavior has changed since the question was first posted. The original code now yields:

outcome from code

jsignell
  • 3,072
  • 1
  • 22
  • 23