简体   繁体   中英

How to move figure-level matplotlib legend to axes of a seaborn displot

I am calling sns.displot to get a FacetGrid

g = sns.displot(
    data=df_all,
    x='a_number',
    hue='a_condition',
    row='a_factor',
    col='another_factor',
    stat="density", 
    common_norm=False,
    element='step',
    palette=palette,
)

Similar to this question, I want to place the automatically-generated legend on one of the axes, instead of outside them as a figure-level legend: How to put the legend on first subplot of seaborn.FacetGrid?

Just calling g.fig.axes[row][col].legend() does not work:

No handles with labels found to put in legend.

So I should generate the handles and labels? I looked at how Grid.add_legend does this and it seems to be some magic that would require me knowing a lot more about how the class works to reproduce it (maybe I am wrong). There's also no _legend_data I can use to dynamically recreate the legend in the same way that the Grid.add_legend method does.

>>> g._legend_data

{}

The "easy" (lazy?) way would be if I could somehow copy the legend instance, add that copy to the axes I want, and then call g.fig._legend.remove() (unless anyone has any better ideas)

I can't figure out how to copy the legend and then assign it to a specific Axes .

It dawned on me I could just call g.legend.set_bbox_to_anchor() as a workaround.

In this case the legend is still figure-level but it lets me get it where I want it.

edit:
@mwaskom replied with a link to this comment on a GitHub issue, that has a code snippet that does what I had in mind:
https://github.com/mwaskom/seaborn/issues/2280#issuecomment-692350136

for my purposes I tweaked it like so

def move_legend(g, ax, new_loc, **kws):
    old_legend = g.legend
    handles = old_legend.legendHandles
    labels = [t.get_text() for t in old_legend.get_texts()]
    title = old_legend.get_title().get_text()
    ax.legend(handles, labels, loc=new_loc, title=title, **kws)

move_legend(g, g.fig.axes[-2], "upper right")
g.legend.remove()

relevant discussion of what's going on under the hood is on that issue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM