python - Gráfica igraph de matriz de adyacencia numpy o pandas
plt title python 3 (2)
En igraph puede usar igraph.Graph.Adjacency
para crear un gráfico a partir de una matriz de adyacencia sin tener que usar zip
. Hay algunas cosas que se deben tener en cuenta cuando una matriz de adyacencia ponderada se utiliza y almacena en un np.array
o pd.DataFrame
.
igraph.Graph.Adjacency
no puede tomar unnp.array
como argumento, pero eso se resuelve fácilmente usandotolist
.Los enteros en la matriz de adyacencia se interpretan como un número de bordes entre nodos en lugar de pesos, y se resuelven utilizando la adyacencia como booleano.
Un ejemplo de cómo hacerlo:
import igraph
import pandas as pd
node_names = [''A'', ''B'', ''C'']
a = pd.DataFrame([[1,2,3],[3,1,1],[4,0,2]], index=node_names, columns=node_names)
# Get the values as np.array, it''s more convenenient.
A = a.values
# Create graph, A.astype(bool).tolist() or (A / A).tolist() can also be used.
g = igraph.Graph.Adjacency((A > 0).tolist())
# Add edge weights and node labels.
g.es[''weight''] = A[A.nonzero()]
g.vs[''label''] = node_names # or a.index/a.columns
Puede reconstruir su marco de datos de adyacencia usando get_adjacency
de la siguiente manera:
df_from_g = pd.DataFrame(g.get_adjacency(attribute=''weight'').data,
columns=g.vs[''label''], index=g.vs[''label''])
(df_from_g == a).all().all() # --> True
Tengo una matriz de adyacencia almacenada como pandas.DataFrame
:
node_names = [''A'', ''B'', ''C'']
a = pd.DataFrame([[1,2,3],[3,1,1],[4,0,2]],
index=node_names, columns=node_names)
a_numpy = a.as_matrix()
Me gustaría crear un igraph.Graph
desde las pandas
o las matrices de adyacencia numpy
. En un mundo ideal, los nodos serían nombrados como se esperaba.
es posible? El tutorial parece guardar silencio sobre el tema.
Estrictamente hablando, una matriz de adyacencia es booleana, con 1 que indica la presencia de una conexión y 0 que indica la ausencia. Dado que muchos de los valores en su matriz a_numpy
son> 1, asumiré que corresponden a pesos de borde en su gráfica.
import igraph
# get the row, col indices of the non-zero elements in your adjacency matrix
conn_indices = np.where(a_numpy)
# get the weights corresponding to these indices
weights = a_numpy[conn_indices]
# a sequence of (i, j) tuples, each corresponding to an edge from i -> j
edges = zip(*conn_indices)
# initialize the graph from the edge sequence
G = igraph.Graph(edges=edges, directed=True)
# assign node names and weights to be attributes of the vertices and edges
# respectively
G.vs[''label''] = node_names
G.es[''weight''] = weights
# I will also assign the weights to the ''width'' attribute of the edges. this
# means that igraph.plot will set the line thicknesses according to the edge
# weights
G.es[''width''] = weights
# plot the graph, just for fun
igraph.plot(G, layout="rt", labels=True, margin=80)