1

I have the following distance matrix:

delta =
[[ 0.          0.71370845  0.80903791  0.82955157  0.56964983  0.          0.        ]
 [ 0.71370845  0.          0.99583115  1.          0.79563006  0.71370845
   0.71370845]
 [ 0.80903791  0.99583115  0.          0.90029133  0.81180111  0.80903791
   0.80903791]
 [ 0.82955157  1.          0.90029133  0.          0.97468433  0.82955157
   0.82955157]
 [ 0.56964983  0.79563006  0.81180111  0.97468433  0.          0.56964983
   0.56964983]
 [ 0.          0.71370845  0.80903791  0.82955157  0.56964983  0.          0.        ]
 [ 0.          0.71370845  0.80903791  0.82955157  0.56964983  0.          0.        ]]

And I'm trying to use the networkx library to represent it as a graph. This is my code:

import networkx as nx

G = nx.from_numpy_matrix(delta) 
pos = nx.random_layout(G) 

plt.figure(figsize=(7, 7))
for k, p in pos.iteritems():
    plt.scatter(p[0], p[1], marker='o', c=colors[k], s=50, edgecolor='None')
lgd = plt.legend(markers, labels, numpoints=1, bbox_to_anchor=(1.17, 0.5))
plt.tight_layout()
plt.axis('equal')
pt.show()

However, what I see is not what I expect. For instance, consider this output:

enter image description here

From delta, node 1 is at the same point as node 6 and 7, and far from node 4. I don't see the in the output plot. Besides, overtime I run it, it results in another output. This is expected, but the distance seem to not be respected. In the following plot, for example, distances between 1 to 6,7 and 4 changed.

enter image description here

I can't understand why.

pceccon
  • 9,379
  • 26
  • 82
  • 158

2 Answers2

2

You are using nx.random_layout, which positions the vertices of the graph in random positions drawn from the uniform distribution. There are other layouts, such as the nx.spring_layout, aka nx.fruchterman_reingold_layout, that try to position the vertices such that their distances approximate the given distances.

A.P.
  • 1,109
  • 8
  • 6
  • http://stackoverflow.com/questions/36318742/visualizing-distance-matrix-using-tsne-and-graph-python – pceccon Mar 31 '16 at 17:53
2

You can use a slightly more consistent layout, maybe shell_layout() or circular_layout(). Technically, in a generic abstract graph, the depicted location has no real meaning, and each of these functions tends to have a little variance each time you call it as a reflection of that fact. They simply place nodes in a reasonable fashion according to some predefined pattern.

If you want consistent placement you'll have to do it yourself.

Understand the structure the layout functions produce and use your understanding of the data to produce a more sensible visualization. These functions produce a dictionary keyed on the nodes with values that are lists of length 2. The first entry specifies the node's x location, the second, the y.
Take this example, a graph of network connections between offices.

pos=nx.spring_layout(G)
print pos

might yield something like

{'A': [1, 12], 'C': [5, 8], 'B': [4, 11], 'E': [8, 3], 'D': [8, 7], 'F': [6, 1]}

However, I know that since my data represents citites it makes sense to display the nodes at locations that represent their physical locations, so I, instead, build my own dictionary (each node already has an initialized attribute of 'x' and 'y').

pos = {}
for node in G.nodes():
    pos[node] = [G.node[node]["x"], G.node[node]["y"]]

This displays the nodes the same way every time. Create your own pos dictionary in a similar manner based on your matrix.

Culex
  • 300
  • 1
  • 9