Comment créer une légende dans matplotlib?

je dessine une légende sur un objet axes dans matplotlib mais le positionnement par défaut qui prétend le placer dans un endroit intelligent ne semble pas fonctionner. Idéalement, j'aimerais que la légende soit glissée par l'utilisateur. Comment cela peut-il être fait?

37
demandé sur Juha 2010-03-29 20:15:47

2 réponses

Note: Ceci est maintenant intégré dans matplotlib

leg = plt.legend()
if leg:
    leg.draggable()

fonctionne


Bien, j'ai trouvé des morceaux de la solution dispersés parmi les listes de diffusion. J'ai trouvé un joli morceau de code modulaire que vous pouvez utiliser... ici, c'est:

class DraggableLegend:
    def __init__(self, legend):
        self.legend = legend
        self.gotLegend = False
        legend.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)
        legend.figure.canvas.mpl_connect('pick_event', self.on_pick)
        legend.figure.canvas.mpl_connect('button_release_event', self.on_release)
        legend.set_picker(self.my_legend_picker)

    def on_motion(self, evt):
        if self.gotLegend:
            dx = evt.x - self.mouse_x
            dy = evt.y - self.mouse_y
            loc_in_canvas = self.legend_x + dx, self.legend_y + dy
            loc_in_norm_axes = self.legend.parent.transAxes.inverted().transform_point(loc_in_canvas)
            self.legend._loc = tuple(loc_in_norm_axes)
            self.legend.figure.canvas.draw()

    def my_legend_picker(self, legend, evt): 
        return self.legend.legendPatch.contains(evt)   

    def on_pick(self, evt): 
        if evt.artist == self.legend:
            bbox = self.legend.get_window_extent()
            self.mouse_x = evt.mouseevent.x
            self.mouse_y = evt.mouseevent.y
            self.legend_x = bbox.xmin
            self.legend_y = bbox.ymin 
            self.gotLegend = 1

    def on_release(self, event):
        if self.gotLegend:
            self.gotLegend = False

...et dans votre code...

def draw(self): 
    ax = self.figure.add_subplot(111)
    scatter = ax.scatter(np.random.randn(100), np.random.randn(100))


legend = DraggableLegend(ax.legend())

j'ai envoyé un e-mail au groupe des utilisateurs de Matplotlib et John Hunter a eu la gentillesse d'ajouter ma solution it à SVN TÊTE.

on Thu, Jan 28, 2010 at 3: 02 PM, Adam Fraser a écrit:

j'ai pensé que je partagerais une solution au problème de la légende traînante depuis il m'a fallu une éternité pour assimiler tous les savoirs épars sur le les listes de diffusion...

Cool -- bel exemple. J'ai ajouté le code à legend.py. Maintenant vous pouvez faire

jambe = ax.légende()

jambe.draggable ()

pour activer le mode draggable. Vous pouvez appelle ce func à plusieurs reprises pour basculer selection de l'état.

j'espère que cela sera utile aux personnes qui travaillent avec matplotlib.

28
répondu Adam Fraser 2015-10-01 05:05:15

dans les nouvelles versions de Matplotlib (v1.0.1), Ceci est intégré.

def draw(self): 
    ax = self.figure.add_subplot(111)
    scatter = ax.scatter(np.random.randn(100), np.random.randn(100))
    legend = ax.legend()
    legend.draggable(state=True)

si vous utilisez matplotlib de manière interactive (par exemple, en mode pylab D'IPython).

plot(range(10), range(10), label="test label")
plot(range(10), [5 for x in range(10)], label="another test")
l = legend()
l.draggable(True)
13
répondu Tim Swast 2011-09-19 21:25:50