0
import matplotlib.pyplot as plt
def plot_arrow(arrow_type):
    if arrow_type == 'good_arrow':
        arrow_color = 'g'
    ar = plt.arrow(x, y, dx , dy, label=arrow_type, fc=arrow_color)
    plt.legend([ar,], [arrow_type,])

The above callback function is used to draw arrows in a plot. I need to add legend to them. These arrows are drawn dynamically. The above code will have only one legend. I tried solutions like this but those do not work for matplotlib.pyplot.arrow

Edit:

Problem: I have two colored arrows but only one legend

Plot example: enter image description here

user009122
  • 125
  • 2
  • 9
  • Can you share some sample output image? – Sheldore Aug 03 '18 at 21:45
  • I've added a link. Not sure why I am not able to embed it – user009122 Aug 03 '18 at 21:52
  • don't draw the legend in this function. instead, return the artists and create the legend in the code block that is calling this function. – Paul H Aug 03 '18 at 21:53
  • This function is a callback. – user009122 Aug 03 '18 at 21:56
  • Is the problem to create a legend for an arrow (actually showing an arrow instead of a rectangle)? Or is it to update a legend? – ImportanceOfBeingErnest Aug 03 '18 at 22:03
  • the problem is to create a new legend. I have two types of arrows but only one legend – user009122 Aug 03 '18 at 22:04
  • You only have one legend entry because you only provide one legend handle to `legend`. To create a legend with two handles, use e.g. `plt.legend([ar, ar2], [arrow_type1, arrow_type2])`. This would require you to store the arrows `ar` and `ar2` somewhere, e.g. in a list outside the callback function. – ImportanceOfBeingErnest Aug 03 '18 at 22:10
  • @ImportanceOfBeingErnest Hmm. I tried avoiding that. This would be called over 1000 times. However I would have only a few colors (5 to 10). Also, I would have multiple arrows of the same color. Would maintaining list of arrows draw a legend for each arrow and not each color? I have updated the image – user009122 Aug 03 '18 at 22:20
  • You would need some logic to produce the list of handles you want to appear in the legend. `numpy.unique()` can come handy for such purposes. – ImportanceOfBeingErnest Aug 03 '18 at 22:28
  • Okay. So storing the list of handles is probably the only way? – user009122 Aug 03 '18 at 22:30
  • No, you can in principle recover them from the axes each time the callback is called. That is for sure much more complicated and expensive though, so I did not propose it. – ImportanceOfBeingErnest Aug 03 '18 at 22:55

1 Answers1

2

Why not just use quiver() in your case? See here.

enter image description here

import matplotlib.pyplot as plt
import numpy as np

plt.figure()

def rand(n):
    return 2.0*np.random.rand(n)-1.0

def plt_arrows(n, c, l, xpos, ypos):
    X, Y = rand(n), rand(n)
    U, V = 4.*rand(n), 4.*rand(n)
    Q = plt.quiver(X, Y, U, V, angles="xy", scale=30, label=l, color=c)
    qk = plt.quiverkey(Q, xpos, ypos, 2, label=l, labelpos='N', labelcolor=c)

plt_arrows(20, "g", "good", 1.05, 0.9)
plt_arrows(20, "r", "bad", 1.05, 0.8)

plt.show()
Gilfoyle
  • 3,282
  • 3
  • 47
  • 83
  • Thanks Samuel. I would have arrows in the order of 100. So I would want a legend for a color as opposed to each arrow. And also I was trying to avoid storing handles. My function is a callback – user009122 Aug 03 '18 at 22:22