0

I was struggling a lot with creating a percentage histogram with seaborn and, recently, I came across this post on github, which was exactly what I was looking for. The argument stat='probability' normalises the data (stat='frequency' will give the same result) and outputs the desired plot. Reproducing the example of the last comment of the post, here's the graph:

tips = sns.load_dataset("tips")
sns.histplot(tips, x="day", hue="sex", stat="probability", multiple="fill", shrink=.8)

percentage histplot

Any ideas whether it is possible to move the legend out? I do not seem to have any access to the legend having tried with ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left'), which disappear the labels. If I try to create new labels, I do not get the color differentiation the hue imposes.

I prefer to avoid an artist or reshaping the original dataframe to use matplotlib. So, any input is very welcomed!

Newbielp
  • 405
  • 2
  • 12
  • As per this [answer](https://stackoverflow.com/a/68849891/7758804) from `seaborn 0.11.2`, just `sns.move_legend(ax, bbox_to_anchor=(1, 1.02), loc='upper left')` – Trenton McKinney Sep 12 '21 at 21:03

1 Answers1

1

As seaborn creates more involved legends, and matplotlib doesn't provide a simple API to manipulate existing legends, the way to move a particular legend can be different for different situations.

In this case, you can access the handles and labels of the existing legend, and use them to create a new legend at the desired location.

import matplotlib.pyplot as plt
import seaborn as sns

tips = sns.load_dataset("tips")
ax = sns.histplot(tips, x="day", hue="sex", stat="probability", multiple="fill", shrink=.8)
ax.legend(handles=ax.legend_.legendHandles, labels=[t.get_text() for t in ax.legend_.texts],
          title=ax.legend_.get_title().get_text(),
          bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()

relocated histplot legend

JohanC
  • 59,187
  • 8
  • 19
  • 45
  • Many thanks @JohanC!! I must familiarise myself with the ```.get_text()``` and ```.get_title()``` methods you used. Any good place you recommend? – Newbielp Mar 15 '21 at 15:50
  • The most educational are probably the official online matplotlib and seaborn tutorials. Specific functions you can find in the manuals and in stackoverflow. The general ideas are much more important than the specific functions. – JohanC Mar 15 '21 at 16:17
  • @ JohanC, I think I have grasped the idea, but I am facing a problem trying to create one common legend for a grid of histplots I created. It'd be great if you could have a look at my piece of code... – Newbielp Mar 30 '21 at 13:00
  • You could add that legend to just one of the plots (e.g. the most central of the rightmost one). – JohanC Mar 30 '21 at 13:52
  • Oh thanks JohanC, I actually found the answer. My main problem was that I could not disappear the legend from each subplot and keep the required information at the same time. But, I finally found the correct code that would disappear the legend of the subplot which is ```g.get_legend().remove()```. I have not understood though why ```g.legend_.remove()``` would not work. – Newbielp Mar 30 '21 at 14:09