2
votes

I'm trying to create a subgraph based on a main graph I created that represents the data network of a project team. Where nodes are team members and edges are the data streams between them

The project team consists of different project roles: project manager, project assistant, engineer, etc. The nodes in the network have certain colors based on the project role of that node.

The data streams know certain frequencies (low, moderate, high, very high) and values (low, moderate, high, very high). The edges have certain widths based on the data stream frequencies and styles based on the data stream values.

My main graph looks like this: Main graph

Now I want to create a subgraph that highlights only the Project managers (yellow nodes) and the edges between them with same edge widths & styles. I've managed to create the subgraph of yellow nodes, but I don't know how to maintain the right edge widths & styles. These are my two results:

Option 1: Subgraph of yellow nodes with fixed edge width (5.0) and style (solid). Problem is that it doesn't show anything about the frequencies/values.

Subgraph 1

I use the code:

Graph_C_PDM = C.subgraph(nodelist_PDM)
plt.figure(figsize=(35,35))
pos = nx.kamada_kawai_layout(C)
nx.draw(C, pos, with_labels=True, alpha=0.2, edges=edges_C, width=edge_frequency_C, style=edge_value_C, edge_color='black', node_color=node_colors_C, node_size=3000, font_size=25)
nx.draw(Graph_C_PDM, pos, with_labels=True, edges=edges_C, width=5, style='solid', edge_color='black', node_color='gold', node_size=3000, font_size=25)
plt.savefig('Graph_C_PDM.pdf')

Option 2: Subgraph of yellow nodes with edge width and style lists of main graph. The problem is that it shows the wrong edge width and styles coming from the main graph list.

Subgraph 2

I use the code:

Graph_C_PDM = C.subgraph(nodelist_PDM)
plt.figure(figsize=(35,35))
pos = nx.kamada_kawai_layout(C)
nx.draw(C, pos, with_labels=True, alpha=0.2, edges=edges_C, width=edge_frequency_C, style=edge_value_C, edge_color='black', node_color=node_colors_C, node_size=3000, font_size=25)
nx.draw(Graph_C_PDM, pos, with_labels=True, edges=edges_C, width=edge_frequency_C, style=edge_value_C, edge_color='black', node_color='gold', node_size=3000, font_size=25)
plt.savefig('Graph_C_PDM.pdf')

I think I should create two separate lists that capture the edge frequencies and edge values of only the edges between the Project managers (yellow nodes). But I don't know how I should do that.

Can someone please help me?

Full code:

#Project C
#step 3.1: Create the empty graph.
C = nx.Graph()
#step 3.2: Call edges from pandas dataframe and set edge attributes by associated dataframe columns.
C = nx.from_pandas_edgelist(df_C, source='source', target='target', edge_attr=['edge_frequency','edge_value', 'edge_weight'])
#step 3.3: Create list of edges.
edges_C =C.edges()
#print(edges_C)
#step 3.4: Create edge list with edge frequency values from each row in the edge list.
edge_frequency_C = [C[u][v]['edge_frequency'] for u,v in edges_C]
#step 3.5: Create list with 'edge value' values from each row in the edge list.
edge_value_C = [C[u][v]['edge_value'] for u,v in edges_C]
#step 3.6: Create list with 'edge weight' values from each row in the edge list.
edge_weight_C = [C[u][v]['edge_weight'] for u,v in edges_C]
# print(edge_frequency_C)
# print(edge_value_C)
# print(edge_weight_C)

#Project C
#step 4.1: Retrieve the node and role information from the csv dataframes for each row and applicable columns.
node_attributes_C = []
for index, rows in df_C.iterrows():
    source_attributes_C = [rows.source, rows.source_role, rows.source_color]
    target_attributes_C = [rows.target, rows.target_role, rows.target_color]
    node_attributes_C.append(source_attributes_C)
    node_attributes_C.append(target_attributes_C)
#print(node_attributes_C)
#step 4.2: Remove duplicates to create a list of unique nodes and their associated attribute.
new_node_attributes_C = []
for item in node_attributes_C:
    if item not in new_node_attributes_C:
        new_node_attributes_C.append(item)
node_attributes_C=new_node_attributes_C
#print(node_attributes_C)
#print(len(node_attributes_C))
#step 4.3: Transform list [] format into dictionary format {key:value} for setting node attributes.
dict_node_roles_C={item[0]:item[1] for item in node_attributes_C}
dict_node_colors_C={item[0]:item[2] for item in node_attributes_C}
#print(dict_node_attributes_C)
#step 4.4: Set node attributes from the created dictionary to the existing nodes in the network.
nx.set_node_attributes(C, dict_node_roles_C, 'Role')
nx.set_node_attributes(C, dict_node_colors_C, 'Color')
#print(C.nodes(data=True))

#Project C
# step 5.1: Create empty list for adding node colors.
node_colors_C = []
#step 5.2: Retrieve the node color from each row of the unique node list and add it to the color list.
for item in node_attributes_C:
    node_colors_C.append(item[2])
# print(node_colors_C)

#Project C
#step 6.1: Set the size of the plot figure being big enough to present the graph.
plt.figure(figsize=(35,35))
#step 6.2: Set the layout style of the graph, here the Kamada Kawai layout is choosen.
pos = nx.kamada_kawai_layout(C)
#step 6.3: Creating the graph including desired graph, node and edge settings.
Graph_C = (nx.draw(C, pos, with_labels=True,edgelist=edges_C, width=edge_frequency_C, style=edge_value_C, edge_color='black', node_color=node_colors_C, node_size=3000, font_size=25))
#step 6.4: Saving the graph as a PDF file.
plt.savefig('Graph_C.pdf')
#step 6.5: Visualizing the graph.
plt.show(Graph_C)

# Step 7: Creating the role specific nodelists. 
nodelist_PDM = []
for (u,v) in C.nodes(data=True):
    if v['Role'] == 'Project / Design management':
        nodelist_PDM.append(u)
print(nodelist_PDM)

# Step 8: Mapping the data sharing networks for specific roles in the project.
# Project / Design management
Graph_C_PDM = C.subgraph(nodelist_PDM)
plt.figure(figsize=(35,35))
pos = nx.kamada_kawai_layout(C)
nx.draw(C, pos, with_labels=True, alpha=0.2, edges=edges_C, width=edge_frequency_C, style=edge_value_C, edge_color='black', node_color=node_colors_C, node_size=3000, font_size=25)
nx.draw(Graph_C_PDM, pos, with_labels=True, edges=edges_C, width=edge_frequency_C, style=edge_value_C, edge_color='black', node_color='gold', node_size=3000, font_size=25)
plt.savefig('Graph_C_PDM.pdf')
1

1 Answers

1
votes

I think I should create two separate lists that capture the edge frequencies and edge values of only the edges between the Project managers (yellow nodes). But I don't know how I should do that.

You can filter your your edge data lists by checking if the corresponding edge only contains nodes that represent your project managers. For example:

edges_PDM = []
edge_frequency_PDM = []
edge_value_PDM = []
for ii, (a, b) in in enumerate(edges_C):
    if a in node_list_PDM and b in node_list_PDM:
        edges_PDM.append((a, b))
        edge_frequency_PDM.append(edge_frequency_C[ii])
        edge_value_PDM.append(edge_value_C[ii])

On a different note, this was a very well asked first question. Next time, it would be great if you also include some example data so anybody attempting to answer your question can easily determine if the answer actually yields the correct result.