0

I have following program that generates my graph and displays it on a single figure.

Edges2 = [(1, 2), (1, 3), (1, 4), (4, 5), (6, 7), (6,8)]

G = nx.DiGraph()

The function that generates the graph is as follows:

    def create_graph(G,nodes,Sets):

G.add_edges_from(nodes)

#value assigned to each world
custom_labels={}
custom_node_sizes={}
node_colours=['y']

for i in range(0, len(Sets)):
    custom_labels[i+1] = Sets[i]
    custom_node_sizes[i+1] = 5000
    if i < len(Sets):
        node_colours.append('b')

 

nx.draw(G,labels=custom_labels,node_list = nodes,node_color=node_colours, node_size=custom_node_sizes.values())
#show with custom labels
plt.show()

To the above function I am passing the list of edges (Edges2). The function generates two disconnected graphs on a single figure. However, I would like to save these two graphs separately.

So basically, is there a way of saving two disconnected graphs into two files? So, I can get graph1.png and graph2.png.

Community
  • 1
  • 1
marcincuber
  • 3,451
  • 1
  • 17
  • 29

2 Answers2

1

I did not quite get the 'Sets' input to your function or why do you add_edges_from(nodes) you use nodes as input and not edges!. So to answer your question of plotting disconnected graphs in 2 separate files I reproduced the problem without the custom_labels as it depends on the 'Sets' input and I sent the Edges2 as an input for nodes and Sets as well. As suggested by @joel I used the weakly_connected_component_subgraphs function and then looped the output of the function save each graph separately. So in the end the original graph is saved in original_graph.png , the subgraphs are saved in graph1.png and graph2.png respectively.

def create_graph(G,nodes,Sets):
    G.add_edges_from(nodes)

    #value assigned to each world
    custom_labels={}
    custom_node_sizes={}
    node_colours=['y']

    for i in range(0, len(Sets)):
        custom_labels[i+1] = Sets[i]
        custom_node_sizes[i+1] = 5000
        if i < len(Sets):
            node_colours.append('b')
    nx.draw(G,node_list = nodes,node_color=node_colours, node_size=1000, with_labels = True)
    plt.savefig("original_graph.png")
    plt.show()
    G_comp = nx.weakly_connected_component_subgraphs(G)
    i =  1 
    for comp in G_comp:
        nx.draw(comp,node_color=node_colours,  node_size=1000, with_labels=True)
        #show with custom labels
        fig_name = "graph" + str(i) + ".png"
        plt.savefig(fig_name)
        plt.show()
        i += 1


Edges2 = [(1, 2), (1, 3), (1, 4), (4, 5), (6, 7), (6,8)]
G = nx.DiGraph()
create_graph(G,Edges2,Edges2)

Original graph enter image description here

graph1 and graph2 enter image description here

EDITED BY AKI: I have added the labels which I needed (see comments). The last part of the code is:

    i =  1
    custom_number = 1;
    for comp in G_comp:
        dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ])
        wanted_keys = (range(custom_number,custom_number + len(comp)))
        newdict = dictfilt(custom_labels, wanted_keys)

        nx.draw(comp,node_color=node_colours,  node_size=1000, with_labels=True, labels = newdict)
        #show with custom labels
        fig_name = "graph" + str(i) + ".png"
        plt.savefig(fig_name)
        plt.show()
        custom_number += len(comp)
        i += 1

This improved version picks up necessary data from dictionary. Many thanks to @author of the answer

marcincuber
  • 3,451
  • 1
  • 17
  • 29
Abdallah Sobehy
  • 2,881
  • 1
  • 15
  • 28
  • The sets list could be as follows: Sets2 = [[('or', 'r', 't')], [('not', 'r'), 'r'], [('not', 's'), 'r'], ['r'], [('box', 's')],[('box', 'b')],[('box', 'b')], [('box', 'c')]] – marcincuber Nov 15 '15 at 13:52
  • And in fact if I use my labels it doesn't give me the correct graphs, the graph2 gives me an error. Is there a way of allowing these custom labels to be present on both seperated graphs? My labels work fine with the original graph but with the splitted graphs error is present – marcincuber Nov 15 '15 at 13:53
  • I still do not get what does 'Sets' represent but in general if you want to display labels, you have to create a **labels** dictionary which maps each node to a label then nx.draw(G, labels = labels, with_labels=True) – Abdallah Sobehy Nov 15 '15 at 13:56
  • The sets need to be displayed for each node. So rather placing 1, it needs to be [('or', 'r', 't')], it is important to display it rather than displaying numbers. When I did your suggested operation I am not getting the graph2 at all. I already have custom_labels={} can I reference it somehow so that each node correspond to one label in given order? – marcincuber Nov 15 '15 at 14:04
  • I had troubles understanding how you create your custom_labels, for instance why do you custom_label[i+1] by this you are not giving a label to node 0 ! – Abdallah Sobehy Nov 15 '15 at 14:08
  • The problem is solved and I added it to your answer. I believe it could be quite useful for this topic, is there a way of adding actual arrows to my graphs including reflexive arrows? – marcincuber Nov 15 '15 at 15:05
  • Great, I do not know about arrows in networkx but if you write into a gexf file using `write_gexf(G,"graph.gexf")` you can then open it with **gephi** and do a lot of manipulations to the figure you have – Abdallah Sobehy Nov 15 '15 at 17:44
0

since your graph is directed,you need to extract strongly connected components of your graph:

graphs = nx.strongly_connected_component_subgraphs(G)

more details can be found here
there are some other useful methods for components which you can find here

Iman Mirzadeh
  • 12,710
  • 2
  • 40
  • 44
  • `connected_component_subgraphs` doesn't give the **strongly** connected components, and in fact isn't written for directed graphs. You meant `strongly_connected_component_subgraphs`. **However** I think the OP actually wants weakly connected components: `weakly_connected_component_subgraphs`. It would also help if your answer gave instructions for how to plot the components separately. – Joel Nov 13 '15 at 22:17
  • yeah you were right, I meant strongly connected comp but I added wrong code.Thanks ;) – Iman Mirzadeh Nov 14 '15 at 00:19
  • I will test it later today, however if someone has written similar function that I need please share it :). – marcincuber Nov 14 '15 at 06:46
  • so for the input Edges2 = [(1, 2), (1, 3), (1, 4), (4, 5), (6, 7), (6,8)], I am using the following: graphs = list(nx.strongly_connected_component_subgraphs(G)) . My outcomes are: [, , ... ] I think something is wrong as I have 2 components and I am getting 8 of them... – marcincuber Nov 14 '15 at 07:23
  • Also how can I save each of them as a .png file? – marcincuber Nov 14 '15 at 07:25
  • @aki : so use weakly_conncted_component_subgraph method ! and Yes , you can save each of subgraph as a .png file.because as you see subgraph returns DiGraph object ! – Iman Mirzadeh Nov 14 '15 at 10:26