How do you show values in a stacked bar chart in python?

  • The following method is more succinct, and easily scales.
  • Putting the data into a pandas.DataFrame is the easiest way to plot a stacked bar plot.
  • Using pandas.DataFrame.plot.bar[stacked=True], or pandas.DataFrame.plot[kind='bar', stacked=True], is the easiest way to plot a stacked bar plot.
    • This method returns a matplotlib.axes.Axes or a numpy.ndarray of them.
  • Since seaborn is just a high-level API for matplotlib, these solutions also work with seaborn plots, as shown in How to annotate a seaborn barplot with the aggregated value.
  • For horizontal stacked bars, see Horizontal stacked bar plot and add labels to each section
  • Tested in python 3.10, pandas 1.4.2, matplotlib 3.5.1, seaborn 0.11.2

Imports & Test DataFrame

import pandas as pd
import matplotlib.pyplot as plt

A = [45, 17, 47]
B = [91, 70, 72]
C = [68, 43, 13]

# pandas dataframe
df = pd.DataFrame[data={'A': A, 'B': B, 'C': C}]
df.index = ['C1', 'C2', 'C3']

     A   B   C
C1  45  91  68
C2  17  70  43
C3  47  72  13

Updated for matplotlib v3.4.2

  • Use matplotlib.pyplot.bar_label, which will automatically center the values in the bar.
  • See How to add value labels on a bar chart for additional details and examples with .bar_label.
  • Tested with pandas v1.2.4, which is using matplotlib as the plot engine.
  • If some sections of the bar plot will be zero, see my answer, which shows how to customize the labels for .bar_label[].
  • ax.bar_label[c, fmt='%0.0f', label_type='center'] will change the number format to show no decimal places, if needed.
ax = df.plot[kind='bar', stacked=True, figsize=[8, 6], rot=0, xlabel='Class', ylabel='Count']
for c in ax.containers:

    # Optional: if the segment is small or 0, customize the labels
    labels = [v.get_height[] if v.get_height[] > 0 else '' for v in c]
    
    # remove the labels parameter if it's not needed for customized labels
    ax.bar_label[c, labels=labels, label_type='center']

Seaborn Options

  • seaborn is a high-level api for matplotlib
  • The seaborn.barplot api doesn't have an option for stacking, but it "can" be implemented with sns.histplot, or sns.displot.

Seaborn DataFrame Format

# create the data frame
df = pd.DataFrame[data={'A': A, 'B': B, 'C': C, 'cat': ['C1', 'C2', 'C3']}]

    A   B   C cat
0  45  91  68  C1
1  17  70  43  C2
2  47  72  13  C3

# convert the dataframe to a long form
df = df.melt[id_vars='cat']

  cat variable  value
0  C1        A     45
1  C2        A     17
2  C3        A     47
3  C1        B     91
4  C2        B     70
5  C3        B     72
6  C1        C     68
7  C2        C     43
8  C3        C     13

axes-level plot

# plot
ax = sns.histplot[data=df, x='cat', hue='variable', weights='value', discrete=True, multiple='stack']

# iterate through each container
for c in ax.containers:

    # Optional: if the segment is small or 0, customize the labels
    labels = [v.get_height[] if v.get_height[] > 0 else '' for v in c]
    
    # remove the labels parameter if it's not needed for customized labels
    ax.bar_label[c, labels=labels, label_type='center']

figure-level plot

# plot
g = sns.displot[data=df, x='cat', hue='variable', weights='value', discrete=True, multiple='stack']

# iterate through each axes
for ax in g.axes.flat:

    # iterate through each container
    for c in ax.containers:

        # Optional: if the segment is small or 0, customize the labels
        labels = [v.get_height[] if v.get_height[] > 0 else '' for v in c]

        # remove the labels parameter if it's not needed for customized labels
        ax.bar_label[c, labels=labels, label_type='center']

Original Answer

  • Using the .patches method unpacks a list of matplotlib.patches.Rectangle objects, one for each of the sections of the stacked bar.
    • Each .Rectangle has methods for extracting the various values that define the rectangle.
    • Each .Rectangle is in order from left to right, and bottom to top, so all the .Rectangle objects, for each level, appear in order, when iterating through .patches.
  • The labels are made using an f-string, label_text = f'{height}', so any additional text can be added as needed, such as label_text = f'{height}%'
    • label_text = f'{height:0.0f}' will display numbers with no decimal places.

Plot

plt.style.use['ggplot']

ax = df.plot[stacked=True, kind='bar', figsize=[12, 8], rot='horizontal']

# .patches is everything inside of the chart
for rect in ax.patches:
    # Find where everything is located
    height = rect.get_height[]
    width = rect.get_width[]
    x = rect.get_x[]
    y = rect.get_y[]
    
    # The height of the bar is the data value and can be used as the label
    label_text = f'{height}'  # f'{height:.2f}' to format decimal values
    
    # ax.text[x, y, text]
    label_x = x + width / 2
    label_y = y + height / 2

    # plot only when height is greater than specified value
    if height > 0:
        ax.text[label_x, label_y, label_text, ha='center', va='center', fontsize=8]
    
ax.legend[bbox_to_anchor=[1.05, 1], loc='upper left', borderaxespad=0.]    
ax.set_ylabel["Count", fontsize=18]
ax.set_xlabel["Class", fontsize=18]
plt.show[]

  • To plot a horizontal bar:
    • kind='barh'
    • label_text = f'{width}'
    • if width > 0:
  • Attribution: jsoma/chart.py

How do you show values on a stacked bar chart in Python?

Use matplotlib. pyplot. bar_label , which will automatically center the values in the bar.

How do you show the value of a stacked bar chart?

The Keys to Adding Totals to the Stacked Bar Chart Above:.
Highlight your data including the “Spacing” column but not including the “Grand Total” column. ... .
On the “Insert” menu select a “2-D Stacked Bar Chart”.
Select “Switch Row/Column” as necessary so the “Spacing” values are not listed as an option on the Y axis..

How do you show data in a bar graph in Python?

Call matplotlib. pyplot. barh[x, height] with x as a list of bar names and height as a list of bar values to create a bar chart. Use the syntax “for index, value in enumerate[iterable]” with iterable as the list of bar values to access each index, value pair in iterable.

Chủ Đề