如何在matplotlib中创build一个可拖动的图例?

我在matplotlib中的轴对象上绘制了一个图例,但声称将它放置在一个聪明的地方的默认位置似乎不工作。 理想情况下,我希望用户可以拖动图例。 如何才能做到这一点?

注意:这是现在内置到matplotlib

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

将按预期工作


那么,我发现在邮件列表中分散的解决scheme。 我已经想出了一个很好的模块化代码块,你可以在这里使用…这里是:

 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 

…在你的代码…

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

我通过电子邮件发送了Matplotlib用户组,John Hunter非常友好,可以将我的解决scheme添加到SVN HEAD中。

在星期四,2010年1月28日下午3:02,亚当弗雷泽写道:

我想我会分享一个可拖动的传奇问题的解决scheme,因为它使我永远消化邮件列表上的所有散布的知识…

酷 – 很好的例子。 我将代码添加到legend.py。 现在你可以做了

leg = ax.legend()
leg.draggable()

启用可拖动模式。 你可以反复调用这个func来切换可拖动的状态。

我希望这对使用matplotlib的人有帮助。

在更新版本的Matplotlib(v1.0.1)中,这是内置的。

 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) 

如果您正在交互使用matplotlib(例如,在IPython的pylab模式下)。

 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)