0

I have an sns.pairplot, with the legend outside the axes. No matter how I adjust the bbox_to_anchor, unless I put the right side of the legend inside the axes, the legend would have its left side cut off a bit.

This is how the legend positioned originally:

enter image description here

I can successfully adjust the position of the legend by:

g._legend.set_bbox_to_anchor((1, .53, .0, 0))

enter image description here

And no matter how I move the legend, it is always the same little part of the legend being cutoff. This is really weird. Is this due to some call by:

plt.subplots_adjust(hspace=0.02, wspace=0.04)    

enter image description here

Here are all the commands that I called to adjust the legend:

g._legend.set_title('')
g._legend.set_bbox_to_anchor((1.01, .53, 0, 0))

#new_labels = ['Cluster 1', 'Cluster 2', 'Cluster 3'...]
new_labels = ['Cluster ' + str(i) for i in range(1, len(cluster_data[cluster_col_index].unique()+1))]
for t, l in zip(g._legend.texts, new_labels): t.set_text(l)


for lh in g._legend.legendHandles: 
    lh.set_alpha(1)
    lh._sizes = [70] 

And

g._legend.borderpad=5

also does not work...

Xin Niu
  • 533
  • 1
  • 5
  • 15
  • save the figure with `f.savefig('test.png', bbox_inches='tight')` – Paul H Sep 11 '20 at 00:10
  • @PaulH thanks for your comments but the problem still exists... – Xin Niu Sep 11 '20 at 00:14
  • @XinNiu Cn you try this `fig.add_axes([0.1, 0.1, 0.6, 0.75])` to add space to side of your graph – Karthik Sep 11 '20 at 03:59
  • @Karthik Thanks for your comment, but I used sns.pairplot to create the figure. When I ran g.add_axes(), it says the object does not have the attribute add_axes(). – Xin Niu Sep 11 '20 at 04:29
  • When setting `bbox_to_anchor`, `loc` also needs to be set. See [seaborn relplot: how to control the location of the legend](https://stackoverflow.com/questions/54209895/seaborn-relplot-how-to-control-the-location-of-the-legend-and-add-title). In this case you probably need `g._legend._loc = 'upper left'` (or `2`) see [docs](https://matplotlib.org/3.3.1/api/_as_gen/matplotlib.pyplot.legend.html). – JohanC Sep 11 '20 at 05:35
  • Why are you anchoring the legend to 1.01? If you dont want it cut off, try anchoring inside the figure. – Jody Klymak Sep 11 '20 at 14:12

2 Answers2

2

You can set your own legend. You can set the legend by using plt.legend(). If you want to remove the original legend, enable ax._lengen.remove().

import matplotlib.pyplot as plt
import seaborn as sns
sns.set_theme(style="ticks")

df = sns.load_dataset("penguins")
ax = sns.pairplot(df, hue="species")
# ax._legend.remove()

plt.legend(['Adelie', 'Chinstrap', 'Gentoo'], bbox_to_anchor=(0.9, 0.6))

plt.show()

enter image description here

r-beginners
  • 31,170
  • 3
  • 14
  • 32
0

I just come up with another solution. Just need to add some more space after the legend labels will work.

like to change the code:

new_labels = ['Cluster ' + str(i) for i in range(1, len(cluster_data[cluster_col_index].unique()+1))]
for t, l in zip(g._legend.texts, new_labels): t.set_text(l)

to:

new_labels = ['Cluster ' + str(i) + ' ' for i in range(1, len(cluster_data[cluster_col_index].unique()+1))]
for t, l in zip(g._legend.texts, new_labels): t.set_text(l)
Xin Niu
  • 533
  • 1
  • 5
  • 15