0

I have the following heatmap:

enter image description here

I've broken up the category names by each capital letter and then capitalised them. This achieves a centering effect across the labels on my x-axis by default which I'd like to replicate across my y-axis.

yticks = [re.sub("(?<=.{1})(.?)(?=[A-Z]+)", "\\1\n", label, 0, re.DOTALL).upper() for label in corr.index]
xticks = [re.sub("(?<=.{1})(.?)(?=[A-Z]+)", "\\1\n", label, 0, re.DOTALL).upper() for label in corr.columns]
fig, ax = plt.subplots(figsize=(20,15))
sns.heatmap(corr, ax=ax, annot=True, fmt="d",
            cmap="Blues", annot_kws=annot_kws,
            mask=mask, vmin=0, vmax=5000,
            cbar_kws={"shrink": .8}, square=True,
            linewidths=5)
for p in ax.texts:
    myTrans = p.get_transform()
    offset = mpl.transforms.ScaledTranslation(-12, 5, mpl.transforms.IdentityTransform())
    p.set_transform(myTrans + offset)
plt.yticks(plt.yticks()[0], labels=yticks, rotation=0, linespacing=0.4)
plt.xticks(plt.xticks()[0], labels=xticks, rotation=0, linespacing=0.4)

where corr represents a pre-defined pandas dataframe.

I couldn't seem to find an align parameter for setting the ticks and was wondering if and how this centering could be achieved in seaborn/matplotlib?

apgsov
  • 794
  • 1
  • 8
  • 30

1 Answers1

0

I've adapted the seaborn correlation plot example below.

from string import ascii_letters
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="white")

# Generate a large random dataset
rs = np.random.RandomState(33)
d = pd.DataFrame(data=rs.normal(size=(100, 7)),
                 columns=['Donald\nDuck','Mickey\nMouse','Han\nSolo',
                          'Luke\nSkywalker','Yoda','Santa\nClause','Ronald\nMcDonald'])

# Compute the correlation matrix
corr = d.corr()

# Generate a mask for the upper triangle
mask = np.triu(np.ones_like(corr, dtype=bool))

# Set up the matplotlib figure
f, ax = plt.subplots(figsize=(11, 9))

# Generate a custom diverging colormap
cmap = sns.diverging_palette(230, 20, as_cmap=True)

# Draw the heatmap with the mask and correct aspect ratio
sns.heatmap(corr, mask=mask, cmap=cmap, vmax=.3, center=0,
            square=True, linewidths=.5, cbar_kws={"shrink": .5})

for i in ax.get_yticklabels():
    i.set_ha('right')
    i.set_rotation(0)
    
for i in ax.get_xticklabels():
    i.set_ha('center')

Note the two for sequences above. These get the label and then set the horizontal alignment (You can also change the vertical alignment (set_va()).

The code above produces this:

example plot

mullinscr
  • 1,668
  • 1
  • 6
  • 14
  • In case you want to center the y-ticks, they will overlap with the axis. You can move them similar to [How to move a tick's label in matplotlib?](https://stackoverflow.com/questions/28615887/how-to-move-a-ticks-label-in-matplotlib) – JohanC Feb 01 '21 at 16:44