3

I'm experimenting with seaborn and have a question about specifying axes properties. In my code below, I've taken two approaches to creating a heatmap of a matrix and placing the results on two sets of axes in a figure.

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

A=np.random.randn(4,4)
labels=['a','b','c','d']

fig, ax = plt.subplots(2)

sns.heatmap(ax =ax[0], data = A)
ax[0].set_xticks(range(len(labels)))
ax[0].set_xticklabels(labels,fontsize=10,rotation=45)
ax[0].set_yticks(range(len(labels)))
ax[0].set_yticklabels(labels,fontsize=10,rotation=45)


ax[1].set_xticks(range(len(labels)))
ax[1].set_xticklabels(labels,fontsize=10,rotation=45)
ax[1].set_yticks(range(len(labels)))
ax[1].set_yticklabels(labels,fontsize=10,rotation=45)
sns.heatmap(ax =ax[1], data = A,xticklabels=labels, yticklabels=labels)
plt.show() 

The resulting figure looks like this:

enter image description here

Normally, I would always take the first approach of creating the heatmap and then specifying axis properties. However, when creating an animation (to be embedded on a tkinter canvas), which is what I'm ultimately interested in doing, I found such an ordering in my update function leads to "flickering" of axis labels. The second approach will eliminate this effect, and it also centers the tickmarks within squares along the axes.

However, the second approach does not rotate the y-axis tickmark labels as desired. Is there a simple fix to this?

fishbacp
  • 1,123
  • 3
  • 14
  • 29

1 Answers1

1

I'm not sure this is what you're looking for. It looks like you create your figure after you change the yticklabels. so the figure is overwriting your yticklabels.

Below would fix your issue.

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

A=np.random.randn(4,4)
labels=['a','b','c','d']

fig, ax = plt.subplots(2)

sns.heatmap(ax =ax[0], data = A)
ax[0].set_xticks(range(len(labels)))
ax[0].set_xticklabels(labels,fontsize=10,rotation=45)
ax[0].set_yticks(range(len(labels)))
ax[0].set_yticklabels(labels,fontsize=10,rotation=45)


ax[1].set_xticks(range(len(labels)))
ax[1].set_xticklabels(labels,fontsize=10,rotation=45)
ax[1].set_yticks(range(len(labels)))
sns.heatmap(ax =ax[1], data = A,xticklabels=labels, yticklabels=labels)
ax[1].set_yticklabels(labels,fontsize=10,rotation=45)

plt.show() 

enter image description here

Jay Patel
  • 1,374
  • 1
  • 8
  • 17
  • This works fine for a single plot, but does not address the "flickering" problem when I incorporate it into an update function used in an animation. It seems that only by setting axis properties prior to calling sns.heatmap can I eliminate the flickering. I've also tried setting xlabels, ylabels=False inside sns.heatmap and then setting the axis properties afterwards, but that does not solve the problem. I probably should have included the animation code as well in my original post. Should I create a new post including the animation code or edit the above? Apologies for not being more clear. – fishbacp Nov 24 '21 at 13:28