42

matplotlibのaxesオブジェクトに凡例を描画していますが、スマートな場所に配置すると主張するデフォルトの配置が機能していないようです。理想的には、凡例をユーザーがドラッグできるようにしたいです。これはどのように行うことができますか?

4

3 に答える 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グループに電子メールを送りましたが、JohnHunterは親切にも私のソリューションをSVNHEADに追加してくれました。

2010年1月28日木曜日午後3時2分、AdamFraserは次のように書いています。

メーリングリストに散らばっているすべての知識を吸収するのに永遠に時間がかかったので、ドラッグ可能な凡例の問題の解決策を共有したいと思いました...

かっこいい-いい例です。私は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 に答える