Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Hello fellow programmers,

For a project I want to generate a stacked bar chart plot. I was succesful at this. However, I want to add a label to every bar to indicate the size of each bar. I read the demo on the fairly new added function to matplotlib called the bar label: Bar Label Demo .

The solution I tried to come up with is as follows:

# hard-coded data
dist_lst = [
    [0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 4, 1, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1], 
    [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 14, 0, 1], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0]
# defined colors
colors = [
    "#e6194b", "#3cb44b", "#ffe119", "#4363d8", "#f58231",
    "#911eb4", "#46f0f0", "#f032e6", "#bcf60c", "#fabebe",
    "#008080", "#e6beff", "#9a6324", "#fffac8", "#800000",
    "#aaffc3", "#808000", "#ffd8b1", "#000075", "#808080",
    "#ffffff", "#000000", "#eb5b01", "#db8c62", "#f58b7a",
    "#288C00",
i = 0
lst = np.array(dist_lst)
fig, ax = plt.subplots()
ax.bar(range(6), lst[0], edgecolor="black", color=colors[0])
sum_arr = lst[0]
for data in lst[1:]:
    i += 1
    ax.bar(range(6), data, bottom=sum_arr, edgecolor="black", color=colors[i])
    sum_arr += data
ax.legend(list(range(1, len(lst))), title="families", ncol=2, bbox_to_anchor=(1, 1))
# Adding size labels
for c in ax.containers:
    ax.bar_label(c, label_type="center")

My apologies if it is poorly readable but for now it works... sort off. The issue being it generates a plot containing also the zero values resulting in clutter.

How do I resolve the issue of these zero values being plotted? Also, if anyone has tips for the color pallete, I'm all ears because I would like to make this as readablefriendly as possible.

Thank you for your time!

When you iterate to add the labels at the end the objects held in c are instances of matplotlib.container.BarContainer. These have an attribute datavalues which are used for labelling unless you provide other labels to matplotlib.axes.Axes.bar_label with the parameter labels.

Therefore, setting empty strings for 0 values allows you to control what is added:

# Adding size labels
for c in ax.containers:
    # Create a new list of labels
    labels = [a if a else "" for a in c.datavalues]
    ax.bar_label(c, labels=labels, label_type="center")

Which, in combination with your code, produces:

Thank you for your helpful answer! But I still have a question, I am using the Spyder 5.0.3. IDE and in previous versions (<5.0.0) I get the error: AttributeError: 'BarContainer' object has no attribute 'datavalues' Do you know the cause of this and how can I resolve it? – N.C.C.P. Jun 3, 2021 at 8:05

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.