seaborn icon indicating copy to clipboard operation
seaborn copied to clipboard

scatterplot without ticks doesn't print labels

Open JanPalasek opened this issue 1 year ago • 3 comments

Hello, I found a bug (or at least a very strange behavior) in sns.scatterplot.

Code:

import matplotlib.pyplot as plt
import seaborn as sns

dataset = sns.load_dataset("titanic")

d = {
  'xtick.top': False,
 'xtick.bottom': False,
 'xtick.labeltop': False,
 'xtick.labelbottom': False,
 'ytick.right': False,
 'ytick.left': False,
 'ytick.labelright': False,
 'ytick.labelleft': False
}
sns.set_theme(style="dark", rc=d)

ax = sns.scatterplot(dataset, x="age", y="fare")
ax.set(xlabel="Age", ylabel="Fare")
plt.show()

image

The plot hides xlabel and ylabel, even though it should be visible according to matplotlib rc settings.

The problem is here:

Module: seaborn._base, lines: 1199-1200 Code:

x_visible = any(t.get_visible() for t in ax.get_xticklabels())
ax.set_xlabel(self.variables.get("x", default_x), visible=x_visible)

Since I hide tick labels in matplotlib rc, x_visible variable is evaluated as False and the xlabel is hidden. However this is not what I want. I want a super clean plot with no ticks but still a label.

Temporary solution: manually overwrite visible when setting the xlabel and ylabel.

import matplotlib.pyplot as plt
import seaborn as sns

dataset = sns.load_dataset("titanic")

d = {
  'xtick.top': False,
 'xtick.bottom': False,
 'xtick.labeltop': False,
 'xtick.labelbottom': False,
 'ytick.right': False,
 'ytick.left': False,
 'ytick.labelright': False,
 'ytick.labelleft': False
}
sns.set_theme(style="dark", rc=d)

ax = sns.scatterplot(dataset, x="age", y="fare")
ax.set_xlabel(xlabel="Age", visible=True)
ax.set_ylabel(ylabel="Fare", visible=True)
plt.show()

image

Is the "visibility logic" still needed? Or can we remove it and just use matplotlib rc settings for this?

Versions:

  • seaborn==0.13.0
  • matplotlib==3.8.0

JanPalasek avatar Oct 18 '23 13:10 JanPalasek

Agreed that this is an edge case. The visibility logic is needed to avoid ending up with interior axis labels on a facetgrid (or other shared-axes plot). The current solution is more or less a hack, so maybe it's not the best approach, but the problem itself still needs solving.

BTW you can also call ax.set(xticks=[], yticks=[]) after plotting and that won't un-set the axis labels, though of course you need to do it every time unlike with the rcparams.

mwaskom avatar Oct 18 '23 16:10 mwaskom

You could also get creative with your rcparams and eg set the tick (label) size to 0. Just mentioning it as a workaround.

mwaskom avatar Oct 18 '23 18:10 mwaskom

Also flagging that this is not a scatterplot specific issue, most functions go through the relevant codepath here.

mwaskom avatar Oct 28 '23 12:10 mwaskom