0

I know there are similar answers such as this one, but that one applies to seaborn's boxplot and it's not working for me with seaborn's factorplot. On a simple factorplot:

import seaborn as sns

tips = sns.load_dataset("tips")

means = tips.groupby(["sex","smoker","time"])["tip"].mean().values
means_labels = [str(int(s)) for s in means]

with sns.plotting_context("notebook",font_scale=2):
    g = sns.factorplot(x="sex", y="total_bill", hue="smoker",\
                   col="time",  data=tips, kind="box", size=6, aspect=.7)

How can one add an annotation (in the example above, the means_labels) below each box, like this:

enter image description here

As I said, I tried using the answer above to at least try to get the position of each box:

import matplotlib.pyplot as plt
ax = plt.gca()
pos = range(len(means))
for tick,label in zip(pos,ax.get_xticklabels()):
        ax.text(pos[tick], means[tick] + 0.5, meanslabels[tick], 
               horizontalalignment='center', color='r', weight='semibold')

But this produces:

enter image description here

I believe this is because I'm passing the whole plot's axes instead of the "factorplot" axes. But I couldn't find a way to do so (if instead of ax=plt.gca() I use, like in the example, ax=sns.factorplot(...), I get the error: AttributeError: module 'seaborn' has no attribute 'gca').

lanadaquenada
  • 395
  • 3
  • 4
  • 26
  • No this is because you pass `ax.get_xticklabels()`, so the first number is at the position of the first ticklabel, the second number at the position of the second ticklabel, for the third number there is no ticklabel anymore... You may instead try to get the boxes and loop over their positions, e.g. `ax.patches[i].get_x()`. – ImportanceOfBeingErnest Apr 28 '18 at 00:35
  • @ImportanceOfBeingErnest I cannot find a way to loop through all the boxes. `ax.patches` when `ax = plt.gca()` contains only 2 items. The only attribute I see in `plt.gca()` with more than 2 values is `lines` with 24 values and `artists` with 4, but I don't see any attribute on `ax.artists[i]` that would give me the x/y position. – lanadaquenada May 02 '18 at 15:55
  • I see. It's really hard to label such black box plot produced by seaborn. You can use the `artists`, get the path and take the mean of the vertices as x value, `np.mean(g.axes[0,0].artists[0].get_path().vertices[:2,0])`. I just fear that this will not help too much because you still need to know which data corresponds to which box. You might be better off with a solution like [here](https://stackoverflow.com/questions/45849028/seaborn-facetgrid-pointplot-label-data-points), mapping a custom function, which includes the annotations. But I currently don't know how to handle the hue in such case. – ImportanceOfBeingErnest May 02 '18 at 18:50

0 Answers0