2
votes

I'm updating all my systems from Bokeh 0.9 to Bokeh 0.11, and have one chart that I can't seem to get to work anymore.

I start with a DataFrame like this:

Out[75]: 
         First  Second  Third  Fourth  Fifth
Red         27      22     33      20      9
Blue        10      27     18      31     14
Magenta     32      10     11       8     10
Yellow       8       6     14      13     15
Green        9       5      6       6      2

And I would produce a nice chart with colors names along the axis, 5 stacked bars in the same order as the legend, which would give the ranks. For example, this is the output for a stacked bar with 10 ranks and 10 categories that we generated in 0.9.0:

Stacked Bar with 10 categories and 10 ranks

I used to do this by just:

plot = Bar(dataframe, list_of_color_names, title="stack of 5 categorical ranked in order from first to last", stacked=True, legend="top_right", ylabel="count", width=600, height=600)

Where "list_of_colors_names" was just a list generated from the index of the DataFrame, but this doesn't work anymore. I realize that 0.11 drops "stacked=True" and and now we use "stack", but I still can't seem to get it to work.

The examples on the Bokeh website are for simpler bar charts and when I apply that model to my DataFrame I get a variety of errors, such as "'NoneType' object is not iterable", but I'm clearly just missing the larger picture about how this type of stacked bar works in 0.11. There are a few other Bokeh stacked bar discussions here but they are either for an earlier version of Bokeh (my code worked in 0.9), or seemed to be a different case. What's the most best way to do this kind of stacked bar now?

1

1 Answers

2
votes

I do not know if it is the only way of doing it, but the stacked bar chart in Bokeh 0.11 works if you put all the data in a column, rather than in a matrix. You then need to provide the matrix row and column indexes in corresponding dataframe columns, called nr and rank in the example code below. These are referred when calling the Bar method, where "stack" shall refer to the columns in your matrix example.

import pandas as pd
from bokeh.charts import Bar, show

all_data={
'nr':  [1,2,3,4,5,
        1,2,3,4,5,
        1,2,3,4,5,
        1,2,3,4,5,
        1,2,3,4,5],
'rank':['First','First','First','First','First',
       'Second','Second','Second','Second','Second',
       'Third','Third','Third','Third','Third',
       'Fourth','Fourth','Fourth','Fourth','Fourth',
       'Fifth','Fifth','Fifth','Fifth','Fifth'],
'data':[27,10,32,8,9,
        22,27,10,6,5,
        33,18,11,14,6,
        20,31,8,16,6,
        9,14,10,15,2]
      }
df=pd.DataFrame(all_data)

p=Bar(df,label='nr',values='data',stack='rank',legend='top_right')
show(p)

A comment: The standard Bar chart palette only has six colors, as shown in your 10 rank example. I use the code snippet below, adapted from others, to generate as many distinct colors as needed for the bar chart. It uses a matplotlib colormap colormap as input.

import matplotlib.cm as cm
import numpy as np

colormap =cm.get_cmap("jet")
different_colors=10
color_mapping=colormap(np.linspace(0,1,different_colors),1,True)
bokeh_palette=["#%02x%02x%02x" % (r, g, b) for r, g, b in color_mapping[:,0:3]]

p=Bar(df,label='nr',values='data',stack='rank',legend='top_right',palette=bokeh_palette)
show(p)

Here is a good page discussing how to choose matplotlib colormaps.