我正在 matplotlib 中的轴对象上绘制图例,但声称将其放置在智能位置的默认定位似乎不起作用。理想情况下,我希望用户可以拖动图例。如何才能做到这一点?
问问题
12028 次
3 回答
30
注意:这现在内置在 matplotlib 中
leg = plt.legend()
if leg:
leg.draggable()
将按预期工作
好吧,我在邮件列表中发现了一些零散的解决方案。我提出了一个很好的模块化代码块,你可以放入并使用它......这里是:
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-users 组发送了电子邮件,John Hunter 很友好地将我的解决方案添加到 SVN HEAD。
2010 年 1 月 28 日星期四下午 3:02,Adam Fraser 写道:
我想我会分享一个解决可拖动图例问题的方法,因为我花了很长时间才能吸收邮件列表上所有分散的知识......
酷——很好的例子。我将代码添加到legend.py。现在你可以做
leg = ax.legend()
leg.draggable()启用可拖动模式。您可以重复调用此函数来切换可拖动状态。
我希望这对使用 matplotlib 的人有所帮助。
于 2010-03-30T14:50:24.877 回答
15
在较新版本的 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)
于 2011-09-19T21:25:50.993 回答
14
在更新的版本(3.0.2)中,它已被弃用,并且可能会在未来的版本中代表一个属性(因此,它不会是可调用的)。
plot(range(10), range(10), label="test label")
plot(range(10), [5 for x in range(10)], label="another test")
plt.legend().set_draggable(True)
于 2018-12-11T05:37:11.643 回答