2010-06-06 33 views
44

Làm thế nào tôi có thể vẽ biểu đồ dendrogram ngay trên một ma trận giá trị, sắp xếp lại một cách thích hợp để phản ánh phân cụm, bằng Python? Một ví dụ là con số sau đây:vẽ sơ đồ kết quả phân lớp phân cấp ontop của ma trận dữ liệu trong python

https://publishing-cdn.elifesciences.org/07103/elife-07103-fig6-figsupp1-v2.jpg

tôi sử dụng để làm cho scipy.cluster.dendrogram dendrogram của tôi và thực hiện phân nhóm theo thứ bậc trên một ma trận dữ liệu. Làm thế nào tôi có thể sau đó vẽ dữ liệu như là một ma trận, nơi các hàng đã được sắp xếp lại để phản ánh một cụm gây ra bởi việc cắt dendrogram tại một ngưỡng cụ thể, và có dendrogram âm mưu cùng với ma trận? Tôi biết làm thế nào để vẽ các chương trình dendrogram trong scipy, nhưng không phải làm thế nào để vẽ ma trận cường độ dữ liệu với thanh tỷ lệ bên phải bên cạnh nó.

Bất kỳ trợ giúp nào về điều này sẽ được đánh giá cao.

+0

Đây là chi tiết của một câu hỏi matplotlib, tôi đã gắn thẻ lại. – dwf

+0

Có thể trùng lặp: http://stackoverflow.com/questions/2455761/reordering-matrix-elements-to-reflect-column-and-row-clustering-in-naiive-python –

+4

Vui lòng cập nhật liên kết đến hình ảnh. –

Trả lời

85

Câu hỏi không xác định ma trận rất tốt: "ma trận giá trị", "ma trận dữ liệu". Tôi giả sử rằng bạn có nghĩa là ma trận khoảng cách . Nói cách khác, phần tử D_ij trong ma trận không đối xứng N-by-N ma trận khoảng cách D biểu thị khoảng cách giữa hai vectơ đặc trưng, ​​x_i và x_j. Đúng không?

Nếu vậy, sau đó thử này (sửa 13 tháng 6 năm 2010, để phản ánh hai dendrograms khác nhau):

import scipy 
import pylab 
import scipy.cluster.hierarchy as sch 

# Generate random features and distance matrix. 
x = scipy.rand(40) 
D = scipy.zeros([40,40]) 
for i in range(40): 
    for j in range(40): 
     D[i,j] = abs(x[i] - x[j]) 

# Compute and plot first dendrogram. 
fig = pylab.figure(figsize=(8,8)) 
ax1 = fig.add_axes([0.09,0.1,0.2,0.6]) 
Y = sch.linkage(D, method='centroid') 
Z1 = sch.dendrogram(Y, orientation='right') 
ax1.set_xticks([]) 
ax1.set_yticks([]) 

# Compute and plot second dendrogram. 
ax2 = fig.add_axes([0.3,0.71,0.6,0.2]) 
Y = sch.linkage(D, method='single') 
Z2 = sch.dendrogram(Y) 
ax2.set_xticks([]) 
ax2.set_yticks([]) 

# Plot distance matrix. 
axmatrix = fig.add_axes([0.3,0.1,0.6,0.6]) 
idx1 = Z1['leaves'] 
idx2 = Z2['leaves'] 
D = D[idx1,:] 
D = D[:,idx2] 
im = axmatrix.matshow(D, aspect='auto', origin='lower', cmap=pylab.cm.YlGnBu) 
axmatrix.set_xticks([]) 
axmatrix.set_yticks([]) 

# Plot colorbar. 
axcolor = fig.add_axes([0.91,0.1,0.02,0.6]) 
pylab.colorbar(im, cax=axcolor) 
fig.show() 
fig.savefig('dendrogram.png') 

Dendrogram and distance matrix http://up.stevetjoa.com/dendrogram.png

Chúc may mắn! Hãy cho tôi biết nếu bạn cần thêm trợ giúp.


Chỉnh sửa: Đối với các màu khác nhau, điều chỉnh thuộc tính cmap trong imshow. Xem các ví dụ scipy/matplotlib docs. Trang đó cũng mô tả cách tạo bản đồ màu của riêng bạn. Để thuận tiện, tôi khuyên bạn nên sử dụng một bản đồ có sẵn từ trước. Trong ví dụ của tôi, tôi đã sử dụng YlGnBu.


Edit: add_axes (see documentation here) chấp nhận một danh sách hoặc tuple: (left, bottom, width, height). Ví dụ: (0.5,0,0.5,1) thêm Axes vào nửa bên phải của hình. (0,0.5,1,0.5) thêm Axes vào nửa trên của hình.

Hầu hết mọi người có thể sử dụng add_subplot để thuận tiện cho nó. Tôi thích add_axes để kiểm soát.

Để xóa đường viền, hãy sử dụng add_axes([left,bottom,width,height], frame_on=False). See example here.

+0

Đây là một câu hỏi hay. Một vài câu hỏi nữa: làm cách nào tôi có thể hiển thị các cụm mẫu ở trên cùng? Nếu ma trận là gen theo mẫu, bạn đã cho thấy các gen ở bên trái nhưng tôi muốn hiển thị các mẫu phân cụm ở trên cùng. Làm thế nào tôi có thể điều chỉnh các trục thích hợp để làm điều đó? Ngoài ra, làm cách nào tôi có thể điều chỉnh bản đồ màu thành vàng sang xanh dương và kiểm soát tỷ lệ của thanh ở bên phải? cám ơn rất nhiều! – user248237dfsf

+0

Tôi đã tải lên một hình có bản đồ màu khác. Xem chỉnh sửa. Bạn có thể định nghĩa "gen" và "sample" không? Tính tương tự được tính như thế nào? Tuy nhiên, tôi cũng đã thêm một dendrogram thứ hai trên ma trận. Hy vọng rằng bạn có thể điều chỉnh nó như bạn thấy phù hợp. –

+0

Cảm ơn Steve, đã trả lời câu hỏi của tôi về dendrogram hàng đầu. Chỉ cần làm rõ nhanh hơn: làm thế nào để bạn thiết lập các đối số của add_axes? Tôi không chắc bạn đã chọn những giá trị số như thế nào. Ví dụ, tôi muốn loại bỏ các hộp xung quanh dendrograms và chỉ hiển thị cây. Nếu đây là những subplots thường xuyên, tôi có thể "set_color (none)" trên mỗi cột sống trong subplot.ax.spines. Tôi có thể làm tương tự ở đây không? – user248237dfsf

8

Nếu ngoài ma trận và dendrogram thì cần phải hiển thị nhãn của các phần tử, có thể sử dụng mã sau, cho biết tất cả các nhãn xoay nhãn x và thay đổi cỡ phông để tránh chồng chéo lên trục x. Nó đòi hỏi phải di chuyển colorbar để có không gian cho các nhãn y:

axmatrix.set_xticks(range(40)) 
axmatrix.set_xticklabels(idx1, minor=False) 
axmatrix.xaxis.set_label_position('bottom') 
axmatrix.xaxis.tick_bottom() 

pylab.xticks(rotation=-90, fontsize=8) 

axmatrix.set_yticks(range(40)) 
axmatrix.set_yticklabels(idx2, minor=False) 
axmatrix.yaxis.set_label_position('right') 
axmatrix.yaxis.tick_right() 

axcolor = fig.add_axes([0.94,0.1,0.02,0.6]) 

Kết quả thu được là thế này (với một bản đồ màu sắc khác nhau):

The result obtained is this:

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