88

これは非常に単純化された例です。

xvalues = [2,3,4,6]

for x in xvalues:
    plt.axvline(x,color='b',label='xvalues')

plt.legend()

ここに画像の説明を入力してください

凡例には、凡例に「xvalues」が青い線として4回表示されます。これを修正するためのよりエレガントな方法は次のものよりもありますか?

for i,x in enumerate(xvalues):
    if not i:
        plt.axvline(x,color='b',label='xvalues')
    else:
        plt.axvline(x,color='b')

ここに画像の説明を入力してください

4

6 に答える 6

156

plt.legendパラメータとして取る

  1. Artistオブジェクトである軸ハンドルのリスト
  2. 文字列であるラベルのリスト

これらのパラメータはどちらもオプションのデフォルトであり、plt.gca().get_legend_handles_labels()。を呼び出す前に辞書に入れることで、重複するラベルを削除できますlegend。これは、dictが重複するキーを持つことができないためです。

例えば:

Pythonバージョン<3.7の場合

from collections import OrderedDict
import matplotlib.pyplot as plt

handles, labels = plt.gca().get_legend_handles_labels()
by_label = OrderedDict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())

Pythonバージョン>3.7の場合

Python 3.7以降、辞書はデフォルトで入力順序を保持します。OrderedDictしたがって、コレクションモジュールを作成する必要はありません。

import matplotlib.pyplot as plt

handles, labels = plt.gca().get_legend_handles_labels()
by_label = dict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())

ここに画像の説明を入力してください

ドキュメントplt.legend

于 2012-11-27T16:53:49.217 に答える
8
handles, labels = ax.get_legend_handles_labels()
handle_list, label_list = [], []
for handle, label in zip(handles, labels):
    if label not in label_list:
        handle_list.append(handle)
        label_list.append(label)
plt.legend(handle_list, label_list)
于 2014-10-24T14:54:02.807 に答える
4

これが「エレガント」と見なすことができるかどうかはわかりませんが、ラベルを"_nolegend_"最初の使用後に設定される変数にすることができます。

my_label = "xvalues"
xvalues = [2,3,4,6]

for x in xvalues:
    plt.axvline(x, color='b', label=my_label)
    my_label = "_nolegend_"

plt.legend()

複数のラベルを付ける必要がある場合は、ラベルの辞書を使用してこれを一般化できます。

my_labels = {"x1" : "x1values", "x2" : "x2values"}
x1values = [1, 3, 5]
x2values = [2, 4, 6]

for x in x1values:
    plt.axvline(x, color='b', label=my_labels["x1"])
    my_labels["x1"] = "_nolegend_"
for x in x2values:
    plt.axvline(x, color='r', label=my_labels["x2"])
    my_labels["x2"] = "_nolegend_"

plt.legend()

2つの異なるラベルが付いた図

( https://stackoverflow.com/a/19386045/1878788に触発された回答)

于 2016-12-19T17:56:00.997 に答える
3

問題-3Dアレイ

質問:2012年11月2013年10月

import numpy as np
a = np.random.random((2, 100, 4))
b = np.random.random((2, 100, 4))
c = np.random.random((2, 100, 4))

解決策-独自性を決定する

私の場合_nolegend_bliDSM)は機能せず、機能しませんlabel if i==0ecatmurの答えはget_legend_handles_labels、凡例を使用して縮小しcollections.OrderedDictます。 Fonsは、これがインポートなしで可能であることを示しています。

これらの答えに沿って、私はdictユニークなラベルに使用することをお勧めします。

# Step-by-step
ax = plt.gca()                      # Get the axes you need
a = ax.get_legend_handles_labels()  # a = [(h1 ... h2) (l1 ... l2)]  non unique
b = {l:h for h,l in zip(*a)}        # b = {l1:h1, l2:h2}             unique
c = [*zip(*b.items())]              # c = [(l1 l2) (h1 h2)]
d = c[::-1]                         # d = [(h1 h2) (l1 l2)]
plt.legend(*d)

または

plt.legend(*[*zip(*{l:h for h,l in zip(*ax.get_legend_handles_labels())}.items())][::-1])

Matthew Bourqueのソリューション よりも、読みにくく、記憶に残るものではないかもしれません。コードゴルフへようこそ。

import numpy as np
a = np.random.random((2, 100, 4))
b = np.random.random((2, 100, 4))

import matplotlib.pyplot as plt
fig, ax = plt.subplots(1)
ax.plot(*a, 'C0', label='a')
ax.plot(*b, 'C1', label='b')

ax.legend(*[*zip(*{l:h for h,l in zip(*ax.get_legend_handles_labels())}.items())][::-1])
# ax.legend()   # Old,  ^ New

plt.show()
于 2019-08-21T22:50:26.747 に答える
2

回答https://stackoverflow.com/a/13589144/9132798https://stackoverflow.com/a/19386045/9132798 に基づいてplt.gca().get_legend_handles_labels()[1]名前のリストが表示され、ラベルがすでにリストにあるかどうかを確認できます。ループプロット(label= name[i] if name[i] not in plt.gca().get_legend_handles_labels()[1] else '')。与えられた例では、このソリューションは次のようになります。

import matplotlib.pyplot as plt

xvalues = [2,3,4,6]

for x in xvalues:
    plt.axvline(x,color='b',\
    label= 'xvalues' if 'xvalues' \
            not in plt.gca().get_legend_handles_labels()[1] else '')

plt.legend()

これはhttps://stackoverflow.com/a/13589144/9132798よりもはるかに短く、 https://stackoverflow.com/a/19386045/9132798よりも柔軟性があります。これは、あらゆる種類のループに使用できるため、個別にループします。ただし、多くのサイクルでは、おそらくhttps://stackoverflow.com/a/13589144/9132798よりも遅くなります。

于 2017-12-23T02:19:12.237 に答える
1

これらのコードスニペットは、個人的には機能しませんでした。私は2つの異なるグループを2つの異なる色でプロットしていました。色ごとに1つだけ表示したい場合、凡例には2つの赤いマーカーと2つの青いマーカーが表示されます。私のために働いたものの簡略化されたバージョンを貼り付けます:

ステートメントのインポート

import matplotlib.pyplot as plt

from matplotlib.legend_handler import HandlerLine2D

データをプロットする

points_grp, = plt.plot(x[grp_idx], y[grp_idx], color=c.c[1], marker=m, ms=4, lw=0, label=leglab[1])        
points_ctrl, = plt.plot(x[ctrl_idx], y[ctrl_idx], color=c.c[0], marker=m, ms=4, lw=0, label=leglab[0])

凡例を追加

points_dict = {points_grp: HandlerLine2D(numpoints=1),points_ctrl: HandlerLine2D(numpoints=1)}
leg = ax.legend(fontsize=12, loc='upper left', bbox_to_anchor=(1, 1.03),handler_map=points_dict)
于 2015-12-21T00:29:13.273 に答える