Un montón de bordes en un gráfico de gráfico en python

Tengo el siguiente guión:

import pandas as pd from igraph import * df_p_c = pd.read_csv('data/edges.csv') ... edges = list_edges vertices = list(dict_case_to_number.keys()) g = Graph(edges=edges, directed=True) plot(g, bbox=(6000, 6000)) 

Tengo 2300 aristas con conexión rara. Esta es mi ttwig de ello: toda el área Y aquí están los zoom de algunas partes de ella:

introduzca la descripción de la imagen aquí introduzca la descripción de la imagen aquí

Esta gráfica no se puede leer porque la distancia entre los bordes es demasiado pequeña. ¿Cómo puedo tener una mayor distancia entre los bordes? Solo los bordes de la misma ‘familia’ tienen poca distancia.

¿Hay alguna otra manera de mejorar las plots con muchos bordes? Estoy buscando cualquier forma de visualizar la correlación padre-hijo, podría ser otro paquete de Python.

Parece que tienes muchos componentes pequeños y desconectados. Si desea un gráfico informativo, creo que debería clasificar y agrupar los componentes conectados por tamaño. Además, la suposición subyacente de muchos algoritmos de diseño de red es que hay un único componente gigante. Por lo tanto, si desea coordenadas sensibles, a menudo tendrá que calcular el diseño de cada componente por separado y luego organizar los componentes entre sí. Yo volvería a trazar su gráfica de esta manera:

introduzca la descripción de la imagen aquí

He escrito el código para este gráfico usando networkx ya que ese es mi módulo de elección. Sin embargo, sería muy fácil sustituir las funciones de igraph con igraph funciones igraph . Las dos funciones que debe reemplazar son networkx.connected_component_subgraphs y lo que quiera usar para el component_layout_func .

 #!/usr/bin/env python import numpy as np import matplotlib.pyplot as plt import networkx def layout_many_components(graph, component_layout_func=networkx.layout.spring_layout, pad_x=1., pad_y=1.): """ Arguments: ---------- graph: networkx.Graph object The graph to plot. component_layout_func: function (default networkx.layout.spring_layout) Function used to layout individual components. You can parameterize the layout function by partially evaluating the function first. For example: from functools import partial my_layout_func = partial(networkx.layout.spring_layout, k=10.) pos = layout_many_components(graph, my_layout_func) pad_x, pad_y: float Padding between subgraphs in the x and y dimension. Returns: -------- pos : dict node : (float x, float y) The layout of the graph. """ components = _get_components_sorted_by_size(graph) component_sizes = [len(component) for component in components] bboxes = _get_component_bboxes(component_sizes, pad_x, pad_y) pos = dict() for component, bbox in zip(components, bboxes): component_pos = _layout_component(component, bbox, component_layout_func) pos.update(component_pos) return pos def _get_components_sorted_by_size(g): subgraphs = list(networkx.connected_component_subgraphs(g)) return sorted(subgraphs, key=len) def _get_component_bboxes(component_sizes, pad_x=1., pad_y=1.): bboxes = [] x, y = (0, 0) current_n = 1 for n in component_sizes: width, height = _get_bbox_dimensions(n, power=0.8) if not n == current_n: # create a "new line" x = 0 # reset x y += height + pad_y # shift y up current_n = n bbox = x, y, width, height bboxes.append(bbox) x += width + pad_x # shift x down the line return bboxes def _get_bbox_dimensions(n, power=0.5): # return (np.sqrt(n), np.sqrt(n)) return (n**power, n**power) def _layout_component(component, bbox, component_layout_func): pos = component_layout_func(component) rescaled_pos = _rescale_layout(pos, bbox) return rescaled_pos def _rescale_layout(pos, bbox): min_x, min_y = np.min([v for v in pos.values()], axis=0) max_x, max_y = np.max([v for v in pos.values()], axis=0) if not min_x == max_x: delta_x = max_x - min_x else: # graph probably only has a single node delta_x = 1. if not min_y == max_y: delta_y = max_y - min_y else: # graph probably only has a single node delta_y = 1. new_min_x, new_min_y, new_delta_x, new_delta_y = bbox new_pos = dict() for node, (x, y) in pos.items(): new_x = (x - min_x) / delta_x * new_delta_x + new_min_x new_y = (y - min_y) / delta_y * new_delta_y + new_min_y new_pos[node] = (new_x, new_y) return new_pos def test(): from itertools import combinations g = networkx.Graph() # add 100 unconnected nodes g.add_nodes_from(range(100)) # add 50 2-node components g.add_edges_from([(ii, ii+1) for ii in range(100, 200, 2)]) # add 33 3-node components for ii in range(200, 300, 3): g.add_edges_from([(ii, ii+1), (ii, ii+2), (ii+1, ii+2)]) # add a couple of larger components n = 300 for ii in np.random.randint(4, 30, size=10): g.add_edges_from(combinations(range(n, n+ii), 2)) n += ii pos = layout_many_components(g, component_layout_func=networkx.layout.circular_layout) networkx.draw(g, pos, node_size=100) plt.show() if __name__ == '__main__': test() 

EDITAR

Si desea que los subgrafos estén bien ordenados, necesita instalar rectangle-packer ( pip install rectangle-packer ), y sustituir _get_component_bboxes con esta versión:

 import rpack def _get_component_bboxes(component_sizes, pad_x=1., pad_y=1.): dimensions = [_get_bbox_dimensions(n, power=0.8) for n in component_sizes] # rpack only works on integers; sizes should be in descending order dimensions = [(int(width + pad_x), int(height + pad_y)) for (width, height) in dimensions[::-1]] origins = rpack.pack(dimensions) bboxes = [(x, y, width-pad_x, height-pad_y) for (x,y), (width, height) in zip(origins, dimensions)] return bboxes[::-1] 

introduzca la descripción de la imagen aquí

Podrías comprar en networkx , que es una bonita biblioteca de gráficos. Networkx tiene soporte de trazado directo para matplotlib .

Admite varios tipos de diseño, por ejemplo , diseño de resorte, diseño aleatorio y algunos más

Debe observar especialmente el diseño de Spring , que tiene algunos parámetros interesantes para su caso de uso:

k (flotante (predeterminado = Ninguno)) – Distancia óptima entre nodos. Si Ninguno, la distancia se establece en 1 / sqrt (n) donde n es el número de nodos. Aumente este valor para alejar los nodos.

O ambos en combinación con un diseño personalizado:

pos (dict o None opcional (predeterminado = Ninguno)) – Posiciones iniciales para los nodos como un diccionario con el nodo como claves y valores como una lista de coordenadas o tupla. Si Ninguno, entonces usa posiciones iniciales aleatorias.

fijo (lista o Ninguno opcional (predeterminado = Ninguno)) – Nodos que se mantienen fijos en la posición inicial.

El peso del borde también puede ser algo que puede ajustar para obtener los resultados que le gustan:

peso (cadena o Ninguno opcional (predeterminado = ‘peso’)) – El atributo de borde que contiene el valor numérico utilizado para el peso de borde. Si Ninguno, entonces todos los pesos de borde son 1.

Recomendaría combinar networkx con bokeh , que es una nueva biblioteca de trazado que crea gráficos html / js basados ​​en la web. Tiene soporte directo para networkx , y tiene algunas características interesantes , como la fácil integración de las herramientas de desplazamiento del nodo. Si tu gráfica no es demasiado grande, el rendimiento es bastante bueno. (He trazado gráficos con unos 20000 nodos y unos pocos miles de bordes).

Con ambas bibliotecas combinadas, todo lo que necesita es el siguiente bit de código para un ejemplo simple (de la documentación) que intenta crear un diseño optimizado:

 import networkx as nx from bokeh.io import show, output_file from bokeh.plotting import figure from bokeh.models.graphs import from_networkx G=nx.karate_club_graph() # Replace with your own graph plot = figure(title="Networkx Integration Demonstration", x_range=(-1.1,1.1), y_range=(-1.1,1.1), tools="", toolbar_location=None) graph = from_networkx(G, nx.spring_layout, scale=2, center=(0,0)) plot.renderers.append(graph) output_file("networkx_graph.html") show(plot) 

¿Sabes qué significado estás buscando? ¿O estás explorando? ¿O es esta una pregunta específica sobre cuestiones de zoom?

Hasta ahora, has hecho un buen trabajo al ver la estructura general. Algunas ideas que podría considerar crear un nuevo vocabulario con algunas rutinas para apoyarlo. Por ejemplo, si hace que un grupo pequeño sea ​​el conjunto de puntos y bordes que están juntos, puede trazar histogtwigs, visualizaciones de grupos superpuestos uno sobre otro, comparar grupos con y sin nodos largos, y así uno.