2

I can't get Bokeh to display my plot. This is my Python code.

import pandas as pd
from bokeh.plotting import figure, ColumnDataSource
from bokeh.io import output_file, show


if __name__ == '__main__':
    file = 'Overview Data.csv'
    overview_df = pd.read_csv(file)
    overview_ds = ColumnDataSource(overview_df)
    output_file('Wins across Seasons.html')
    print(overview_ds.data)
    p = figure(plot_width=400, plot_height=400)

    # add a circle renderer with a size, color, and alpha
    p.circle('Season', 'Wins', source = overview_ds, size=20, color="navy", alpha=0.5)

    # show the results
    show(p)

I checked my Chrome browser Inspect Element and the console shows the following.

Wins across Seasons.html:17 [bokeh] could not set initial ranges e.set_initial_range @ Wins across Seasons.html:17

This only seems to happen when I am reading from a file. Hard-coding x and y coordinates work.

I have checked other posts but none of the fixes worked. All my packages are up to date.

This is the file I am reading

Season,Matches Played,Wins,Losses,Goals,Goals Conceded,Clean Sheets
2011-12,38,28,5,89,33,20
2010-11,38,23,4,78,37,15
2009-10,38,27,7,86,28,19
2008-09,38,28,4,68,24,24
2007-08,38,27,5,80,22,21
2006-07,38,28,5,83,27,16

This is the output of the print statement.

{'Season': array(['2011-12', '2010-11', '2009-10', '2008-09', '2007-08', '2006-07'],
      dtype=object), 'Matches Played': array([38, 38, 38, 38, 38, 38], dtype=int64), 'Wins': array([28, 23, 27, 28, 27, 28], dtype=int64), 'Losses': array([5, 4, 7, 4, 5, 5], dtype=int64), 'Goals': array([89, 78, 86, 68, 80, 83], dtype=int64), 'Goals Conceded': array([33, 37, 28, 24, 22, 27], dtype=int64), 'Clean Sheets': array([20, 15, 19, 24, 21, 16], dtype=int64), 'index': array([0, 1, 2, 3, 4, 5], dtype=int64)}
braaterAfrikaaner
  • 1,072
  • 10
  • 20
arka roy
  • 23
  • 1
  • 3

2 Answers2

4

Bokeh does not know what to do with those string dates unless you tell it. There are two basic possibilities:

  • Keep them as strings, and treat them as categorical factors. You can do that by telling Bokeh what the factors are when you create the plot:

    p = figure(plot_width=400, plot_height=400, 
               x_range=list(overview_df.Season.unique()))
    

    That results in this figure:

    enter image description here

    If you want a different order of categories you can re-order x_range however you like.

  • Convert them to real datetime values and use a datetime axis. You can do this by telling Pandas to parse column 0 as a date field:

    overview_df = pd.read_csv(file, parse_dates=[0])
    

    and telling Bokeh to use a datetime axis:

    p = figure(plot_width=400, plot_height=400, x_axis_type="datetime")
    

    That results in this figure:

    enter image description here

bigreddot
  • 33,642
  • 5
  • 69
  • 122
  • Was facing the same problem right now, thanks. I am not sure if it's too difficult but a warning from bokeh would have saved me some time. I had set the x_axis_type='datetime' but my x axis values were strings, had to do pd.to_datetime() and it worked. – Abhinav Upadhyay Jul 16 '18 at 14:17
  • It's not really possible to warn until things hit the browser, and the type is ultimately wrong in the place it is needed. Before then, there is no way to know what the ultimate type will be, i.e. you might have a datetime axis and strings, and a `CustomJSTransform` that turns the strings to dates in the browser. Warning about that would be incorrect, but it's not really possible to distinguish those cases. Perhaps we could make a better JS console message, but it would still just be a JS console message that most people won't even know to look for. – bigreddot Jul 16 '18 at 16:18
  • I understand. I just learned to use it yesterday and already feel productive with it. Are you a developer behind it? I want to say thank you for creating and maintaining it. – Abhinav Upadhyay Jul 16 '18 at 16:54
  • 1
    Yes, I am the project lead, thank you very much for the kind words – bigreddot Jul 16 '18 at 17:09
  • great solution. Note that you can get the same error when you pass a list of date objects instead of datetime objects. --> convert them to datetime and it works. – Joris May 12 '21 at 11:44
1

you can convert the 'Season'-column to datetime to get an output.

overview_df = pd.read_csv(file)
overview_df.Season = pd.to_datetime(overview_df.Season)
overview_ds = ColumnDataSource(overview_df)
habet
  • 131
  • 10