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

发布于 2024-08-26 14:26:55 字数 85 浏览 7 评论 0原文

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

I'm drawing a legend on an axes object in matplotlib but the default positioning which claims to place it in a smart place doesn't seem to work. Ideally, I'd like to have the legend be draggable by the user. How can this be done?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

对你的占有欲 2024-09-02 14:26:55

注意:现在已内置到 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 用户组发了电子邮件,John Hunter 很友善地告诉我将我的解决方案添加到 SVN HEAD 中。

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

<块引用>

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

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

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

启用可拖动模式。你可以
重复调用此函数进行切换
可拖动状态。

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

Note: This is now built into matplotlib

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

will work as expected


Well, I found bits and pieces of the solution scattered among mailing lists. I've come up with a nice modular chunk of code that you can drop in and use... here it is:

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

...and in your code...

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


legend = DraggableLegend(ax.legend())

I emailed the Matplotlib-users group and John Hunter was kind enough to add my solution it to SVN HEAD.

On Thu, Jan 28, 2010 at 3:02 PM, Adam
Fraser
wrote:

I thought I'd share a solution to the draggable legend problem since
it took me forever to assimilate all the scattered knowledge on the
mailing lists...

Cool -- nice example. I added the code to
legend.py. Now you can do

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

to enable draggable mode. You can
repeatedly call this func to toggle
the draggable state.

I hope this is helpful to people working with matplotlib.

黑寡妇 2024-09-02 14:26:55

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

In even newer versions (3.0.2) it is deprecated and will potentially be representing a property in future versions (hence, it will not be callable).

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)
泛泛之交 2024-09-02 14:26:55

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

In newer versions of Matplotlib (v1.0.1), this is built-in.

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)

If you are using matplotlib interactively (for example, in IPython's pylab mode).

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文