'Move the legend for xarray plot lines in python

I'm using xarray in python to plot a DataArray with several panels containing each of them plotting several lines (hue). By default, the location of the legend is set on the right of the panels. I'm trying to find a way to move it to the top or bottom of the panels.

I have no issue doing that with plot.pcolormesh, as the argument cbar_kwargs={'orientation': 'horizontal'} works well, but does it exist something similar with plot.line()? I've looked at the documentation and I couldn't find anything regarding that.

As an example, this is code I use (it is very straightforwards):

p = dataArray.plot.line(
    y="z",
    hue="source",
    col="t",
    col_wrap=4,
)
plt.gca().invert_yaxis()
plt.draw()
plt.show()

Which produces this figure.

Thanks for your help.

Edit. Following advises from somewhere else, I explored a bit the problem.

Xarray creates a FacetGrid object (from seaborn lib). This object contains a function to automatically add a legend (which is used by xarray) to expand the figure with a right panel where the legend object is drawn. I figured out how to access this object (p.figlegend) which itself has the attribute set_bbox_to_anchor which indeed allows to move the legend... but only relative to this additional panel.

Now that I have the legend object, I could totally move it where ever I want, but this is not really the option I was looking for. Firstly, if I do that I will have to create the legend object from scratch, which is what I wanted to avoid by using xarray automatic line plot, secondly I will have a small empty panel on the right of my figure. At this point creating the figure from subplot & making the panels one by one would be easier.

I think my issue could be simply reduced to: is it possible to have a FacetGrid object that draw the legend under or over the figure instead of on the right? If not, there is probably no simple way to do what I want to do.



Solution 1:[1]

I don't have your data but this should work:

p = dataArray.plot.line(
    y="z",
    hue="source",
    col="t",
    col_wrap=4,
add_legend=False
)
p.add_legend(bbox_to_anchor=(0.5, -.05),
          ncol=5)

You don't automatically create the legend, so you put add_legend=False in the call of plot.line() but then you add it and pass your options. You will need to play with bbox_to_anchor location, and with ncol. I put 5 because in the example you gave you had 5 lines.

the horizontal option is available in pcolormesh because that is a colorbar, not a legend. In fact, even outside of xarray you don't have a horizontal option for the legend, if I am not mistaken, you have it only for a colorbar.

Hope this helps!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 claude