2

I am new to bokeh and am trying to plot stock data in a line plot The X-axis should be dates and the y-axis will be Closing Price of the stock.

Here is an example of my code:

data = pd.DataFrame({'Symbol' : ['AMBA','FB','WWD','AMBA','FB','WWD','AMBA','FB','WWD','AMBA','FB','WWD','AMBA','FB','WWD','AMBA','FB','WWD',],
                     'Previous_Close' : [10,20,30,10,20,30,10,20,30,10,20,30,10,20,30,10,20,30,],
                     'Date' : pd.to_datetime(['01/01/16', '01/01/16', '01/01/16', '01/02/16', '01/02/16', '01/02/16', '01/03/16', '01/03/16', '01/03/16', '01/04/16',
                                            '01/04/16', '01/04/16', '01/05/16', '01/05/16', '01/05/16', '01/06/16', '01/06/16', '01/06/16'], format = '%m/%d/%y')})
Symbols = [sym for sym in data.Symbol.unique()]
Dates = [date for date in data.Date.unique()]
format_dates = [date.strftime('%b%d_%y') for date in dates]
colors = ['Darkred', 'Orange', 'Navy']

output_notebook()

TOOLS = ['hover','pan','box_zoom','resize', 'save', 'reset']
# CREATE FIGURE
p = figure(width = 800, height = 600, tools = TOOLS)

cnum = 0
# PLOT
for sym in Symbols:
    # plot stock closing price
    p.line(range(len(dates)), data[data.Symbol==sym].Previous_Close, color = colors[cnum])
    # add stock symbol as text label to end of line
    p.text(len(Symbols), data[data.Symbol==sym].Previous_Close.iloc[-1], [sym],
           text_color = colors[cnum], text_font_size = '10pt')
    cnum +=1
show(p)

Obviously the data is made up here but the idea is the same. All i want is to set the x tick labels to the formatted date names. In Pyplot I would just do:

ax.set_xticklables(format_dates)
axis()

I have tried setting the x_axis_type to 'datetime' but this only gives me milliseconds. I've tried using DateTimeFormatter() but either I'm not understanding how to use it or it's not working (probably the former).

THINGS I'VE TRIED (RE ANSWERS):

This changes the x axis to milliseconds: p = figure(width = 800, height = 600, x_axis_type='datetime', tools = TOOLS)

cnum = 0
# PLOT
for sym in Symbols:
    # NO CHANGE TO X ARG
    p.line(range(len(dates)), data[data.Symbol==sym].Previous_Close, color = colors[cnum])

This changes the x ticks to decades from 1970: p = figure(width = 800, height = 600, x_axis_type='datetime', tools = TOOLS)

cnum = 0
# PLOT
for sym in Symbols:
    # CHANGE X ARG TO DATETIME DATES
    p.line(dates, data[data.Symbol==sym].Previous_Close, color = colors[cnum])
RSHAP
  • 2,337
  • 3
  • 28
  • 39

2 Answers2

1

use:

p = figure(width = 800, height = 600, x_axis_type='datetime', tools = TOOLS)
Luke Canavan
  • 2,107
  • 12
  • 13
  • when I do this (without changing the x parameter of the line) it sets the x-axis to miliseconds. When I change the x arg to dates (ie list of datetime objects) it changes the x ticks to decades from epoch – RSHAP Mar 18 '16 at 04:12
1

It looks like your pandas indexing is causing trouble. I think this code should work:

import numpy as np
import pandas as pd
from bokeh.plotting import figure, output_file, show

data = pd.DataFrame({'Symbol' : ['AMBA','FB','WWD','AMBA','FB','WWD','AMBA','FB','WWD','AMBA','FB','WWD','AMBA','FB','WWD','AMBA','FB','WWD',],
                     'Previous_Close' : [10,20,30,10,20,30,10,20,30,10,20,30,10,20,30,10,20,30,],
                     'Date' : pd.to_datetime(['01/01/16', '01/01/16', '01/01/16', '01/02/16', '01/02/16', '01/02/16', '01/03/16', '01/03/16', '01/03/16', '01/04/16', '01/04/16', '01/04/16', '01/05/16', '01/05/16', '01/05/16', '01/06/16', '01/06/16', '01/06/16'], format = '%m/%d/%y')})

symbols = [sym for sym in data.Symbol.unique()]
dates = [date for date in data.Date.unique()]
dates.sort()
lastDate = dates[-1]
colors = ['Darkred', 'Orange', 'Navy']

output_notebook()

TOOLS = ['hover','pan','box_zoom','resize', 'save', 'reset']
# CREATE FIGURE
p = figure(width = 800, height = 600, tools = TOOLS, x_axis_type="datetime")

# PLOT
for cnum, sym in enumerate(symbols):
    # plot stock closing price
    p.line(data[data.Symbol==sym].Date.values, data[data.Symbol==sym].Previous_Close.values, color = colors[cnum])

p.text(data[data.Date==lastDate].Date.values, data[data.Date==lastDate].Previous_Close.values, data[data.Date==lastDate].Symbol.values, text_color = colors, text_font_size = '10pt')

show(p)

This is what the output looks like: example using dates in an axis

Peter
  • 567
  • 3
  • 10
  • Great this (Mostly) works! Now i just need to find out how to adjust the number of ticks shown on the axis, but I will look that up or post a new question in stackoflow. My one question though is is there a way to get a list of the x axis values or the x tick label values etc... eg in matplotlib I could go `plt.axis()` to get the axis ranges, and `ax.get_xticklabels()` to get a list of the tick labels. Any bokeh equivalent? – RSHAP Mar 18 '16 at 19:38
  • 1
    Hmm, I'm just learning bokeh myself, so I'm not sure there is an easy equivalent. I think getting the tick labels would be hard, because that is done in javascript and can be changed interactively by the user. But to just set the number of ticks you can use, for example, `p.yaxis[0].ticker.desired_num_ticks = 20` in the example code. – Peter Mar 18 '16 at 21:13