34

I've got 2000+ nodes and 900+ edges, but when I was trying to make graphics in networkx, I found all the nodes crowded together. I tried changing attribute values, such as scale, k. I found them no use since there were hundreds of nodes with labels below which means I could not choose the small size of nodes. I'm wondering if there's a method to expand the canvas or other ways to increase the distance of nodes to avoid overlapping so I can see each node and it's label clearly.

Thanks

Suryaveer Singh
  • 577
  • 2
  • 13
lukas
  • 341
  • 1
  • 3
  • 4
  • 1
    Comment (originally posted as answer by @PavloMuts): Some discussions had been already on the similar problem. You could check them out [here](https://stackoverflow.com/questions/21978487/improving-python-networkx-graph-layout). – ImportanceOfBeingErnest Mar 23 '18 at 13:00
  • Thank you so much! It helps a lot by changing parameters like alpha , nodesize, k, though I still cannot do graph drawing perfectly. It is really a difficult thing. – lukas Mar 29 '18 at 14:23
  • There are some other visualization packages out there you might consider trying. If you want to stick strictly to Python, I might recommend [the plotly Dash Cytoscape](https://dash.plot.ly/cytoscape) package. – CJ Sullivan Sep 12 '19 at 19:16
  • 2
    On a related topic for your question, here is a publication (https://doi.org/10.1371/journal.pcbi.1007244) that might be useful as a guide in visualizing your data. You might not even need to plot every node or you can be more thoughtful in what is plotted (i.e., aggregate similar nodes together so it is easier to visualize). – Eric Leung May 07 '20 at 22:05

2 Answers2

2

You can use interactive graphs by plotly to plot such a large number of nodes and edges. You can change every attribute like canvas size etc and visualize it more easily by zooming other actions.
Example:

Import plotly

import plotly.graph_objects as go

import networkx as nx

Add edges as disconnected lines in a single trace and nodes as a scatter trace

G = nx.random_geometric_graph(200, 0.125)
edge_x = []
edge_y = []
for edge in G.edges():
    x0, y0 = G.nodes[edge[0]]['pos']
    x1, y1 = G.nodes[edge[1]]['pos']
    edge_x.append(x0)
    edge_x.append(x1)
    edge_x.append(None)
    edge_y.append(y0)
    edge_y.append(y1)
    edge_y.append(None)

edge_trace = go.Scatter(
    x=edge_x, y=edge_y,
    line=dict(width=0.5, color='#888'),
    hoverinfo='none',
    mode='lines')

node_x = []
node_y = []
for node in G.nodes():
    x, y = G.nodes[node]['pos']
    node_x.append(x)
    node_y.append(y)

node_trace = go.Scatter(
    x=node_x, y=node_y,
    mode='markers',
    hoverinfo='text',
    marker=dict(
        showscale=True,
        # colorscale options
        #'Greys' | 'YlGnBu' | 'Greens' | 'YlOrRd' | 'Bluered' | 'RdBu' |
        #'Reds' | 'Blues' | 'Picnic' | 'Rainbow' | 'Portland' | 'Jet' |
        #'Hot' | 'Blackbody' | 'Earth' | 'Electric' | 'Viridis' |
        colorscale='YlGnBu',
        reversescale=True,
        color=[],
        size=10,
        colorbar=dict(
            thickness=15,
            title='Node Connections',
            xanchor='left',
            titleside='right'
        ),
        line_width=2))

Color node points by the number of connections.

Another option would be to size points by the number of connections i.e. node_trace.marker.size = node_adjacencies

node_adjacencies = []
node_text = []
for node, adjacencies in enumerate(G.adjacency()):
    node_adjacencies.append(len(adjacencies[1]))
    node_text.append('# of connections: '+str(len(adjacencies[1])))

node_trace.marker.color = node_adjacencies
node_trace.text = node_text

Create network graph

fig = go.Figure(data=[edge_trace, node_trace],
             layout=go.Layout(
                title='<br>Network graph made with Python',
                titlefont_size=16,
                showlegend=False,
                hovermode='closest',
                margin=dict(b=20,l=5,r=5,t=40),
                annotations=[ dict(
                    text="Python code: <a href='https://plotly.com/ipython-notebooks/network-graphs/'> https://plotly.com/ipython-notebooks/network-graphs/</a>",
                    showarrow=False,
                    xref="paper", yref="paper",
                    x=0.005, y=-0.002 ) ],
                xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
                yaxis=dict(showgrid=False, zeroline=False, showticklabels=False))
                )
fig.show()

You can get more details about plotly on internet
See docs: https://plotly.com/python/network-graphs/

Rodrigo
  • 3
  • 3
Suryaveer Singh
  • 577
  • 2
  • 13
0

When I had the same problem I figured out where I wanted my nodes to be and gave them as an input to networkx from a csv file:

f1 = csv.reader(open('nodes-C4-final.csv','r'),delimiter="\t")
for row in f1:
    G.add_node(row[0], label=row[1], weight = float(row[3]), pos =(float(row[4]),float(row[5])))
Hamidreza
  • 26
  • 4