How to make a multi-level chart column label

Question:

I stopped at this point:

df = pd.DataFrame({'id': [1, 2, 3],
               'users': [40, 2, 51],
               'buyers': [15, 1, 29],
               'percentage': [37.5000, 50.0000, 56.8627]})

fig, ax = plt.subplots(figsize=(10, 6))

# Plot the all users
sns.barplot(x='id', y='users', data=df, palette='Blues', edgecolor='grey', alpha=0.7)
# Plot the buyers
sns.barplot(x='id', y='buyers', data=df, palette='Blues', edgecolor='black', hatch='//')

# display column values
for container in ax.containers:
    ax.bar_label(container, fontsize=13)
plt.show()

The chart looks like this:

enter image description here

I also need to include data from the "percentage" frame in the shaded portion of the chart. Please tell me how to do it. Thanks

Asked By: Kate

||

Answers:

  • Add the 'percentage' values by passing a custom list to the labels= parameter in .bar_label
    • Use enumerate and .loc to index the values from df.
    • f"{v.get_height()}: {df.loc[i, 'percentage']}%" is used to customize the annotation string.
  • See this answer for additional details and examples using .bar_label.
  • See this answer for additional details about seaborn stacked bars with annotations.
  • Tested in python 3.10, pandas 1.4.3, matplotlib 3.5.2, seaborn 0.12.0
df = pd.DataFrame({'id': [1, 2, 3],
               'users': [40, 2, 51],
               'buyers': [15, 1, 29],
               'percentage': [37.5000, 50.0000, 56.8627]})

fig, ax = plt.subplots(figsize=(10, 6))

# Plot the all users
sns.barplot(x='id', y='users', data=df, palette='Blues', edgecolor='grey', alpha=0.7, ax=ax)
# Plot the buyers
sns.barplot(x='id', y='buyers', data=df, palette='Blues', edgecolor='darkgrey', hatch='//', ax=ax)

# extract the separate containers
c1, c2 = ax.containers

# annotate with the users values
ax.bar_label(c1, fontsize=13)

# annotate with the buyer and percentage values
l2 = [f"{v.get_height()}: {df.loc[i, 'percentage']}%" for i, v in enumerate(c2)]
ax.bar_label(c2, labels=l2, fontsize=8, label_type='center', fontweight='bold')
   
plt.show()

enter image description here

Answered By: Trenton McKinney