将距离矩阵可视化为图形

时间:2013-09-20 08:21:14

标签: matrix data-visualization

我正在做一个聚类任务,我有一个距离矩阵。我希望将这个距离矩阵可视化为2D图。如果有任何方法可以在线或使用R或python等编程语言,请告诉我。 我的距离矩阵如下, enter image description here 我使用了经典的多维缩放功能(在R中)并获得了一个看起来像这样的2D图:enter image description here 但我要找的是一个节点和加权边缘在它们之间运行的图形。

4 个答案:

答案 0 :(得分:7)

可能性1

我假设您需要一个二维图形,其中节点位置之间的距离与表格提供的相同

在python中,您可以将networkx用于此类应用程序。一般来说,有很多这样做的方法,记住,所有这些都只是近似值(因为一般来说,不可能在给定成对距离的情况下创建点的二维表示)它们是某种应力最小化(或能量)最小化)近似,试图找到与所提供的相似距离的“合理”表示。

作为一个例子,您可以考虑一个四点示例(应用正确的离散度量):

     p1 p2 p3 p4
  ---------------
  p1  0  1  1  1
  p2  1  0  1  1
  p3  1  1  0  1
  p4  1  1  1  0

一般来说,绘制实际的“图形”是多余的,因为你已完全连接一个(每对节点都已连接),所以只绘制点就足够了。

Python example

import networkx as nx
import numpy as np
import string

dt = [('len', float)]
A = np.array([(0, 0.3, 0.4, 0.7),
               (0.3, 0, 0.9, 0.2),
               (0.4, 0.9, 0, 0.1),
               (0.7, 0.2, 0.1, 0)
               ])*10
A = A.view(dt)

G = nx.from_numpy_matrix(A)
G = nx.relabel_nodes(G, dict(zip(range(len(G.nodes())),string.ascii_uppercase)))    

G = nx.to_agraph(G)

G.node_attr.update(color="red", style="filled")
G.edge_attr.update(color="blue", width="2.0")

G.draw('distances.png', format='png', prog='neato')

在R中,您可以尝试multidimensional scaling

# Classical MDS
# N rows (objects) x p columns (variables)
# each row identified by a unique row name

d <- dist(mydata) # euclidean distances between the rows
fit <- cmdscale(d,eig=TRUE, k=2) # k is the number of dim
fit # view results

# plot solution 
x <- fit$points[,1]
y <- fit$points[,2]
plot(x, y, xlab="Coordinate 1", ylab="Coordinate 2", 
  main="Metric  MDS",    type="n")
text(x, y, labels = row.names(mydata), cex=.7)

可能性2

您只想绘制标有边缘的图表

再次,networkx可以提供帮助:

import networkx as nx   

# Create a graph
G = nx.Graph()

# distances
D = [ [0, 1], [1, 0] ]

labels = {}
for n in range(len(D)):
    for m in range(len(D)-(n+1)):
        G.add_edge(n,n+m+1)
        labels[ (n,n+m+1) ] = str(D[n][n+m+1])

pos=nx.spring_layout(G)

nx.draw(G, pos)
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels,font_size=30)

import pylab as plt
plt.show()

答案 1 :(得分:2)

您没有提到是否需要二维图表。我想你想要建立一个2维的图形,因为你需要它来实现可视化。考虑到你必须意识到,对于大多数图表来说,这根本不可能。

可能做的是以某种方式近似来自距离矩阵的值,例如小值以具有相对小的边缘和大值以具有相对大的长度。

根据之前的所有考虑,一个选项是graphviz。请参阅neato功能。 一般来说,您感兴趣的是力导向绘图。有关详细信息,请参阅wikipedia

答案 2 :(得分:2)

Multidimensional scaling(MDS)正是您想要的。有关详情,请参阅herehere

答案 3 :(得分:0)

您可以使用d3js Force Directed Graph并配置节点之间的距离。 d3js force layout具有一些聚类功能,可以分隔距离相近的节点。这是一个示例,其中值为节点之间的距离:

http://vida.io/documents/SyT7DREdQmGSpsBkK

另一种可视化方法是在节点之间使用相同的距离,但线宽不同。在这种情况下,您需要根据值计算笔画宽度:

.style("stroke-width", function(d) { return Math.sqrt(d.value / 50); });