攝影或3C

Python: 如何使用graphviz套件繪製U型流程圖? with g.subgraph() as s: s.attr(rank=’same’) 如何使用U形排列,營造出node下方有label的效果?取代xlabel功能

code:

# -*- coding: utf-8 -*-
"""
Created on Mon Nov 10 15:35:58 2024

@author: SavingKing
"""


from graphviz import Digraph

# 创建一个有向图设置其布局为从左到右
g = Digraph('G', filename='process_graph.gv', format='png', engine='dot')
g.attr(rankdir='LR')
"""g = Digraph('G', filename='process_graph.gv', format='png', engine='dot', 
graph_attr={'rankdir': 'LR'})
"""

# 添加节点,替换原有节点名称为A, B, C, ...
g.node('A', 'A ')
g.node('B', 'B ')
g.node('C', 'C ')
g.node('D', 'D ')
g.node('E', 'E ')
g.node('F', 'F ')
g.node('G', 'G ')
g.node('H', 'H ')
g.node('I', 'I ')

# 添加边根据流程逐步连接节点
g.edge('A', 'B')
g.edge('B', 'C')
g.edge('C', 'D')
g.edge('D', 'E')
g.edge('E', 'F')
g.edge('F', 'G')
g.edge('G', 'H')
g.edge('H', 'I')

# 创建子图以设置特定节点的排列
# 将D, E, F在同一水平线上
with g.subgraph() as s:
    s.attr(rank='same')
    s.node('D')
    s.node('E')
    s.node('F')

# 将C和G在同一水平线上
with g.subgraph() as s:
    s.attr(rank='same')
    s.node('C')
    s.node('G')

# 将B和H在同一水平线上
with g.subgraph() as s:
    s.attr(rank='same')
    s.node('B')
    s.node('H')

# 将A和I在同一水平线上
with g.subgraph() as s:
    s.attr(rank='same')
    s.node('A')
    s.node('I')

# 渲染图形
g.render('process_graph', view=True)

輸出的圖檔:

Digraph?

在 Graphviz 的 Python 包中,graph_attrnode_attredge_attr 的說明中提到的 “Mapping of (attribute, value) pairs” 實際上是指這些屬性可以由一個映射型態(如字典)來設定,其中包含多個屬性和值的組合。這裡的 (attribute, value) 表示的是鍵值對,而不是指具體使用 tuple 類型來儲存這些屬性。

在 Python 中,字典(dict)是一種常用的映射型態,用來儲存和處理鍵值對。當文檔中提到 (attribute, value) 對時,它是一種通用的說法,用來表達任何形式的鍵和值的組合。實際上,在用 Python 接口操作時,我們通常會使用字典來表示這些對,因為字典提供了一個簡單且直接的方式來管理這些屬性。

例如,當你設定 graph_attr

graph_attr={'rankdir': 'LR'}

這裡使用的是一個字典來存儲屬性名稱 rankdir 和它的值 LR。這是因為字典可以非常方便地以 key: value 的形式存儲和訪問數據。

因此,雖然文檔用 (attribute, value) 這種說法可能讓人聯想到 tuple,實際上在實作時使用的是字典,這是因為字典在處理這類映射關係時更為直觀和方便。

推薦hahow線上學習python: https://igrape.net/30afN

如何使用子圖label取代node的xlabel 
因為無法控制xlabel的位置
自動出現在node的左下方
採用子圖僅有一個node,
子圖label取代xlabel
營造出node上方有label的效果
運用本篇的U形排列
去掉原本的node E
edge使用style="invis"
要當成label的node使用shape="plaintext"
以及調整nodesep="0.1"
營造出node下方有label的效果
注意註解掉的node,
子圖中若有定義該node
主圖不用重複定義
code:

# -*- coding: utf-8 -*-
"""
Created on Mon Nov 10 15:35:58 2024

@author: SavingKing
"""


from graphviz import Digraph

# 创建一个有向图设置其布局为从左到右
g = Digraph('G', filename='process_graph.gv', format='png', engine='dot')
g.attr(rankdir='LR',nodesep="0.1")
"""g = Digraph('G', filename='process_graph.gv', format='png', engine='dot', 
graph_attr={'rankdir': 'LR'})
"""

# 添加节点,替换原有节点名称为A, B, C, ...
# g.node('A', 'A ')
# g.node('B', 'B ')
# g.node('C', 'C ')
# g.node('D', 'D ')
# #g.node('E', 'E ')
# g.node('F', 'F ')
# g.node('G', 'G ')
# g.node('H', 'H ')
# g.node('I', 'I ')

# 添加边根据流程逐步连接节点
g.edge('A', 'B')
g.edge('B', 'C')
g.edge('C', 'D')

#g.edge('D', 'E')
#g.edge('E', 'F')
g.edge('D', 'F',style="invis") #

g.edge('F', 'G',style="invis")
g.edge('G', 'H',style="invis")
g.edge('H', 'I',style="invis")

# 创建子图以设置特定节点的排列
# 将D, E, F在同一水平线上
with g.subgraph() as s:
    s.attr(rank='same')
    s.node('D')
    #s.node('E')
    s.node('F',shape="plaintext")

# 将C和G在同一水平线上
with g.subgraph() as s:
    s.attr(rank='same')
    s.node('C')
    s.node('G',shape="plaintext")

# 将B和H在同一水平线上
with g.subgraph() as s:
    s.attr(rank='same')
    s.node('B')
    s.node('H',shape="plaintext")

# 将A和I在同一水平线上
with g.subgraph() as s:
    s.attr(rank='same')
    s.node('A')
    s.node('I',shape="plaintext")

# 渲染图形
g.render('process_graph', view=True)

輸出的圖檔:

推薦hahow線上學習python: https://igrape.net/30afN

儲蓄保險王

儲蓄險是板主最喜愛的儲蓄工具,最喜愛的投資理財工具則是ETF,最喜愛的省錢工具則是信用卡