Cómo crear una leyenda arrastrable en matplotlib?


Estoy dibujando una leyenda en un objeto axes en matplotlib, pero el posicionamiento predeterminado que afirma colocarlo en un lugar inteligente no parece funcionar. Idealmente, me gustaría que la leyenda sea arrastrable por el usuario. ¿Cómo se puede hacer esto?

Author: Juha, 2010-03-29

2 answers

Nota: Esto ahora está integrado en matplotlib

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

Funcionará como se espera


Bueno, encontré partes y piezas de la solución dispersas entre las listas de correo. Se me ocurrió un buen fragmento modular de código que puedes usar... aquí 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

...y en tu código...

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


legend = DraggableLegend(ax.legend())

Envié un correo electrónico al grupo Matplotlib-users y John Hunter tuvo la amabilidad de agregar mi solución a SVN HEAD.

El jueves, 28 de enero de 2010 a las 3: 02 PM, Adam Fraser escribió:

Pensé en compartir una solución al problema de la leyenda arrastrable desde me tomó una eternidad asimilar todo el conocimiento disperso en el listas de correo...

Genial nice buen ejemplo. He añadido el código a legend.py. Ahora usted puede hacer

Pierna = hacha.leyenda()
pierna.arrastrable ()

Para habilitar el modo arrastrable. Puedes llame repetidamente a este func para alternar el estado arrastrable.

Espero esto es útil para las personas que trabajan con matplotlib.

 28
Author: Adam Fraser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-01 05:05:15

En las versiones más recientes de Matplotlib (v1.0.1), esto está integrado.

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 está utilizando matplotlib interactivamente (por ejemplo, en el modo pylab de 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
Author: Tim Swast,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-09-19 21:25:50