pythonmatplotlibseaborn

How do I center vertical labels in a seaborn barplot?


When I add a vertical text label to a seaborn bar chart, the labels are offset to the left of centre, like so:

enter image description here

How can I nudge the labels a little to the right so that they are nicely centred?

MWE:

import matplotlib.pyplot as plt
import seaborn as sns

percentages = [8.46950845e+00, 1.58712232e+01, 2.13963086e+01, 2.33865318e+01, 2.04539820e+01, 1.41358888e+01, 7.79622697e+00, 3.49245775e+00, 1.28729140e+00, 3.91327891e-01, 9.80073446e-02, 2.02461563e-02, 3.46222120e-03, 4.92413036e-04, 5.82500571e-05, 5.70562340e-06, 4.59952409e-07, 3.05322729e-08, 1.57123083e-09, 4.80936609e-11]

plt.figure(figsize=(9, 5), dpi=100)
ax = sns.barplot(
    x = range(1, len(percentages) + 1),
    y = percentages,
    legend=False,
    hue = range(1, len(percentages) + 1),
    palette="GnBu_d"
)
plt.text(0, percentages[0]/2, "Additive", ha="center", va="center", rotation=90, fontsize=10, weight="bold")
plt.text(1, percentages[1]/2, "Additive x Additive", ha="center", va="center", rotation=90, weight="bold")
plt.show()

Solution

  • Your text is correctly centered, however you only use letters that are above the baseline, which makes it look like it is not centered.

    See here for a description of matplotlib's alignment modes:

    enter image description here

    So what you're looking for would be va='center_baseline', and this works well on horizontal text/bars without rotation:

    plt.text(percentages[1]/2, 1, 'Additive x Additive', ha='center',
             va='center_baseline', weight='bold')
    

    enter image description here

    Unfortunately, this is not supported in ha, even with rotation=90.

    One option could to manually add a small offset, which will depend on the figure dimensions:

    plt.text(1, 1, 'Add', ha='center', rotation=90, weight='bold')
    plt.text(1, 4, 'bdpdjy', ha='center', rotation=90, weight='bold', color='red')
    
    offset = 0.07
    plt.text(2+offset, 1, 'Add', ha='center', rotation=90, weight='bold')
    plt.text(2+offset, 4, 'bdpdjy', ha='center', rotation=90, weight='bold', color='blue')
    

    Example:

    enter image description here

    Note how the red bdpdjy is correctly centered, but no longer the blue one with a manual offset.