Python画流程图,从0到实践,完整版(附源码)

文摘   2024-10-21 19:35   北京  

ISEE小语


“人生中最尴尬的事,莫过于高估了自己和别人的关系。”
——网友




通过Python画流程图,在日常工作中特定的场景中会使用到,本次在实践中遇到的问题一步一步的解决,有心分享,有使用到的同学可共勉!

在Python中,使用graphviz库可以非常方便地绘制流程图。graphviz是一个开源的图形可视化软件,可以生成各种图形,包括流程图。



先看实际效果

画了一简化的项目流程图

注:流程图有些细节可能与实际不符,请忽略^^

接下来,我们一步一步的操作,以下可能会有些啰嗦,别介意,因为第一次使用,踩坑了!



前期准备

环境

Pycharm

Python 3.9.16


三方库

pip install graphviz==0.20.3



安装软件

安装Graphviz软件,是必须的,在各个系统的安装如下:

macOS:使用Homebrew安装

brew install graphviz


Linux:使用包管理器安装(以Ubuntu为例)

sudo apt-get install graphviz


Windows:下载安装程序

https://graphviz.org/download/

小栈使用的是Windows系统,这里着重介绍一下安装步骤:

1、下载,小栈直接下载第一个

默认下载最新的即可,如果遇到不兼容的情况,可以下载其他较低的版本,在官网中都可以找到,根据实际情况而定!


2、右击graphviz-install-12.1.2-win64.exe,以管理员身份运行


3、根据提示安装

注:在这里选择加入环境变量,就不需要手动设置了



4、重启系统方可使用

小栈亲测,在windows 10下面安装完成后,需要重启一下系统才可以使用,其他系统,暂不清楚!


基本使用


我们从简单、复杂和多样化的方面,了解如何使用。

简单流程图

# -*- coding: utf-8 -*-from graphviz import Digraph

def create_flowchart(): dot = Digraph(comment='Simple Flowchart')
# 添加节点 dot.node('A', '开始') dot.node('B', '步骤 1') dot.node('C', '步骤 2') dot.node('D', '结束')
# 添加边(有向) dot.edges(['AB', 'BC', 'CD'])
# 保存并显示 dot.render('simple_flowchart', format='png', view=True)

create_flowchart()

看一下结果:

中文变成了乱码,试了一下英文的情况没有这问题,那接下来针对中文乱码的问题解决一下。

这个时候,我们需要设置字体属性,以SimSun为例:

# -*- coding: utf-8 -*-from graphviz import Digraph

def create_flowchart(): dot = Digraph(comment='Simple Flowchart')
# 设置全局字体属性(以SimSun为例) fontname = 'SimSun' dot.attr(fontname=fontname)
# 添加节点 dot.node('A', '开始', fontname=fontname) dot.node('B', '步骤 1', fontname=fontname) dot.node('C', '步骤 2', fontname=fontname) dot.node('D', '结束', fontname=fontname)
# 添加边(有向) dot.edges(['AB', 'BC', 'CD'])
# 保存并显示 dot.render('simple_flowchart_02', format='png', view=True)

create_flowchart()

再看一下结果:



复杂流程图

复杂流程图,我们添加了不同节点形状、判断和字体大小

使用Graphviz中的shape属性来设置节点的形状:

  • 开始节点(通常用椭圆形):shape='ellipse'

  • 判断节点(通常用菱形):shape='diamond'

  • 过程节点(通常用长方形):shape='box'


# -*- coding: utf-8 -*-from graphviz import Digraph

def create_flowchart(): dot = Digraph(comment='Complexity Flowchart')
# 设置全局字体属性(以SimSun为例) fontname = 'SimSun' fontsize = '10' dot.attr(fontname=fontname, splines='ortho')
# 添加节点并设置形状 dot.node('开始', '开始', shape='ellipse', fontname='SimSun') dot.node('步骤1', '步骤 1', shape='box', fontname='SimSun') dot.node('步骤2', '步骤 2', shape='box', fontname='SimSun') dot.node('条件判断', '是否通过', shape='diamond', fontname='SimSun') dot.node('结束', '结束', shape='ellipse', fontname='SimSun')
# 添加边 dot.edge('开始', '步骤1') dot.edge('步骤1', '步骤2') dot.edge('步骤2', '条件判断') dot.edge('条件判断', '步骤1', xlabel='不通过', fontname='SimSun', constraint='false', fontsize=fontsize) dot.edge('条件判断', '结束', xlabel='通过', fontname='SimSun', fontsize=fontsize)
# 保存并显示 dot.render('complexity_flowchart', format='png', view=True)

create_flowchart()

看一下结果:

附:

关于Graphviz 支持多种节点形状,梳理了一些常见的:
ellipse - 默认椭圆形box - 矩形diamond - 菱形circle - 圆形plaintext - 仅文本,不显示边框hexagon - 六边形octagon - 八边形triangle - 三角形parallelogram - 平行四边形trapezium - 梯形
请根据所画流程图实际需求进行使用。



多样化流程图

多样化流程图,我们添加了不同节点的颜色,及横向和流程的配合使用。换个说法就是美化。

使用Graphviz中的rankdir属性来设置流程图的方向:

  • 设置LR:从左到右(横向)

  • 设置RL:从右到左(横向)

  • 设置TB:从上到下(纵向)

  • 设置BT:从下到上(纵向)


# -*- coding: utf-8 -*-from graphviz import Digraph

def create_flowchart(): dot = Digraph(comment='Complexity Flowchart')
# 设置全局字体属性(以SimSun为例) fontname = 'SimSun' fontsize = '10'
dot.attr(fontname=fontname, splines='ortho', rankdir='TB')
# 添加节点并设置形状 dot.node('开始', '开始', shape='ellipse', fontname='SimSun', style='filled', color='lightblue') dot.node('步骤1', '步骤 1', shape='box', fontname='SimSun', style='filled', color='lightgreen') dot.node('步骤2', '步骤 2', shape='box', fontname='SimSun', style='filled', color='lightgreen') dot.node('步骤3', '步骤 3', shape='box', fontname='SimSun', style='filled', color='lightgreen') dot.node('条件判断', '是否通过', shape='diamond', fontname='SimSun', style='filled', color='lightyellow') dot.node('结束', '结束', shape='ellipse', fontname='SimSun', style='filled', color='lightcoral')
# 添加边 dot.edge('开始', '步骤1') dot.edge('步骤1', '步骤2') with dot.subgraph() as s: s.attr(rank='same') s.edge('步骤2', '步骤3', label='输出', fontname='SimSun', fontsize=fontsize) dot.edge('步骤2', '条件判断') dot.edge('条件判断', '步骤1', xlabel='不通过', fontname='SimSun', constraint='false', color='red', fontsize=fontsize) dot.edge('条件判断', '结束', xlabel='通过', fontname='SimSun', fontsize=fontsize)
# 保存并显示 dot.render('complexity_flowchart_02', format='png', view=True)

create_flowchart()

结果:



实战


我们实践一个项目的简化流程图。

项目流程图

项目流程模块比较多,分为项目立项、需求阶段、设计阶段、研发阶段、测试阶段和项目结束。

这些阶段只是一个简化的,仅限学习,如果用到实际工作中,可能会有些许不适用,毕竟每个公司的流程多多少少会有些差异!

核心代码如下:

# -*- coding: utf-8 -*-from graphviz import Digraph

def create_flowchart(): dot = Digraph(comment='项目简化流程图')
# 设置全局字体属性(以SimSun为例) fontname = 'SimSun' fontsize = '10'
dot.attr(fontname=fontname, splines='ortho', rankdir='TB')
# 需求阶段流程 with dot.subgraph(name='cluster_需求阶段') as c: c.attr(label='需求阶段', fontname=fontname, color='blue') c.node('需求分析', '需求分析', shape='box', fontname=fontname, style='filled', color='lightgreen') c.node('PRD', '需求文档&原型', shape='box', fontname=fontname, style='filled', color='lightgreen') c.node('PRD_1', '需求文档&原型文档', shape='plaintext', fontname=fontname, color='lightgreen') c.node('需求评审', '需求评审', shape='diamond', fontname=fontname, style='filled', color='lightyellow')
# 添加边 c.edge('需求分析', 'PRD') with c.subgraph() as c1: c1.attr(rank='same') c1.edge('PRD', 'PRD_1', label=' ', fontname=fontname, fontsize=fontsize) c.edge('PRD', '需求评审') dot.edge('需求评审', '需求分析', xlabel='不通过', fontname=fontname, constraint='false', color='red', fontsize=fontsize)
# 设计阶段流程 with dot.subgraph(name='cluster_设计阶段') as s: s.attr(label='设计阶段', fontname=fontname, color='blue') s.node('UI设计', 'UI设计', shape='box', fontname=fontname, style='filled', color='lightgreen') s.node('详细UI设计', '详细UI设计', shape='box', fontname=fontname, style='filled', color='lightgreen') s.node('UI原型图', 'UI原型图', shape='plaintext', fontname=fontname, color='lightgreen') s.node('设计评审', '设计评审', shape='diamond', fontname=fontname, style='filled', color='lightyellow')
# 添加边 s.edge('UI设计', '详细UI设计') s.edge('详细UI设计', '设计评审') with s.subgraph() as s1: s1.attr(rank='same') s1.edge('详细UI设计', 'UI原型图', label=' ', fontname=fontname, fontsize=fontsize) s.edge('设计评审', 'UI设计', xlabel='不通过', fontname=fontname, constraint='false', color='red', fontsize=fontsize)
# 研发阶段流程 with dot.subgraph(name='cluster_研发阶段') as y: y.attr(label='研发阶段', fontname=fontname, color='blue') y.node('技术分析', '技术分析', shape='box', fontname=fontname, style='filled', color='lightgreen') y.node('技术设计', '技术设计', shape='box', fontname=fontname, style='filled', color='lightgreen') y.node('技术设计文档', '技术设计文档', shape='plaintext', fontname=fontname, color='lightgreen') y.node('技术评审', '技术评审', shape='diamond', fontname=fontname, style='filled', color='lightyellow') y.node('编码', '编码', shape='box', fontname=fontname, style='filled', color='lightgreen') y.node('研发完成', '研发完成', shape='box', fontname=fontname, style='filled', color='lightgreen')
# 添加边 y.edge('技术分析', '技术设计') y.edge('技术设计', '技术评审') with y.subgraph() as y1: y1.attr(rank='same') y1.edge('技术设计', '技术设计文档', label=' ', fontname=fontname, fontsize=fontsize) y.edge('技术评审', '技术分析', xlabel='不通过', fontname=fontname, constraint='false', color='red', fontsize=fontsize) y.edge('编码', '研发完成')
# 测试阶段流程 with dot.subgraph(name='cluster_测试阶段') as t: t.attr(label='测试阶段', fontname=fontname, color='blue') t.node('测试分析', '测试分析', shape='box', fontname=fontname, style='filled', color='lightgreen') t.node('测试用例', '测试用例', shape='box', fontname=fontname, style='filled', color='lightgreen') t.node('测试用例文档', '测试用例文档', shape='plaintext', fontname=fontname, color='lightgreen') t.node('用例评审', '用例评审', shape='diamond', fontname=fontname, style='filled', color='lightyellow') t.node('执行测试', '执行测试', shape='box', fontname=fontname, style='filled', color='lightgreen') t.node('测试报告', '测试报告', shape='box', fontname=fontname, style='filled', color='lightgreen')
# 添加边 t.edge('测试分析', '测试用例') t.edge('测试用例', '用例评审') with t.subgraph() as t1: t1.attr(rank='same') t1.edge('测试用例', '测试用例文档', label=' ', fontname=fontname, fontsize=fontsize) t.edge('用例评审', '测试分析', xlabel='不通过', fontname=fontname, constraint='false', color='red', fontsize=fontsize) t.edge('研发完成', '执行测试') t.edge('执行测试', '测试报告')
dot.node('开始', '项目开始', shape='ellipse', fontname=fontname, style='filled', color='lightblue') dot.node('立项', '项目立项', shape='box', fontname=fontname, style='filled', color='lightgreen') dot.edge('开始', '立项') dot.edge('立项', '需求分析')
dot.edge('需求评审', 'UI设计', xlabel='通过', fontname=fontname, fontsize=fontsize) dot.edge('需求评审', '技术分析', xlabel='通过', fontname=fontname, fontsize=fontsize) dot.edge('需求评审', '测试分析', xlabel='通过', fontname=fontname, fontsize=fontsize) dot.edge('技术评审', '编码', xlabel='通过', fontname=fontname, fontsize=fontsize) dot.edge('设计评审', '编码', xlabel='通过', fontname=fontname, fontsize=fontsize) dot.edge('用例评审', '执行测试', xlabel='通过', fontname=fontname, fontsize=fontsize)
dot.node('验收', '验收', shape='box', fontname=fontname, style='filled', color='lightgreen') dot.node('部署实施', '部署实施', shape='box', fontname=fontname, style='filled', color='lightgreen') dot.node('结束', '结束', shape='ellipse', fontname=fontname, style='filled', color='lightcoral') dot.edge('测试报告', '验收') dot.edge('验收', '部署实施') dot.edge('部署实施', '结束')
# 保存并显示 dot.render('项目简化流程图', format='png', view=True)

create_flowchart()

结果:

终于完成了,是不是很Nice


总结


这个完成后,小栈感觉用代码画图,除非是有固定流程的,想自动化实现,要不谁这么干呢?你们觉得的呢?

示例的代码,小栈也进行了梳理分享,有兴趣的同学可下载!


后台回复flowchart即可获取源码!



寄语:世间三美,明月,清风,眼前……



看到这儿的朋友帮点个“”和“在看”,谢谢支持~!

     

文章就分享到这儿,喜欢就点个吧!




往期推荐  点击标题可跳转


ISEE小栈
没有花里胡哨,简单才是王道。
 最新文章