2014-10-25 24 views
15

Tôi muốn tạo một âm mưu phân tán Matplotlib, với chú thích hiển thị màu cho mỗi lớp. Ví dụ: tôi có danh sách các giá trị xy và danh sách các giá trị classes. Mỗi phần tử trong các danh sách x, yclasses tương ứng với một điểm trong cốt truyện. Tôi muốn mỗi lớp có màu riêng của nó, mà tôi đã mã hóa, nhưng sau đó tôi muốn các lớp được hiển thị trong một huyền thoại. Tôi cần chuyển những thông số nào cho hàm legend() để đạt được điều này?Âm mưu phân tán Matplotlib với chú thích

Đây là mã của tôi cho đến nay:

x = [1, 3, 4, 6, 7, 9] 
y = [0, 0, 5, 8, 8, 8] 
classes = ['A', 'A', 'B', 'C', 'C', 'C'] 
colours = ['r', 'r', 'b', 'g', 'g', 'g'] 
plt.scatter(x, y, c=colours) 

Trả lời

9

Trước tiên, tôi có cảm giác bạn có nghĩa là sử dụng dấu nháy, không backticks khi tuyên bố màu sắc.

Đối với chú giải, bạn cần một số hình dạng cũng như các lớp. Ví dụ, sau đây tạo ra một danh sách các hình chữ nhật được gọi là recs cho mỗi màu trong class_colours.

import matplotlib.patches as mpatches 

classes = ['A','B','C'] 
class_colours = ['r','b','g'] 
recs = [] 
for i in range(0,len(class_colours)): 
    recs.append(mpatches.Rectangle((0,0),1,1,fc=class_colours[i])) 
plt.legend(recs,classes,loc=4) 

Output from first code block

Bạn có thể sử dụng vòng tròn quá nếu bạn muốn, chỉ cần kiểm tra các tài liệu matplotlib.patches. Có một cách thứ hai để tạo một chú giải, trong đó bạn chỉ định "Nhãn" cho một tập hợp các điểm bằng cách sử dụng một lệnh phân tán riêng biệt cho mỗi bộ. Một ví dụ về điều này được đưa ra dưới đây.

classes = ['A','A','B','C','C','C'] 
colours = ['r','r','b','g','g','g'] 
for (i,cla) in enumerate(set(classes)): 
    xc = [p for (j,p) in enumerate(x) if classes[j]==cla] 
    yc = [p for (j,p) in enumerate(y) if classes[j]==cla] 
    cols = [c for (j,c) in enumerate(colours) if classes[j]==cla] 
    plt.scatter(xc,yc,c=cols,label=cla) 
plt.legend(loc=4) 

enter image description here

Phương pháp đầu tiên là một trong những cá nhân tôi đã sử dụng, thứ hai tôi chỉ tìm thấy nhìn vào tài liệu matplotlib. Kể từ khi truyền thuyết được bao gồm datapoints tôi di chuyển chúng, và các địa điểm cho truyền thuyết có thể được tìm thấy here. Nếu có một cách khác để tạo huyền thoại, tôi không thể tìm thấy nó sau một vài tìm kiếm nhanh trong tài liệu.

+0

Vì vậy, trong ví dụ của bạn, 'recs' và' labels' có cùng độ dài không? Và không có cách nào chỉ để thêm một huyền thoại bằng cách sử dụng các điểm đánh dấu mặc định như được vẽ trong ví dụ của tôi? Có vẻ lạ là cách duy nhất để có một huyền thoại trong một âm mưu phân tán là tạo ra một danh sách các hình dạng cho tất cả các điểm, thay vì chỉ tự động gán tất cả các điểm cùng một hình dạng. – Karnivaurus

+0

'Nhãn' trong ví dụ đầu tiên không đúng, tôi muốn sử dụng' các lớp' ở đó. Tôi cũng tìm thấy một cách thứ hai để tạo một huyền thoại trong tài liệu mà tôi đã thêm vào câu trả lời cùng với ảnh chụp màn hình. Tôi đã viết khối mã thứ hai với giả định rằng dữ liệu từ các lớp khác nhau được trộn lẫn. Nếu bạn biết thực tế dữ liệu của bạn được nhóm theo lớp và màu, bạn có thể đơn giản hóa đáng kể khối mã thứ hai bằng cách sử dụng ví dụ 'xc = x [0: 2]' cho lớp 'A'. Hoặc nếu dữ liệu của bạn ban đầu được chia theo lớp, thì chỉ đơn giản là không bao giờ kết hợp nó vào một danh sách duy nhất và bỏ qua nhu cầu xây dựng danh sách. – TheSchwa

5

Có hai cách để thực hiện. Một trong số đó cung cấp cho bạn các mục nhập huyền thoại cho mỗi điều bạn vẽ, và một cái khác cho phép bạn đặt bất cứ điều gì bạn muốn trong truyền thuyết, đánh cắp rất nhiều từ câu trả lời this.

Dưới đây là cách đầu tiên:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.linspace(-1,1,100) 

fig = plt.figure() 
ax = fig.add_subplot(1,1,1) 

#Plot something 
ax.plot(x,x, color='red', ls="-", label="$P_1(x)$") 
ax.plot(x,0.5 * (3*x**2-1), color='green', ls="--", label="$P_2(x)$") 
ax.plot(x,0.5 * (5*x**3-3*x), color='blue', ls=":", label="$P_3(x)$") 

ax.legend() 
plt.show() 

enter image description here

Chức năng ax.legend() có nhiều hơn một sử dụng, đầu tiên chỉ tạo ra truyền thuyết dựa trên các dòng trong axes đối tượng, allwos thứ hai bạn để kiểm soát các mục nhập theo cách thủ công và được mô tả here.

Về cơ bản, bạn cần cung cấp cho chú giải tay cầm dòng và nhãn được liên kết.

Cách khác cho phép bạn đặt bất kỳ thứ gì bạn muốn trong chú giải, bằng cách tạo các đối tượng và nhãn Artist và chuyển chúng đến hàm ax.legend(). Bạn có thể sử dụng điều này để chỉ đặt một số dòng của bạn trong truyền thuyết, hoặc bạn có thể sử dụng nó để đặt bất cứ điều gì bạn muốn trong truyền thuyết.

import matplotlib.pyplot as plt 
import numpy as np 

x = np.linspace(-1,1,100) 

fig = plt.figure() 
ax = fig.add_subplot(1,1,1) 

#Plot something 
p1, = ax.plot(x,x, color='red', ls="-", label="$P_1(x)$") 
p2, = ax.plot(x,0.5 * (3*x**2-1), color='green', ls="--", label="$P_2(x)$") 
p3, = ax.plot(x,0.5 * (5*x**3-3*x), color='blue', ls=":", label="$P_3(x)$") 

#Create legend from custom artist/label lists 
ax.legend([p1,p2], ["$P_1(x)$", "$P_2(x)$"]) 

plt.show() 

enter image description here

Hoặc ở đây, chúng tôi tạo Line2D đối tượng mới, và cung cấp cho họ với các huyền thoại.

import matplotlib.pyplot as pltit|delete|flag 
import numpy as np 
import matplotlib.patches as mpatches 

x = np.linspace(-1,1,100) 

fig = plt.figure() 
ax = fig.add_subplot(1,1,1) 

#Plot something 
p1, = ax.plot(x,x, color='red', ls="-", label="$P_1(x)$") 
p2, = ax.plot(x,0.5 * (3*x**2-1), color='green', ls="--", label="$P_2(x)$") 
p3, = ax.plot(x,0.5 * (5*x**3-3*x), color='blue', ls=":", label="$P_3(x)$") 

fakeLine1 = plt.Line2D([0,0],[0,1], color='Orange', marker='o', linestyle='-') 
fakeLine2 = plt.Line2D([0,0],[0,1], color='Purple', marker='^', linestyle='') 
fakeLine3 = plt.Line2D([0,0],[0,1], color='LightBlue', marker='*', linestyle=':') 

#Create legend from custom artist/label lists 
ax.legend([fakeLine1,fakeLine2,fakeLine3], ["label 1", "label 2", "label 3"]) 

plt.show() 

enter image description here

Tôi cũng đã cố gắng để có được những phương pháp sử dụng patches để làm việc, như trên trang hướng dẫn huyền thoại matplotlib, nhưng nó dường như không làm việc vì vậy tôi đã từ bỏ.

1

Trong dự án của tôi, tôi cũng muốn tạo một phân tán rỗng legend.Here là giải pháp của tôi:

from mpl_toolkits.basemap import Basemap 
#use the scatter function from matplotlib.basemap 
#you can use pyplot or other else. 
select = plt.scatter([], [],s=200,marker='o',linewidths='3',edgecolor='#0000ff',facecolors='none',label=u'监测站点') 
plt.legend(handles=[select],scatterpoints=1) 

Chăm sóc "label", "scatterpoints" ở trên.

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