Reputation: 1
Adding more details per guidance...
Here's my model:
class Orders(models.Model):
Order_ID = models.CharField(max_length=50, primary_key=True, auto_created=True)
Order_Desc = models.CharField(max_length=255)
Order_Type = models.CharField(max_length=50)
Order_Received_Date = models.DateTimeField()
Order_Priority= models.CharField(max_length=10)
def __str__(self):
return (self.Order_ID)
In my views, i have the following query:
selected_year=request.GET.get('year', datetime.datetime.now().year-1)
Orders_By_Year = Orders.objects.annotate(extract_year=Cast('Order_Received_Date',CharField())).annotate(year=Substr('extract_year', Length('extract_year')-3, 4))
Orders = Orders_By_Year.filter(year=selected_year).values('Order_Type','Order_Priority').annotate(order_total=Count('Order_Priority')).order_by('Order_Type', 'Order_Priority')
This generated the following queryset based on the selected year:
<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).
I'm getting an error because the axis categorical factors (Order Type in this case) is not unique. can someone help me with this?
Upvotes: -1
Views: 75
Reputation: 99
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)
Upvotes: -1