2013-10-15 24 views
16

私はこのスニペットを私のプロットに凡例を追加しようとしています:matplotlibの凡例に重複している項目はありますか?

import matplotlib.pylab as plt 

fig = plt.figure() 
axes = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # left, bottom, width, height (range 0 to 1) 
axes.set_xlabel('x (m)') 
axes.set_ylabel('y (m)') 
for i, representative in enumerate(representatives): 
    axes.plot([e[0] for e in representative], [e[1] for e in representative], color='b', label='Representatives') 
axes.scatter([e[0] for e in intersections], [e[1] for e in intersections], color='r', label='Intersections') 
axes.legend() 

私はこのプロットは明らか

enter image description here

で終わる、項目がプロットに複製されます。このエラーを修正するにはどうすればよいですか?

+0

これはエラーではありません。ラベルが同じであるため、多くの繰り返しエントリが追加されています。 forループ内のラベルを変更する必要がある場合は... –

+2

ここにあなたの質問に対する素晴らしい答えがあります:http://stackoverflow.com/questions/13588920/stop-matplotlib-repeating-labels-in-legend –

答えて

28

は、言う:

label属性が空の文字列であるか、無視されます これらのアーティスト、「_」で始まる場合。

私はループに似たラインをプロットしていると私は唯一の伝説の1例ラインをしたいのであれば、私は通常

iは私のループインデックスです
ax.plot(x, y, label="Representatives" if i == 0 else "") 

ような何かを行います。

別々にビルドするのは面倒ではありませんが、しばしば、ラベルロジックを可能な限り線図に近づけたいと考えています。

matplotlib開発者自身が明示的であることを"_nolegend_"を使用する傾向があることに注意してください。)

+0

良い洞察力。 i == 0は本当にトリックです。しかし、散乱事はi == 0で解くことはできません。なぜなら、ループ内にないからです。私はそれを完璧にするためにどのように進むことができますか? http://i.stack.imgur.com/B3osh.jpg –

+0

@mavErick:申し訳ありませんが、私はフォローしていません。伝説には「交差点」の行が1つしかありません。 – DSM

+0

はい、正確です。しかし、なぜ私は伝説の中に3つの赤い点がありますか? 1つではいけませんか? –

2

これはエラーではありません。 forループ内のラベルには、反復ラベルlen(representatives)-1が凡例に追加されています。何の代わりにあなたが

for i, representative in enumerate(representatives): 
    rep, = axes.plot([e[0] for e in representative], [e[1] for e in representative], color='b') 
inter = axes.scatter([e[0] for e in intersections], [e[1] for e in intersections], color='r') 
axes.legend((rep, inter), ("Representatives", "Intersections")) 

編集のような何かをした場合:以下のコードのフォーマットはmatplotlib legend tutorialに掲載のフォーマットを使用しています。上記のコードが失敗した理由は、rep, =の後にカンマがないためです。各反復repは上書きされ、を呼び出すために使用されるときは、最後の代表プロットのみがrepに格納されます。

fig = plt.figure() 
ax = fig.add_subplot(111) 
for i, representative in enumerate(representatives): 
    rep, = ax.plot([e[0] for e in representative], [e[1] for e in representative], color='b') 
inter = ax.scatter([e[0] for e in intersections], [e[1] for e in intersections], color='r') 
ax.legend((rep, inter), ("Representatives", "Intersections")) 

また、あなたはOPで行う方法あなたのデータをプロットしてみてくださいしかし

handles, labels = ax.get_legend_handles_labels() 

使用しhandleslabelsの内容を編集伝説を作ることができます。欠場するのは簡単ですが、docsとして

4

ここでは、すでに正常にラベルを割り当てた後、重複凡例エントリを削除する方法です:

representatives=[[[-100,40],[-50,20],[0,0],[75,-5],[100,5]], #made up some data 
       [[-60,80],[0,85],[100,90]], 
       [[-60,15],[-50,90]], 
       [[-2,-2],[5,95]]] 
fig = plt.figure() 
axes = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # left, bottom, width, height (range 0 to 1) 
axes.set_xlabel('x (m)') 
axes.set_ylabel('y (m)') 
for i, representative in enumerate(representatives): 
    axes.plot([e[0] for e in representative], [e[1] for e in representative],color='b', label='Representatives') 
#make sure only unique labels show up (no repeats) 
handles,labels=axes.get_legend_handles_labels() #get existing legend item handles and labels 
i=arange(len(labels)) #make an index for later 
filter=array([]) #set up a filter (empty for now) 
unique_labels=tolist(set(labels)) #find unique labels 
for ul in unique_labels: #loop through unique labels 
    filter=np.append(filter,[i[array(labels)==ul][0]]) #find the first instance of this label and add its index to the filter 
handles=[handles[int(f)] for f in filter] #filter out legend items to keep only the first instance of each repeated label 
labels=[labels[int(f)] for f in filter] 
axes.legend(handles,labels) #draw the legend with the filtered handles and labels lists 

そして、ここでは結果があります: enter image description here 左は上記のスクリプトの結果です。右側では、伝言通話はaxes.legend()に置き換えられています。

利点は、ほとんどのコードを通り、通常はラベルを割り当て、インラインループやifを心配する必要がないことです。また、これを凡例などのラッパーに組み込むこともできます。

+0

これはありがとうございました。これは、行の追加の背後にあるロジックを修正することなく、簡単な修正を提供しました。 – Haboryme

関連する問題