2013-10-15 18 views
16

Tôi cố gắng để thêm khẳng định truyền thuyết âm mưu của tôi với đoạn này:Các mục trùng lặp trong chú giải trong 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() 

tôi kết thúc với âm mưu này

enter image description here

Rõ ràng, các mục được nhân đôi trong cốt truyện. Làm thế nào tôi có thể sửa lỗi này?

+0

đây không phải là lỗi, nó đang thêm nhiều mục lặp lại vì nhãn là như nhau. Nếu phải thay đổi nhãn bên trong vòng lặp for ... –

+2

Đây là câu trả lời tuyệt vời cho câu hỏi của bạn: http://stackoverflow.com/questions/13588920/stop-matplotlib-repeating-labels-in-legend –

Trả lời

28

Khi docs nói, mặc dù nó rất dễ dàng để bỏ lỡ:

Nếu thuộc tính label là chuỗi rỗng hoặc bắt đầu với “_”, những nghệ sĩ sẽ bị bỏ qua.

Vì vậy, nếu tôi đang âm mưu dòng tương tự trong một vòng lặp và tôi chỉ muốn dòng một ví dụ trong truyền thuyết, tôi thường làm một cái gì đó giống như

ax.plot(x, y, label="Representatives" if i == 0 else "") 

nơi i là chỉ số vòng lặp của tôi.

Nó không phải là khá tốt đẹp để xem xét như xây dựng chúng một cách riêng biệt, nhưng thường tôi muốn giữ logic nhãn càng gần với bản vẽ dòng càng tốt.

(Lưu ý rằng matplotlib phát triển bản thân có xu hướng sử dụng "_nolegend_" để được rõ ràng.)

+0

Thông tin chi tiết thú vị. I == 0 thực sự là thủ thuật. Nhưng điều phân tán không thể được giải quyết bởi i == 0, vì nó không nằm trong vòng lặp. Làm thế nào tôi có thể tiến hành để làm cho nó hoàn hảo? http://i.stack.imgur.com/B3osh.jpg –

+0

@mavErick: Tôi xin lỗi, tôi không theo dõi. Chỉ có một dòng 'Intersections' trong truyền thuyết. – DSM

+0

Vâng, chính xác. Nhưng tại sao tôi có ba chấm đỏ trong truyền thuyết? Không nên chỉ là một? –

2

Đây không phải là lỗi. Nhãn của bạn bên trong vòng lặp for đang thêm len(representatives)-1 nhãn lặp lại vào chú giải của bạn. Điều gì sẽ xảy ra nếu thay vào đó bạn đã làm điều gì đó như

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")) 

Chỉnh sửa: Định dạng của mã bên dưới sử dụng định dạng được đăng trên matplotlib legend tutorial. Lý do mã trên không thành công do có dấu phẩy bị thiếu sau rep, =. Mỗi lần lặp lại, rep sẽ bị ghi đè và khi được sử dụng để gọi legend, chỉ cốt truyện đại diện mới nhất được lưu trữ trong 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")) 

Bạn cũng có thể thử âm mưu dữ liệu của bạn theo cách bạn làm trong OP của bạn, nhưng làm cho huyền thoại sử dụng

handles, labels = ax.get_legend_handles_labels() 

và chỉnh sửa nội dung của handleslabels.

4

Dưới đây là một phương pháp để loại bỏ các mục huyền thoại nhân đôi sau khi đã gán nhãn thường:

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 

Và đây là kết quả : enter image description here Ở bên trái là kết quả của tập lệnh ở trên. Ở bên phải, cuộc gọi chú thích đã được thay thế bằng axes.legend().

Lợi thế là bạn có thể đi qua hầu hết mã của mình và chỉ gán nhãn bình thường và không lo lắng về vòng lặp nội tuyến hoặc if s. Bạn cũng có thể xây dựng này thành một wrapper xung quanh huyền thoại hoặc một cái gì đó như thế.

+0

Cảm ơn điều này, điều này cung cấp một sửa chữa nhanh chóng mà không cần sửa đổi logic đằng sau việc bổ sung các dòng. – Haboryme

Các vấn đề liên quan