先上一个需求图片:用思维导图画的重卡换电站的配电系统图
图中,10-0-01表示10kV进线断路器,B01和B02代表两个变压器,4-0-01表示变压器的低压侧断路器,这个断路器会分成几段母线,分别接至各个负载的出线断路器,比如4-1-02等。如果智能箱变的物联网传过来的设备编号如下所示,如何画出上图中的配电接线呢?
swap_id = {'100550'}
vcb_id = {'10-1-01'}
transformer_id = {'B01'}
input_acb_id = {'4-0-01'}
output_acb_id = {'4-2-20', '4-1-01', '4-2-05', '4-2-51', '4-2-08', '4-1-06', '4-1-03', '4-2-50', '4-1-02', '4-2-04', '4-1-07'}
我找到了python可视化的包pyecharts,里面有一个树形图就是专门画这种思维导图的
第1个参数:symbol 标记的图形,根据下面的表格,我选了矩形
标记 | 图形 |
emptyCircle | 空心圆 |
circle | 圆 |
rect | 矩形 |
roundRect | 圆角矩形 |
triangle | 三角形 |
diamond | 菱形 |
pin | 针形 |
arrow | 尖头 |
第2个参数:symbol_size 标记图形的大小,根据需求的样式,我设置成[50,20]
第3个参数:pos_left,标记左边的距离,为了防止标记互相重叠,我设置成50
第4个参数:edge_shape,连接线的样式,curve表示曲线,polyline表示折线,如需求图所示,我设置成polyline
第5个参数:initial_tree_depth,初始化时树的深度,因为树的层级过多,初始化时会自动收缩部分层级,为了全部显示所有层级,我设置成尽可能大的值:8
第6个参数:orient,思维导图的方向,如下图所示,我选择TB(从上到下)
标记 | 样式 |
LR | 从左到右 |
RL | 从右到左 |
TB | 从上到下 |
BT | 从下到上 |
最后,上代码,里面可以看到如何构建树形图的数据
from pyecharts import options as opts
from pyecharts.charts import Tree
from pyecharts.render import make_snapshot
from snapshot_selenium import snapshot
import pandas as pd
station_name = "重卡换电站"
swap_id_set = {'100550'}
vcb_id_set = {'10-1-01'}
transformer_id_set = {'B01'}
input_acb_set = {'4-0-01'}
output_acb_set = {'4-2-20', '4-1-01', '4-2-05', '4-2-51', '4-2-08', '4-1-06', '4-1-03', '4-2-50', '4-1-02', '4-2-04', '4-1-07'}
# 画出系统配置图
output_acb_dict = []
for item in list(output_acb_set):
lv_bus = item.split('-')[1]
output_acb_dict.append({
'lv_bus': lv_bus,
'load': item})
df_load = pd.DataFrame(output_acb_dict).groupby(['lv_bus'])['load'].apply(list).reset_index()
# 画出根结点:换电站编号
data = [{"name": list(swap_id_set)[0]}]
# 画出换电站编号的子结点:高压断路器编号
data[0]['children'] = [{"name": list(vcb_id_set)[0]}]
# 画出高压断路器的子结点:变压器编号
data[0]['children'][0]['children'] = [{"name": list(transformer_id_set)[0]}]
# 画出变压器的子结点:低压进线断路器编号
data[0]['children'][0]['children'][0]['children'] = [{"name": list(input_acb_set)[0]}]
# 画出低压进线断路器的子结点:低压母线
data[0]['children'][0]['children'][0]['children'][0]['children'] = []
for index, item in df_load.iterrows():
lv_bus = item['lv_bus']
data[0]['children'][0]['children'][0]['children'][0]['children'].append(
{"name": f"{item['lv_bus']}段低压"}
)
data[0]['children'][0]['children'][0]['children'][0]['children'][index]['children'] = []
# 在每段低压母线下画出负载
for load in item['load']:
load_code = int(load.split('-')[2])
if load_code < 20:
data[0]['children'][0]['children'][0]['children'][0]['children'][index]['children'].append(
{
"name": load,
"children": [{"name": f"架载机{load_code}"}]
}
)
elif 20 <= load_code < 30:
data[0]['children'][0]['children'][0]['children'][0]['children'][index]['children'].append(
{
"name": load,
"children": [{"name": "站用电"}]
}
)
elif 30 <= load_code < 40:
data[0]['children'][0]['children'][0]['children'][0]['children'][index]['children'].append(
{
"name": load,
"children": [{"name": "SVG"}]
}
)
elif 40 <= load_code < 50:
data[0]['children'][0]['children'][0]['children'][0]['children'][index]['children'].append(
{
"name": load,
"children": [{"name": "其它"}]
}
)
elif 50 <= load_code < 60:
data[0]['children'][0]['children'][0]['children'][0]['children'][index]['children'].append(
{
"name": load,
"children": [{"name": "备用电"}]
}
)
else:
data[0]['children'][0]['children'][0]['children'][0]['children'][index]['children'].append(
{
"name": load,
"children": [{"name": "充电桩"}]
}
)
c = (
Tree()
.add("", data, orient='TB', edge_shape='polyline', initial_tree_depth=8,
symbol='rect', symbol_size=[50, 20], pos_left=50)
.set_global_opts(title_opts=opts.TitleOpts(title=station_name))
)
make_snapshot(snapshot, c.render(), "配电系统图.png")