在同一图上同时绘制两个距离矩阵? [英] Plotting two distance matrices together on same plot?

查看:84
本文介绍了在同一图上同时绘制两个距离矩阵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从两个不同的距离矩阵创建树状图并进行比较.我在此处作为起点,但是问题在于,由于我使用的是两个不同的矩阵,但是使用相同的聚类方法,因此我需要将两个不同的矩阵一起绘制以进行比较分析.我想知道是否有可能将每个正方形/节点的对角分开以显示两个不同的距离矩阵.

I'm trying to create dendrograms from two different distance matrices and compare them. I used the code here as a starting point, but the problem is since I'm using two different matrices but same clustering method, I need to plot two different matrices together for a comparative analysis. I was wondering if it is possible to separate to halves of each square/node diagonally to show two different distance matrices.

此图像代表了我针对的结果:

This image represents the result which I'm targeting for:

这是我的代码:

from sklearn import preprocessing
from sklearn.neighbors import DistanceMetric 
import pandas as pd
import numpy as np
from ete3 import Tree
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.metrics.pairwise import cosine_distances
import scipy
import pylab
import scipy.cluster.hierarchy as sch
import scipy.spatial.distance as sd 
import random
#g[n] is a one dimensional array containing datapoints
g1 = random.sample(range(30), 5)
g2 = random.sample(range(30), 5)
g3 = random.sample(range(30), 5)
g4 = random.sample(range(30), 5)
g5 = random.sample(range(30), 5)
g1 = np.array(g1)
g2 = np.array(g2)
g3 = np.array(g3)
g4 = np.array(g4)
g5 = np.array(g5)
X = (g1,g2,g3,g4,g5)
#Comparing between euclidean and cosine###########################################
distanceC = cosine_distances(X)
dist = DistanceMetric.get_metric('euclidean')
distanceE = dist.pairwise(X)
##################################################################################

#Plots############################################################################

# 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.average(sd.squareform(distanceC))
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.average(sd.squareform(distanceE))
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']
distance = distance[idx1,:]
distance = distance[:,idx2]
im = axmatrix.matshow(distance, 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')
##################################################################################

推荐答案

没有内置方法来绘制由三角形组成的图像,将像素减半.

There is no built-in method to draw an image consisting of triangles, cutting the pixels in half.

因此,需要构建一些自定义的热图.这可以使用三角形的PolyCollection来完成.在下面的解决方案中,一个函数在原点周围创建一个三角形的点,并在需要时旋转它们,并应用偏移量.遍历数组可以为每个点创建一个三角形.最后,将所有这些三角形收集到PolyCollection中.

So one would need to build some custom heatmap. This could be done using a PolyCollection of triangles. In the solution below a function creates the points of a triangle around the origin, rotates them if needed, and applies an offset. Looping over the array allows to create a triangle for each point. Finally all those triangles are collected into a PolyCollection.

然后,您可以决定对数组之一和其顶部的自定义三角形矩阵使用普通的imshowmatshow图.

You may then decide to use a normal imshow or matshow plot for one of the arrays and the custom triangle matrix on top of it.

import matplotlib.pyplot as plt
import matplotlib.collections as collections
import numpy as np

def triatpos(pos=(0,0), rot=0):
    r = np.array([[-1,-1],[1,-1],[1,1],[-1,-1]])*.5
    rm = [[np.cos(np.deg2rad(rot)), -np.sin(np.deg2rad(rot))],
           [np.sin(np.deg2rad(rot)),np.cos(np.deg2rad(rot)) ] ]
    r = np.dot(rm, r.T).T
    r[:,0] += pos[0]
    r[:,1] += pos[1]
    return r

def triamatrix(a, ax, rot=0, cmap=plt.cm.viridis, **kwargs):
    segs = []
    for i in range(a.shape[0]):
        for j in range(a.shape[1]):
            segs.append(triatpos((j,i), rot=rot) )
    col = collections.PolyCollection(segs, cmap=cmap, **kwargs)
    col.set_array(a.flatten())
    ax.add_collection(col)
    return col


A,B = np.meshgrid(range(5), range(4))
B*=4

fig, ax=plt.subplots()
im1 = ax.imshow(A)
im2 = triamatrix(B, ax, rot=90, cmap="Reds")

fig.colorbar(im1, ax=ax, )
fig.colorbar(im2, ax=ax, )

plt.show()

当然也可以使用其中两个三角形矩阵

Of course it would be equally possible to use two of those triangle matrices

im1 = triamatrix(A, ax, rot=0, cmap="Blues")
im2 = triamatrix(B, ax, rot=180, cmap="Reds")
ax.set_xlim(-.5,A.shape[1]-.5)
ax.set_ylim(-.5,A.shape[0]-.5)

这还需要手动设置轴限制.

which would also require to set the axis limits manually.

这篇关于在同一图上同时绘制两个距离矩阵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆