【问题标题】:How to create a draggable legend in matplotlib?如何在 matplotlib 中创建可拖动的图例?
【发布时间】:2011-02-02 03:02:21
【问题描述】:

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

【问题讨论】:

  • Adam:考虑到这是实质性的、彻底的和相关的,足以包含在 Matplotlib 发行版中,并且考虑到(我认为)你删除了原来的问题,你介意在此 Q 的顶部,以便用户了解此代码的用途(以使他们不必阅读代码本身)。干得好,顺便说一下我 +1。
  • 谢谢道格。我按照您的建议在顶部提出了问题。希望这会有所帮助。 :]
  • 这可以扩展到辅助轴吗?

标签: python matplotlib draggable legend


【解决方案1】:

注意:这现在已内置到 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,亚当 弗雷泽 写道:

我想我会分享一个解决可拖动图例问题的方法,因为 我花了很长时间才能吸收所有零散的知识 邮件列表...

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

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

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

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

【讨论】:

  • 请注意,这是一个很棒但非常旧的版本,您最好使用 set_draggable(请参阅下面的my answer
【解决方案2】:

在较新版本的 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)

【讨论】:

    【解决方案3】:

    在较新的版本 (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)
    

    【讨论】:

    • 为什么这不是默认设置对我来说是个谜。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    相关资源
    最近更新 更多