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.Adjacencyno puede tomar unnp.arraycomo 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)