1

I am trying to get to something like this but with more cats for each scenario (I have 4 scenarios but many cats): Desired Output

I can only achieve this when the number of 'Cat's is equal to the number of 'Scenario's. I don't fully understand how the factors line in the code is working and I think the answer lies within that. whenever I add more Cats I get this error:

IndexError: list index out of range

The code I have is follows:

from bokeh.models import ColumnDataSource, FactorRange
from bokeh.models import Range1d
from calendar import month_abbr
import numpy as np
from bokeh.palettes import Spectral3
from bokeh.transform import factor_cmap

systems = ["Scenario1", "Scenario2", "Scenario3", "Scenario4"] 
subsystems =["Cat1","Cat2", "Cat3", "Cat4"]#, "Cat5", "Cat6"] 

factors =[(systems[ind],subsystem) for ind, subsystem in enumerate(subsystems) for subsystem in subsystems]

count_closed = [52,52,49,26,9,8, 32,20]#,33,66,9,8] 

count_open = [0,0,1, 0] 
count_waived = [3,1,0,0]
statuses = ["count_closed", "count_open", "count_waived"] 

data = dict(factors = factors, count_closed=count_closed, count_open=count_open, count_waived=count_waived )

source = ColumnDataSource(data=data)

p = figure(x_range = FactorRange(*factors), plot_height=250, title="Repeat 10 cats for each scenario",
           toolbar_location = 'right',
           tools = "hover", tooltips="$name @subsystems: @$name")

p.vbar_stack(statuses, x="factors", width=0.9, alpha = 0.5, color=["navy","red","pink"], source=source, legend_label=statuses)

p.y_range.start = 0 
p.x_range.range_padding = 0.1
p.xaxis.major_label_orientation = 1
p.xgrid.grid_line_color = None
p.legend.location = "top_center"
p.legend.orientation = "horizontal"

show(p)
Brain_overflowed
  • 426
  • 1
  • 5
  • 21

1 Answers1

0

To generate a list with tuples of all combinations, your variable factors, you can use

from itertools import product
factors = list(product(systems, subsystems))

This will create a list which is understood by bokehs FactorRange.

Complete Example

from itertools import product

import numpy as np

from bokeh.models import ColumnDataSource, FactorRange, Range1d
from bokeh.plotting import figure, show, output_notebook
output_notebook()

systems = ["Scenario1", "Scenario2", "Scenario3", "Scenario4"]
subsystems =["Cat1","Cat2", "Cat3", "Cat4", "Cat5", "Cat6"]

factors = list(product(systems, subsystems))

count_closed = np.random.randint(0,20, len(factors))
count_open = np.random.randint(0,20, len(factors))
count_waived = np.random.randint(0,20, len(factors))
statuses = ["count_closed", "count_open", "count_waived"] 

data = dict(factors = factors, count_closed=count_closed, count_open=count_open, count_waived=count_waived )

source = ColumnDataSource(data=data)

p = figure(x_range = FactorRange(*factors), plot_height=250, title="Repeat 10 cats for each scenario",
           toolbar_location = 'right',
           tools = "hover", tooltips="$name @subsystems: @$name")

p.vbar_stack(statuses, x="factors", width=0.9, alpha = 0.5, color=["navy","red","pink"], source=source, legend_label=statuses)

p.y_range.start = 0 
p.x_range.range_padding = 0.1
p.xaxis.major_label_orientation = 1
p.xgrid.grid_line_color = None
p.legend.location = "top_center"
p.legend.orientation = "horizontal"

show(p)

Output

Bar plot with 4 scenarios and 6 categories

mosc9575
  • 5,618
  • 2
  • 9
  • 32