これは非常に単純化された例です。
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')
legend
は、引数として軸ハンドルとラベルのリストを取ります。デフォルトはplt.gca().get_legend_handles_labels()
です。 legend
を呼び出すときに、重複するラベルを削除できます。次に例を示します。
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())
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)
これらのコードスニペットは個人的には機能しませんでした。 2つの異なるグループを2つの異なる色でプロットしました。凡例には、2つの赤いマーカーと2つの青いマーカーが表示されますが、色ごとに1つしか見たくありませんでした。私がうまくいったことの簡略版を貼り付けます:
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)
これが「エレガント」と見なされるかどうかはわかりませんが、最初の使用後に"_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()
( https://stackoverflow.com/a/19386045/1878788 に触発された回答)
回答に基づいて https://stackoverflow.com/a/13589144/9132798 および https://stackoverflow.com/a/19386045/9132798plt.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 よりも遅くなります。