我想创建具有层次关系的复杂数据图。为简单起见,我创建了有关问题的小样本数据。
样本数据
DS PNL Type Load
DS-1 PNL-101 Normal Power Room 1, Room 2, Room 3
DS-1 PNL-102 Normal Power Room 4, Room 5
DS-1 PNL-103 Emergency Room 6, Room 7
DS-1 PNL-104 Emergency Room 8
DS-2 PNL-201 Emergency Office 1, Office 2
DS-2 PNL-202 Normal Power Office 3, Workshop
DS-2 PNL-203 Light Corridors
DS-3 PNL-301 Normal Power Equipment 1, Equipment 2
DS-4 None Normal Power Road
数据在excel中,我已将其作为pandas数据框导入。 我想创建一个图形,使它显示连接到“ DS”的“ PNL”和连接到每个“ PNL”的“负载”。我需要用定界符“,”分隔“负载”列,以获取单独的负载,例如DS-1至PNL-101的第1室,第2室,第3室。
我尝试了以下代码,在某种程度上可以完成这项工作。它创建了图,但是问题是每个PNL都连接到每个Load(这是错误的)。
例如,如果我要为包含DS-2的所有实例绘制图形,则预期图形应为DS-2与PNL-202,PNL-202和PNL-203连接(我已经实现了)。同样,PNL-201仅应与Office 1和Office 2连接。PNL-202应与Office 3和Workshop连接。 PNL-203应该仅与走廊连接。
import numpy as np
import pandas as pd
import matplotlib as plt
import networkx as nx
#import pygraphviz as pgv
from graphviz import Graph, Digraph
import graphviz # https://www.graphviz.org/doc/info/shapes.html
df = pd.read_excel('data.xlsx')
g = Graph(format='png')
def show_impact(item):
'''
Input: The partial string to search in the dataframe df.
All the rows which contains the string "item", are extracted to
form another dataframe df0.
Output: Plot the graph of the extracted small dataframe.
'''
# Search all rows that contains the string "item".
s = df.stack() # convert entire data frame into a series of values
df0 = df.iloc[s[s.str.contains(item,na=False)].index.get_level_values(0)]
# Load column to list of individual locations
loc = df0['Load'].str.split(',',expand=True).values.tolist()
# Draw Nodes First
for i, row in df0.iterrows():
for j, col in enumerate(df0):
# Draw DS Nodes
g.node(str(row['DS']), style='filled', shape='rect', color='#FF5733')
# Draw PNL nodes
g.node(str(row['PNL']), style='filled', shape='rect', color='#FFC300')
# Draw Load nodes
for k in loc:
for l in k:
g.node(str(l), style='filled', shape='rect', color='#C0C0C0')
# Edges (DS-PNL)
for i, row in df0.iterrows():
g.edge(str(row['DS']), str(row['PNL']), color='red', label='')
# Edges (PNL-Loads)
for i, row in df0.iterrows():
for k in loc:
for l in k:
g.edge(str(row['PNL']), str(l), color='red', label='')
g.view()
show_impact('DS-2')