Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make edges start from outside the node in Networkx

I have a weighted circular layout plot. I wanted to make edges start from the outside of the node, but cannot find a way to do so. I tried setting alpha=1, but that didn't give me the desired outcome. The image below displays what I'm getting right now

enter image description here

This is the following code I have for nodes right now:

for n in G.nodes():
    if n in set1:
        G.nodes[n]['color'] = '#7a8eff'
    elif n in set2:
        G.nodes[n]['color'] = '#eb2c30'
    elif n in set3:
        G.nodes[n]['color'] = '#7300ff'
    else:
        G.nodes[n]['color'] = '#730a15'

colors = [node[1]['color'] for node in G.nodes(data=True)]
nx.draw_networkx_nodes(G, pos, node_size=1000, node_color=colors)


# edges
for edge in G.edges():
    source, target = edge
    rad = 0.25
    node_color_dict = dict(G.nodes(data='color'))
    if node_color_dict[source] == node_color_dict[target]:
        arrowprops=dict(lw=G.edges[(source,target)]['weight'],
                        arrowstyle="-",
                        color='blue',
                        connectionstyle=f"arc3,rad={rad}",
                        linestyle= '-',
                        alpha=0.45)
        ax.annotate("",
                    xy=pos[source],
                    xytext=pos[target],
                    arrowprops=arrowprops
                   )
    else:
        arrowprops=dict(lw=G.edges[(source,target)]['weight'],
                        arrowstyle="-",
                        color='purple',
                        connectionstyle=f"arc3,rad={rad}",
                        linestyle= '-',
                        alpha=0.45)
        ax.annotate("",
                    xy=pos[source],
                    xytext=pos[target],
                    arrowprops=arrowprops
                   )
# labels
nx.draw_networkx_labels(G, pos, font_size=11, font_family="monospace", font_color='white', font_weight='bold', alpha=1.0)

like image 750
nandz123 Avatar asked Nov 12 '20 11:11

nandz123


People also ask

How to set NetworkX edge labels offset in Matplotlib?

How to set NetworkX edge labels offset in Matplotlib? Set the figure size and adjust the padding between and around the subplots. Initialize a graph with edges, name, or graph attributes.

How to create curved edges with NetworkX in Python3?

To create curved edges with NetworkX in Python3, we can use connectionstyle="arc3, rad=0.4".

What are nodes and edges in a graph?

Well, graphs are built using nodes and edges. A node represents some object, perhaps a person or organization, and an edge represents the actual connection from one node to another node. So in the example below, “A”, “B”, “C”, and “D” are nodes and the lines between them are the edges. We can also change the color of all the nodes quite easily.

How to successfully predict edges in a network?

The following means can be assumed in order to successfully predict edges in a network : If two vertices are connected to the same third vertices, the tendency for them to share a connection is Triadic Closure. comm_neighb (X, Y) = |N (X) N (Y)|, where N (X) is the set of all neighbours of X.


Video Answer


1 Answers

A full example, which produces the desired result:

import networkx as nx
import matplotlib.pylab as pl


G = nx.karate_club_graph()
pos = nx.kamada_kawai_layout(G)

set1 = set(node for node in G if G.nodes[node]["club"] == "Mr. Hi")
set2 = set(node for node in G if G.nodes[node]["club"] != "Mr. Hi")

for n in G.nodes():
    if n in set1:
        G.nodes[n]['color'] = '#7a8eff'
    elif n in set2:
        G.nodes[n]['color'] = '#eb2c30'

for u, v in G.edges():
    G.edges[(u,v)]["weight"] = 1

colors = [node[1]['color'] for node in G.nodes(data=True)]
nodes_draw = nx.draw_networkx_nodes(G, pos, node_size=1000, node_color=colors)

ax = pl.gca()

# draw in the order, edges, nodes, node labels
zorder_edges = 3
zorder_nodes = 4
zorder_node_labels = 5

# edges
for edge in G.edges():
    source, target = edge
    rad = 0.25
    node_color_dict = dict(G.nodes(data='color'))
    if node_color_dict[source] == node_color_dict[target]:
        arrowprops=dict(lw=G.edges[(source,target)]['weight'],
                        arrowstyle="-",
                        color='blue',
                        connectionstyle=f"arc3,rad={rad}",
                        linestyle= '-',
                        #alpha=0.45,
                        zorder=zorder_edges,
                        )
        ax.annotate("",
                    xy=pos[source],
                    xytext=pos[target],
                    arrowprops=arrowprops
                   )
    else:
        arrowprops=dict(lw=G.edges[(source,target)]['weight'],
                        arrowstyle="-",
                        color='purple',
                        connectionstyle=f"arc3,rad={rad}",
                        linestyle= '-',
                        #alpha=0.45,
                        zorder=zorder_edges,
                        )
        ax.annotate("",
                    xy=pos[source],
                    xytext=pos[target],
                    arrowprops=arrowprops
                   )
# labels
node_labels_dict = nx.draw_networkx_labels(G, pos, font_size=11, font_family="monospace", font_color='white', font_weight='bold',
                                           #alpha=1.0
                                           )

nodes_draw.set_zorder(zorder_nodes)
for node_labels_draw in node_labels_dict.values():
    node_labels_draw.set_zorder(zorder_node_labels)

pl.axis("off")
# do don't cut off nodes
ax.set_xlim([1.1*x for x in ax.get_xlim()])
ax.set_ylim([1.1*y for y in ax.get_ylim()])
pl.show()

The result:

Visualization of the resulting network

Background

You can change the zorder of the created matplotlib objects:

import networkx as nx
import matplotlib.pylab as pl
# an example graph with string (names) as nodes
g = nx.karate_club_graph()
pos = nx.kamada_kawai_layout(g)

e = nx.draw_networkx_edges(g, pos=pos, )
n = nx.draw_networkx_nodes(g, pos=pos, )

e.set_zorder(5) 
n.set_zorder(10)
pl.show()

In case you use some advanced edge drawing, add the zorder parameter to the arrowprops parameter (all possible parameters) of annotate, e.g.

arrowprops=dict(lw=G.edges[(source,target)]['weight'],
                        arrowstyle="-",
                        color='blue',
                        connectionstyle=f"arc3,rad={rad}",
                        linestyle= '-',
                        alpha=0.45,
                        zorder=0)

I've included this answer to avoid cutting nodes at the border.

like image 130
Sparky05 Avatar answered Sep 19 '22 13:09

Sparky05