0

I have seen many good questions questions and answers, but I am not sure how to combine two of them:

These two questions have great answers, but I am unable to do both at the same time! Putting both code into a single function doesn't work:

def func():

  ...

  # revome duplicate legends
  legend(ax)

  plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))

# remove duplicate legends
def legend(ax):
    handles, labels = ax.get_legend_handles_labels()
    unique = [(h, l) for i, (h, l) in enumerate(zip(handles, labels)) if l not in labels[:i]]
    ax.legend(*zip(*unique))

I tried putting the code plt.legend(...) before and after legend(ax):

  • Putting the remove duplicate function before moving it outside of the plot area results in the legend being moved outside of the plot area, but does not remove any duplicate legends: enter image description here

  • Removing the duplicate legends before moving the legends outside of the plot area for some reason also does not move the legend out of the plot area, but it removes the duplicate legends! enter image description here

How do I fix this to not only move the legend out of the plot area, and remove any duplicate legends?

DialFrost
  • 1,610
  • 1
  • 8
  • 28
  • Does this answer your question? [Is there any difference between plt.legend and ax.legend in matplotlib?](https://stackoverflow.com/questions/49020745/is-there-any-difference-between-plt-legend-and-ax-legend-in-matplotlib) – MisterMiyagi Aug 11 '22 at 12:56
  • No @MisterMiyagi, it doesn't really provide any information on how to solve my problem I think. If i misread or misunderstood anything, please let me know! – DialFrost Aug 11 '22 at 12:57
  • 1
    Both `plt.legend` and `ax.legend` are effectively the same, so each is going to override whatever you did with the previous call. You must combine the calls into one, not repeat them one after the other. – MisterMiyagi Aug 11 '22 at 12:58
  • @MisterMiyagi Oh whoops! Fixed, but the problem still occurs unfortunately (I changed everything to `ax.legend`), and how do I combine those two? – DialFrost Aug 11 '22 at 13:01
  • 1
    The point is that you must make only *one* call to `XYZ.legend`, no matter what `XYZ` is. – MisterMiyagi Aug 11 '22 at 13:01

1 Answers1

0

Credits to @MisterMiyagi for helping me out

I had two errors in my code:

  1. I used both plt.legend and ax.legend, so they overlapped each other
  2. However that still doesn't fix the problem, I also had to make sure when running ax.legend, it had to be in one command, not multiple as they would override each other!

This will work:

def func():

  ...

  # revome duplicate legends
  legend(ax)

# remove duplicate legends
def legend(ax):
    handles, labels = ax.get_legend_handles_labels()
    unique = [(h, l) for i, (h, l) in enumerate(zip(handles, labels)) if l not in labels[:i]]
    ax.legend(*zip(*unique), loc='center left', bbox_to_anchor=(1, 0.5))
DialFrost
  • 1,610
  • 1
  • 8
  • 28