Reputation: 1646
I have created a directed networkx graph using following nodes, edges and label for each nodes:
G = nx.DiGraph()
#Add nodes
G.add_nodes_from([0,1,2,3,4,5,6,7,8,9, 10, 11, 12, 13, 14, 15, 16])
#Specify the edges
G.add_edges_from([(0,12),
(1,8),
(2,8),
(3,4), (3,6),
(4,3),
(5,9),
(7,10),
(8,12),
(9, 10),
(10, 13), (10, 15),
(11, 13),
(12, 15),
(13, 16),
(14, 16)])
#Specify the position of nodes
pos = {0:(0, 700),
1:(0, 600),
2:(0, 500),
3:(0, 400),
4:(0, 300),
5:(0, 200),
6:(0, 100),
7:(0, 0),
8:(50, 550),
9:(50, 200),
10:(50, 0),
11:(50, -100),
12:(100, 550),
13:(100, -100),
14:(100, -200),
15:(150, 0),
16:(150, -200)}
#Specify the label for each nodes
labels = {}
labels[0] = "Fuel mix per mode"
labels[1] = "Specific energy intensity per fuel\n per mode (MJ/vkm)"
labels[2] = "Specific emissions per fuel\n (gCO2/MJ)"
labels[3] = "Total freight transport activity\n (tkm)"
labels[4] = "Per capita freight transport\n activity (tkm/cap)"
labels[5] = "Modal split (% of tkm)"
labels[6] = "Load factor (tkm/vkm)"
labels[7] = "Share of tkm electrified\n per mode (%)"
labels[8] = "Emissions intensity per fuel\n (gCO2/vkm)"
labels[9] = "Amount of vehicle-kilometers\n (vkm) per mode"
labels[10] = "Amount of electrified and\n non-electrified vkm per mode"
labels[11] = "Power demand of electrified\n transport per mode (kWh/vkm)"
labels[12] = "Average emissions intensity of\n non-electrified transport (gCO2/vkm)"
labels[13] = "Electrified demand of electrified\n transport per mode (kWh)"
labels[14] = "Emissions intensity of electricity\n (gCO2/kWh)"
labels[15] = "Emissions from non-electrified\n transport (MtCO2)"
labels[16] = "Emissions from electrified transport\n (MtCO2)"
I'd like to get a logic tree diagram as shown
where the number refer to each nodes.
I specified the node color, edge color and border color of different nodes and plotted the graph as follows:
plt.figure(figsize = (16, 12))
nodes = np.arange(0, 17).tolist()
node_colors = ["silver","whitesmoke","whitesmoke","whitesmoke","silver",
"silver","silver","silver","silver","whitesmoke",
"whitesmoke","whitesmoke","silver","whitesmoke",
"whitesmoke","whitesmoke","whitesmoke"]
edges_colors = ["black","black","black", "black","black","black","black",
"red","red","red","red","red","red","red","red","blue"]
border_colors = ["brown","brown","brown","brown","red","brown","brown","brown",
"red","red","red","brown",
"red","red","blue",
"green","green"]
nx.draw_networkx(G, node_shape = "s", pos = pos, node_size = 2000,
node_color = node_colors,
edge_color = edges_colors, #color of the edges
edgecolors = border_colors, #color of border of nodes
labels = labels,
with_labels = True,
)
I get the plot as shown:
The labels are outside the nodes. I found that it is possible to add bbox = dict()
inside nx.draw_networkx()
to get the labels inside bounding box as shown below. However, I also want to have unique node color, and border color for each node. All the nodes became of same color while adding bbox = dict()
. And the arrows are further hidden by bbox. So how can I get the labels within the border of nodes while still having unique colors affiliated to nodes?
I think this is partly possible using matplotlib.patches.Rectangle
. However, the arrows got hidden when I used patches. It seems that the node_shape
take the similar form of markers in scatter plots in matplotlib. I can only increase the size of the node as a whole. But I'd like to get a rectangular node instead of square. Is it also possible to increase only the width of node here to enclose the labels within its boundary?
Upvotes: 1
Views: 454
Reputation: 16581
As noted in the comments by @Lrrr, networkx
might not be appropriate for highly-customized visualizations. Given your example, one great alternative is mermaid
. There is a blog post that explains how to convert networkx
to mermaid
syntax (via graphml
).
Upvotes: 0