'How to avoid overlapping when there's hundreds of nodes in networkx?

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



Solution 1:[1]

You can use interactive graphs by ploty to plot such 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 ploty

import plotly.graph_objects as go

import networkx as nx

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

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 ploty on internet
See docs: https://plotly.com/python/network-graphs/

Solution 2:[2]

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])))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Hamidreza