Django Bokeh Stacked Bar Chart

I have the following queryset:

<QuerySet [
{'Order_Type': 'Phone', 'Order_Priority': 'NA', 'Order_total': 2}, 
{'Order_Type': 'Web', 'Order_Priority': 'High', 'Order_total': 3}, 
{'Order_Type': 'Web', 'Order_Priority': 'Med', 'Order_total': 9}]>

I want to create a stacked bar chart using Bokeh that shows the total number of orders for each order type; each bar will also show the breakdown order priority (see image).

enter image description here

I'm getting an error because the axis categorical factors (Order Type in this case) is not unique. can someone help me with this?

The problem is that bokeh expects unique categorical factors on the x-axis, but your initial queryset contained multiple records for the same Order _Type. In order to fix this, you need to first aggregate your data so that each Order_Type has a breakdown of Order_priority values.

from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource
from collections import defaultdict

data = [
    {'Order_Type': 'Phone', 'Order_Priority': 'NA', 'Order_total': 2},
    {'Order_Type': 'Web', 'Order_Priority': 'High', 'Order_total': 3},
    {'Order_Type': 'Web', 'Order_Priority': 'Med', 'Order_total': 9},
]

aggregated_data = defaultdict(lambda: defaultdict(int))
for entry in data:
    order_type = entry['Order_Type']
    order_priority = entry['Order_Priority']
    aggregated_data[order_type][order_priority] += entry['Order_total']

order_types = list(aggregated_data.keys())
order_priorities = sorted({priority for values in aggregated_data.values() for priority in values})

source_data = {'Order_Type': order_types}
for priority in order_priorities:
    source_data[priority] = [aggregated_data[order_type].get(priority, 0) for order_type in order_types]

source = ColumnDataSource(source_data)
p = figure(x_range=order_types, title="Stacked Order Chart")
colors = ["#c9d9d3", "#718dbf", "#e84d60"][:len(order_priorities)]
p.vbar_stack(order_priorities, x='Order_Type', source=source, color=colors, legend_label=order_priorities)
show(p)
Back to Top