0

I'm with a weird behavior in Seaborn inside a Jupyter Notebook. I draw a list of bloxplots and it prints fine:

sns.boxplot(
data=df_enem, y='CO_ESCOLA', x='nota_final', orient='h', 
order=df_melhores.head(NUM_MELHORES).CO_ENTIDADE)

The top of the chart is fine, as you can see in this screenshot: good image

Now I print exactly the same chart, but get and set the yticks and the figure margins are messed up:

ax = sns.boxplot(data=df_enem, y='CO_ESCOLA', x='nota_final', orient='h', 
                 order=df_melhores.head(NUM_MELHORES).CO_ENTIDADE)
locs, labels = plt.yticks()
plt.yticks(locs, labels);

messed up margins

If I print the locs and labels variables, I get just:

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39] <a list of 40 Text yticklabel objects>

The same problem happens at the bottom of the figure.

Any workaround to fix this figure?

neves
  • 33,186
  • 27
  • 159
  • 192

1 Answers1

1

You need to record your ylim before changing the yticks and then set it back after having changed the ticks. Something like this should work fine:

ylim=ax.get_ylim()    
locs, labels = plt.yticks()
plt.yticks(locs, labels)
ax.set_ylim(ylim)

The reason behind this problem is that lim and ticks are not independent. The ticks are just discrete points within your limits. So when you set the yticks the limits of the graph are changed to match the first/last ytick element. You can see this with a simple example:

iris = sns.load_dataset("iris")
ax = sns.boxplot(data=iris, orient="h", palette="Set2")
ylim=ax.get_ylim()

The ylim are: (3.5, -0.5). If we now change the the yticks and check again the ylim:

yticks = ax.get_yticks()
ax.set_yticks(yticks)
ylim=ax.get_ylim()

we have:

In [38]: yticks
Out[38]: array([0, 1, 2, 3])
In [39]: ylim
Out[39]: (3.0, 0.0)

p.s. this is not a seaborn related issue, but is just the way matplotlib works. For more info you can check the ticker api and this answer.

baccandr
  • 1,090
  • 8
  • 15
  • The workaround is fine, but the analysis here is wrong. This is due to a bug in matplotlib 3.1.1. So use any other version of matplotlib. I therefore closed as duplicate of [this](https://stackoverflow.com/questions/56942670/matplotlib-seaborn-first-and-last-row-cut-in-half-of-heatmap-plot/56942725#56942725). – ImportanceOfBeingErnest Oct 23 '19 at 10:58