【问题标题】:plotting results of hierarchical clustering ontop of a matrix of data in python在python中的数据矩阵上绘制层次聚类的结果
【发布时间】:2011-02-28 07:15:46
【问题描述】:

如何在 Python 中在值矩阵的顶部绘制树状图,并适当地重新排序以反映聚类?下图就是一个例子:

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

我使用 scipy.cluster.dendrogram 来制作我的树状图并对数据矩阵执行层次聚类。然后如何将数据绘制为矩阵,其中行已重新排序以反映在特定阈值处切割树状图引起的聚类,并将树状图绘制在矩阵旁边?我知道如何在 scipy 中绘制树状图,但不知道如何使用右侧比例尺绘制数据的强度矩阵。

对此的任何帮助将不胜感激。

【问题讨论】:

标签: python cluster-analysis machine-learning matplotlib scipy


【解决方案1】:

这个问题没有很好地定义矩阵:“值矩阵”,“数据矩阵”。我假设您的意思是距离矩阵。换句话说,对称非负 N×N 距离矩阵 D 中的元素 D_ij 表示两个特征向量 x_i 和 x_j 之间的距离。对吗?

如果是这样,那么试试这个(2010 年 6 月 13 日编辑,以反映两个不同的树状图):

import scipy
import pylab
import scipy.cluster.hierarchy as sch
from scipy.spatial.distance import squareform


# 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])

condensedD = squareform(D)

# 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(condensedD, method='centroid')
Z1 = sch.dendrogram(Y, orientation='left')
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(condensedD, 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')

祝你好运!如果您需要更多帮助,请告诉我。


编辑:对于不同的颜色,调整imshow中的cmap属性。有关示例,请参阅scipy/matplotlib docs。该页面还描述了如何创建自己的颜色图。为方便起见,我建议使用预先存在的颜色图。在我的示例中,我使用了YlGnBu


编辑:add_axes (see documentation here) 接受列表或元组:(left, bottom, width, height)。例如,(0.5,0,0.5,1) 在图的右半边添加了一个Axes(0,0.5,1,0.5) 在图的上半部分添加了一个Axes

大多数人可能会使用add_subplot 来方便。我喜欢add_axes 的控制力。

要删除边框,请使用add_axes([left,bottom,width,height], frame_on=False)See example here.

【讨论】:

  • 这是一个很好的问题。还有几个问题:如何在顶部显示样本的聚类?如果矩阵是按样本排列的基因,那么您已经在左侧显示了基因,但我想在顶部显示样本聚类。我怎样才能适当地调整轴来做到这一点?另外,如何将颜色图调整为黄色到蓝色并控制右侧栏的比例?非常感谢!
  • 我上传了一张不同颜色的图。见编辑。你能定义“基因”和“样本”吗?相似度如何计算?尽管如此,我还在矩阵上方添加了第二个树状图。希望您可以根据需要进行调整。
  • 感谢史蒂夫,他回答了我关于顶部树状图的问题。再快速澄清一下:如何设置 add_axes 的参数?我不确定你是如何选择这些数值的。例如,我想删除树状图周围的框,只显示树。如果这些是常规子图,我可以在 subplot.ax.spines 中的每个脊椎上“设置颜色(无)”。我可以在这里做同样的事情吗?
  • 我认为你使用联动功能的方式是错误的。如果你查看linkage()的源代码,如果第一个参数(这里你使用D)是一个矩阵,它将被视为数据,而不是距离。要输入距离,您必须将 D 的上三角形做成一维向量,然后将其传递给 links()。
  • 这个答案很有帮助!但是,正如@danioyuan 提到的,linkage 函数的使用现在似乎是错误的。使用距离矩阵,将其转换为向量形式的距离矩阵。即 D = squareform(D) 在使用 linkage 之前。 github.com/scipy/scipy/blob/v0.15.1/scipy/cluster/…
【解决方案2】:

如果除了矩阵和树状图还需要显示元素的标签,可以使用以下代码,显示所有标签旋转 x 标签并更改字体大小以避免在 x 轴上重叠.它需要移动颜色条以便为 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])

得到的结果是这样的(用不同的颜色贴图):

【讨论】:

    猜你喜欢
    • 2011-02-28
    • 2014-10-24
    • 2017-11-23
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 2015-12-14
    相关资源
    最近更新 更多