The following code tries to place a label for each node apart from the one that is by default included by NetworkX/Matplotlib. The original positions of the nodes are obtained through the call to "nx.spring_layout(g)".
The problem is that, when it comes to draw with Matplotlib the labels, the latter are misplaced, as it can be seen in the attached graph.
Should I be doing something differently?
import logging
import networkx as nx
import matplotlib.pyplot as plt
__log = logging.getLogger(__name__)
g = nx.Graph()
nodes = ['shield', 'pcb-top', 'pcb-config', 'chassis']
for k in nodes:
g.add_node(k)
plt.figure(figsize=(8, 11), dpi=150)
nx.draw(g, with_labels=True)
node_cfg = nx.spring_layout(g)
for k, node in node_cfg.items():
__log.debug('node = %s #(%.6f, %.6f)', k, node[0], node[1])
plt.text(node[0], node[1], k, bbox={'color': 'grey'})
plt.savefig('test.png')
Use the same position information for the network drawing as for the labels.
node_cfg = nx.spring_layout(g)
plt.figure(figsize=(8, 11), dpi=150)
nx.draw(g, pos=node_cfg, with_labels=True)
Related
I am trying to create bipartite of certain nodes, for small numbers it looks perfectly fine:
Image for around 30 nodes
Unfortunately, this isn't the case for more nodes like this one:
Image for more nodes
My code for determining the position of each node looks something like this:
pos = {}
pos[SOURCE_STRING] = (0, width/2)
row = 0
for arr in left_side.keys():
pos[str(arr).replace(" ","")]=(NODE_SIZE, row)
row += NODE_SIZE
row = 0
for arr in right_side.keys():
pos[str(arr).replace(" ","")]=(2*NODE_SIZE,row)
row += NODE_SIZE
pos[SINK_STRING] = (3*NODE_SIZE, width/2)
return pos
And then I feed it to the DiGraph class:
G = nx.DiGraph()
G.add_nodes_from(nodes)
G.add_edges_from(edges, len=1)
nx.draw(G, pos=pos ,node_shape = "s", with_labels = True,node_size=NODE_SIZE)
This doesn't make much sense since they should be in the same distance from each other since NODE_SIZE is constant it doesn't change for the rest of the program.
Following this thread:
Bipartite graph in NetworkX
Didn't help me either.
Can something be done about this?
Edit(Following Paul Brodersen Advice using netGraph:
Used this documentation: netgraph doc
And still got somewhat same results, such as:
netgraph try
Using edges and different positions, also played with node size, with no success.
Code:
netgraph.Graph(edges, node_layout='bipartite', node_labels=True)
plt.show()
In your netgraph call, you are not changing the node size.
My suggestion with 30 nodes:
import numpy as np
import matplotlib.pyplot as plt
from netgraph import Graph
edges = np.vstack([np.random.randint(0, 15, 60),
np.random.randint(16, 30, 60)]).T
Graph(edges, node_layout='bipartite', node_size=0.5, node_labels=True, node_label_offset=0.1, edge_width=0.1)
plt.show()
With 100 nodes:
import numpy as np
import matplotlib.pyplot as plt
from netgraph import Graph
edges = np.vstack([np.random.randint(0, 50, 200),
np.random.randint(51, 100, 200)]).T
Graph(edges, node_layout='bipartite', node_size=0.5, node_labels=True, node_label_offset=0.1, edge_width=0.1)
plt.show()
I have created a knowledge graph from below dataframe using spacy and networkx library in Python.
Now I want to visualize this Graph in Protege. Is this possible? If yes then how this can be done?
I am attaching the dataframe and code for creating the Graph below.
kg_df = pd.DataFrame({'source':source, 'target':target, 'edge':relations})
G=nx.from_pandas_edgelist(kg_df, "source", "target",
edge_attr=True, create_using=nx.MultiDiGraph())
plt.figure(figsize=(12,12))
pos = nx.spring_layout(G, k = 0.5) # k regulates the distance between nodes
nx.draw(G, with_labels=True, node_color='skyblue', node_size=1500, edge_cmap=plt.cm.Blues, pos = pos)
plt.show()
print(kg_df)
I wonder how I can add the edge weights to my Bokeh plot (from NetworkX), preferably for edge_renderer.hover_glyph, like in this picture:
A possible answer for this problem is using nx.get_edge_attributes and pass the values to draw_networkx_edge_labels as the labels for the edges.
Here's the so awaited code:
pos=nx.spring_layout(G)
nx.draw_networkx(G, pos)
labels = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels)
Here's a full working example:
import networkx as nx
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(4,4))
G = nx.Graph()
G.add_node('A', pos="1,3!", demand=-10)
G.add_node('B', pos="3,5!")
G.add_node('C', pos="3,1!")
G.add_node('D', pos="4,3!")
G.add_node('E', pos="5,5!")
G.add_node('F', pos="5,1!")
G.add_node('G', pos="7,3!", demand=10)
G.add_edge('A','B',weight=20,capacity=20,label='(20,20)')
G.add_edge('A','C',weight=7,capacity=15,label='(7,15)')
G.add_edge('B','E',weight=16,capacity=21,label='(16,21)')
G.add_edge('B','D',weight=4,capacity=4,label='(4,4)')
G.add_edge('C','F',weight=3,capacity=9,label='(3,9)')
G.add_edge('C','D',weight=4,capacity=4,label='(4,4)')
G.add_edge('D','E',weight=2,capacity=2,label='(2,2)')
G.add_edge('D','F',weight=6,capacity=10,label='(6,10)')
G.add_edge('E','G',weight=18,capacity=24,label='(18,24)')
G.add_edge('F','G',weight=9,capacity=10,label='(9,10)')
pos=nx.spring_layout(G)
nx.draw_networkx(G, pos)
labels = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels)
I am trying to create timetables or cardioid graph using network in python this is my code
import matplotlib.pyplot as plt
import networkx as nx
G = nx.Graph()
n = 10
for i in range(1,n):
if i*2 < n:
G.add_node(i, weight=i)
G.add_node(i*2, weight=i*2)
G.add_edge(i, i*2)
else:
G.add_node(i, weight=i)
G.add_node(i*2-n, weight=i*2-n)
G.add_edge(i,i*2 - n)
plt.figure(figsize=(10,6))
nx.draw_networkx(G, pos=nx.circular_layout(G), node_size=1000)
But then I am getting something like this
enter image description here
Whereas I want nodes to be in a a sorted manner like 0,1,2... in circular format, how do I achieve that?
You can achieve it by using
nx.draw_networkx(G, pos=nx.circular_layout(sorted(G.nodes()), node_size=1000)
to get the nodes sorted in an anticlockwise manner.
Otherwise, for a clockwise ordering you can use
nx.draw_networkx(G, pos=nx.circular_layout(sorted(G.nodes(), reverse=True)), node_size=1000)
Example:
I am plotting directed graph using networkx in python. However, I found that arrow head of edge is thick from one end instead of pointed arrow. I want to change the thick edge to pointed arrow. Here is my code, actual output, and desired output:
import networkx as nx
import matplotlib.pyplot as plt
G=nx.DiGraph()
item = [1,2]
G.add_edge(*item) #color = item[-1], weight = 2)
pos = nx.circular_layout(G)
nx.draw(G, pos, with_labels = True, edge_color = 'b')
plt.show()
Output
Desired output:
Any suggestion would be really helpful?
This may be a late answer, but in the new version networkx 2.1 you can set the arrow type by using the arrowstyle and arrowsize parameter.
import networkx as nx
import matplotlib.pyplot as plt
G=nx.DiGraph()
item = [1,2]
G.add_edge(*item) #color = item[-1], weight = 2)
pos = nx.circular_layout(G)
nx.draw(G, pos, with_labels = True, edge_color = 'b', arrowsize=20, arrowstyle='fancy')
plt.show()
You can go to the documentation for details: https://networkx.github.io/documentation/stable/reference/generated/networkx.drawing.nx_pylab.draw_networkx_edges.html#networkx.drawing.nx_pylab.draw_networkx_edges
Good news. This is possible now with the development version of networkx (will be networkx-2.1). Your code now now draws arrows
In [5]: import networkx as nx
...: import matplotlib.pyplot as plt
...:
...: G=nx.DiGraph()
...:
...: item = [1,2]
...:
...: G.add_edge(*item) #color = item[-1], weight = 2)
...:
...: pos = nx.circular_layout(G)
...: nx.draw(G, pos, with_labels = True, edge_color = 'b')
...: plt.show()
...:
This is not possible with nx.draw for now. According to https://github.com/networkx/networkx/blob/master/networkx/drawing/nx_pylab.py#L584 , it hasn't been implemented yet.
However, you can try to use graphviz to plot your graph. Networkx has an interface to convert your graph to graphviz object easily. See https://networkx.github.io/documentation/stable/reference/drawing.html#module-networkx.drawing.nx_agraph.