How to plot percentage with seaborn distplot / histplot / displot

  • As of seaborn 0.11.2
  • For both types of plots, experiment with common_binsand common_norm.
    • For example, common_norm=True will show the percent as a part of the entire population, whereas False will show the percent relative to the group.
  • The implementation shown in this answer shows how to add annotations.
import seaborn as sns
import matplotlib.pyplot as ply

# data
data = sns.load_dataset('titanic')

Figure Level

p = sns.displot(data=data, x='age', stat="percent", hue="sex", height=3)
plt.show()

enter image description here

p = sns.displot(data=data, x='age', stat="percent", col="sex", height=3)
plt.show()

enter image description here

  • Type annotations (:=) used in labels requires python >= 3.8. This can be implemented with a for-loop, without using :=.
fg = sns.displot(data=data, x='age', stat="percent", col="sex", height=3.5, aspect=1.25)

for ax in fg.axes.ravel():
    
    # add annotations
    for c in ax.containers:

        # custom label calculates percent and add an empty string so 0 value bars don't have a number
        labels = [f'{w:0.1f}%' if (w := v.get_height()) > 0 else '' for v in c]

        ax.bar_label(c, labels=labels, label_type="edge", fontsize=8, rotation=90, padding=2)
    
    ax.margins(y=0.2)

plt.show()

enter image description here

Axes Level

fig = plt.figure(figsize=(4, 3))
p = sns.histplot(data=data, x='age', stat="percent", hue="sex")
plt.show()

enter image description here

Percent by Group

p = sns.displot(data=data, x='age', stat="percent", hue="sex", height=4, common_norm=False)

enter image description here

p = sns.displot(data=data, x='age', stat="percent", col="sex", height=4, common_norm=False)

enter image description here

fig = plt.figure(figsize=(5, 4))
p = sns.histplot(data=data, x='age', stat="percent", hue="sex", common_norm=False)
plt.show()

enter image description here

Leave a Comment