web-dev-qa-db-ja.com

凡例の複数の行ラベルを組み合わせたpyplot

複数の線がプロットされる結果となるデータがあります。凡例でこれらの線に単一のラベルを付けたいと思います。これは、以下の例を使用してよりよく示すことができると思います。

a = np.array([[ 3.57,  1.76,  7.42,  6.52],
              [ 1.57,  1.2 ,  3.02,  6.88],
              [ 2.23,  4.86,  5.12,  2.81],
              [ 4.48,  1.38,  2.14,  0.86],
              [ 6.68,  1.72,  8.56,  3.23]])

plt.plot(a[:,::2].T, a[:, 1::2].T, 'r', label='data_a')

plt.legend(loc='best')

Out [23]でわかるように、プロットは5つの異なる線になりました。結果のプロットは次のようになります legend of multiple line plot

複数のラベルを避けるようにプロット方法を指示する方法はありますか?カスタム凡例(ラベルと線の形状を一度に指定する)をできるだけ使用したくありません。

14
hashmuke

頻繁に行う予定がある場合は、小さなヘルパーを個人的に機能させます。

from matplotlib import pyplot
import numpy


a = numpy.array([[ 3.57,  1.76,  7.42,  6.52],
                 [ 1.57,  1.2 ,  3.02,  6.88],
                 [ 2.23,  4.86,  5.12,  2.81],
                 [ 4.48,  1.38,  2.14,  0.86],
                 [ 6.68,  1.72,  8.56,  3.23]])


def plotCollection(ax, xs, ys, *args, **kwargs):

  ax.plot(xs,ys, *args, **kwargs)

  if "label" in kwargs.keys():

    #remove duplicates
    handles, labels = pyplot.gca().get_legend_handles_labels()
    newLabels, newHandles = [], []
    for handle, label in Zip(handles, labels):
      if label not in newLabels:
        newLabels.append(label)
        newHandles.append(handle)

    pyplot.legend(newHandles, newLabels)

ax = pyplot.subplot(1,1,1)  
plotCollection(ax, a[:,::2].T, a[:, 1::2].T, 'r', label='data_a')
plotCollection(ax, a[:,1::2].T, a[:, ::2].T, 'b', label='data_b')
pyplot.show()

凡例のhandlesおよびlabelsから(現在のものよりも)重複を削除する簡単な(そしてIMOがより明確な)方法は次のとおりです。

handles, labels = pyplot.gca().get_legend_handles_labels()
newLabels, newHandles = [], []
for handle, label in Zip(handles, labels):
  if label not in newLabels:
    newLabels.append(label)
    newHandles.append(handle)
pyplot.legend(newHandles, newLabels)
12
will

上記のwillの応答に基づくNumpyソリューション。

import numpy as np
import matplotlib.pylab as plt
a = np.array([[3.57, 1.76, 7.42, 6.52],
              [1.57, 1.20, 3.02, 6.88],
              [2.23, 4.86, 5.12, 2.81],
              [4.48, 1.38, 2.14, 0.86],
              [6.68, 1.72, 8.56, 3.23]])

plt.plot(a[:,::2].T, a[:, 1::2].T, 'r', label='data_a')
handles, labels = plt.gca().get_legend_handles_labels()

等しいラベルが等しいハンドルを持っていると仮定して、ハンドルインデックスに対応する一意のラベルとそれぞれのインデックスを取得します。

labels, ids = np.unique(labels, return_index=True)
handles = [handles[i] for i in ids]
plt.legend(handles, labels, loc='best')
plt.show()
9
rafaelvalle

だから、意志の提案と別の質問を使用して ここ 、私はここに私の救済策を残しています

handles, labels = plt.gca().get_legend_handles_labels()
i =1
while i<len(labels):
    if labels[i] in labels[:i]:
        del(labels[i])
        del(handles[i])
    else:
        i +=1

plt.legend(handles, labels)

そして、新しいプロットは次のようになります、 modified multiple line plot legend

7
hashmuke

Matplotlibは、行のコレクションへの優れたインターフェイスを提供します LineCollection 。コードは簡単です

import numpy
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

a = numpy.array([[ 3.57,  1.76,  7.42,  6.52],
                 [ 1.57,  1.2 ,  3.02,  6.88],
                 [ 2.23,  4.86,  5.12,  2.81],
                 [ 4.48,  1.38,  2.14,  0.86],
                 [ 6.68,  1.72,  8.56,  3.23]])

xs = a[:,::2]
ys = a[:, 1::2]
lines = LineCollection([list(Zip(x,y)) for x,y in Zip(xs, ys)], label='data_a')
f, ax = plt.subplots(1, 1)
ax.add_collection(lines)
ax.legend()
ax.set_xlim([xs.min(), xs.max()]) # have to set manually
ax.set_ylim([ys.min(), ys.max()])
plt.show()

これにより、以下の出力が得られます。 A plot of the lines collected under a single legend entry.

6
televator

ローテクソリューションは、2つのプロット呼び出しを行うことです。 1つはデータをプロットし、もう1つはハンドルを運ぶだけです。

a = np.array([[ 3.57,  1.76,  7.42,  6.52],
              [ 1.57,  1.2 ,  3.02,  6.88],
              [ 2.23,  4.86,  5.12,  2.81],
              [ 4.48,  1.38,  2.14,  0.86],
              [ 6.68,  1.72,  8.56,  3.23]])

plt.plot(a[:,::2].T, a[:, 1::2].T, 'r')
plt.plot([],[], 'r', label='data_a')

plt.legend(loc='best')

結果は次のとおりです。

result

2
Arthur Bauville

私はこのトリックをします:

for i in range(len(a)):
  plt.plot(a[i,::2].T, a[i, 1::2].T, 'r', label='data_a' if i==0 else None)
1
Chien Nguyen