I'm learning how to visualise the relationship some clusters as a graph. Let say I have 10 clusters (0-9) and I have already compute a distance between them and store it on a dictionary, named cluster_dist
, that looks like this:
defaultdict(int,
{('9', '2'): 90.0541376578846,
('1', '5'): 35.89579773471981,
('0', '2'): 35.89411581688678,
('5', '9'): 38.71629863467774,
('3', '5'): 4.263508474490007,
('2', '8'): 23.178581625571567,
('2', '7'): 75.21291397588608,
('1', '2'): 5.785812660966547,
('4', '6'): 5.785812660966547,
('1', '4'): 5.785812660966547})
So keys of this dictionary are tuples that represent edges and the value of these is a type of distance that I calculate between each cluster. The higher the distance, I expect that they are further apart on a graph.
Is it possible to create a graph with this kind of input? I was trying something like this:
g.add_vertices(10)
for clusters, dist in cluster_dist.items():
a,b = map(int, list(clusters))
g.add_edge(a, b, weight = dist )
But here I am not sure how to plot this on a way that the weight is interpreted as distance. I am a complete noob with graphs and igraph, so I bet there is a better way to assign the distance attribute to each edge.
Is it possible to represent a network out of any set of predetermined distances between nodes? If so, what is the best way to do this with igraph in python? In the case is not mathematically possible to generate a network that represent a given set of distances, is there any method to represent an approximation?
Thanks for your time :)
Using networkx
and the kamada_kawai_layout
as layout respecting distances.
import networkx as nx
import matplotlib.pyplot as plt
cluster_dist = \
{('9', '2'): 90.0541376578846,
('1', '5'): 35.89579773471981,
('0', '2'): 35.89411581688678,
('5', '9'): 38.71629863467774,
('3', '5'): 4.263508474490007,
('2', '8'): 23.178581625571567,
('2', '7'): 75.21291397588608,
('1', '2'): 5.785812660966547,
('4', '6'): 5.785812660966547,
('1', '4'): 5.785812660966547}
# convert to graph
G = nx.Graph()
for (node1,node2), weight in cluster_dist.items():
G.add_edge(node1, node2, weight=weight)
# compute layout for plotting
pos = nx.kamada_kawai_layout(G, weight='weight')
nx.draw(G,pos)
# next code for labels is not really necessary, but I think it makes it clearer
labels = {k: round(v,2) for k,v in nx.get_edge_attributes(G,'weight').items()}
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels)
nx.draw_networkx_labels(G,pos)
plt.show()
Output: