hbstha123
hbstha123

Reputation: 1646

Is it possible to increase the width of node in networkx graph so that the labels are within nodes?

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 enter image description here 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:

enter image description here

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? enter image description here

Upvotes: 1

Views: 454

Answers (1)

SultanOrazbayev
SultanOrazbayev

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

Related Questions