如何在matplotlib中创建可拖动的图例? [英] How to create a draggable legend in matplotlib?

查看:532
本文介绍了如何在matplotlib中创建可拖动的图例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在matplotlib中的axis对象上绘制图例,但是声称将其放置在智能位置的默认位置似乎不起作用.理想情况下,我希望图例可由用户拖动.该怎么办?

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?

推荐答案

注意:现在已内置到matplotlib中

Note: This is now built into matplotlib

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

将按预期工作

好吧,我发现解决方案的点点滴滴散布在邮件列表中.我想出了一个不错的模块化代码块,您可以插入并使用...在这里:

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())

我通过电子邮件发送给Matplotlib-users组,约翰·亨特(John Hunter)很友好,可以将我的解决方案添加到SVN HEAD.

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

2010年1月28日,星期四,亚当 弗雷泽 写道:

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...

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

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

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

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

启用可拖动模式.你可以 反复调用此功能进行切换 可拖动状态.

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

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

I hope this is helpful to people working with matplotlib.

这篇关于如何在matplotlib中创建可拖动的图例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆