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

Ada*_*ser 40 python matplotlib legend draggable

我在matplotlib中的轴对象上绘制了一个图例,但声称将其置于智能位置的默认定位似乎不起作用.理想情况下,我希望用户可以拖动图例.如何才能做到这一点?

Ada*_*ser 30

注意:现在内置于matplotlib中

leg = plt.legend()
if leg:
    leg.draggable()
Run Code Online (Sandbox Code Playgroud)

将按预期工作


好吧,我发现解决方案的各个部分分散在邮件列表中.我想出了一个很好的模块化代码块,你可以放入并使用......这里是:

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
Run Code Online (Sandbox Code Playgroud)

......并在你的代码中......

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


legend = DraggableLegend(ax.legend())
Run Code Online (Sandbox Code Playgroud)

我通过电子邮件发送了Matplotlib用户组,John Hunter非常友好地将我的解决方案添加到SVN HEAD.

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

我以为我会分享一个解决这个可拖延的传奇问题的方案,因为我花了很长时间才能吸收邮件列表上所有分散的知识......

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

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

启用可拖动模式.您可以重复调用此函数来切换可拖动状态.

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

  • 请注意,这是一个很棒的版本,但确实是旧版本,您最好使用set_draggable(请参阅下面的[我的回答](/sf/answers/3760259681/)) (2认同)

Tim*_*ast 14

在较新版本的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)
Run Code Online (Sandbox Code Playgroud)

如果您以交互方式使用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)
Run Code Online (Sandbox Code Playgroud)


bor*_*rgr 12

在更新的版本 (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)
Run Code Online (Sandbox Code Playgroud)

  • 对我来说,这是一个谜,为什么这不是默认值。 (2认同)