使用python画树状图
文章目录
前言
最近到一个需求,跟传销裂变差不多,有上级和下级的概念,根据下级的充值金额给上级返佣,这时候有个上下级的树状图肯定测试起来更加直观一点,也降低沟通成本。
一、前期准备
本地安装graphviz
graphviz是一个软件,可以根据特定语法文件生成图。
安装命令如下(我是mac环境):
brew install graphviz
安装python库
安装完本地已经可以根据文件生成PDF图了,但是我们还是要安装下python库,这样写代码组装数据比较方便
pip3 install graphviz
二、使用过程
1. hello world
先写个demo看一下效果
代码如下:
from graphviz import Digraph
# 画布
g = Digraph('G', filename='demo.gv')
# 定义两个节点
g.node('A', label='node1')
g.node('B', label='node2')
# 定义一条链接
g.edge('A', 'B')
# 渲染
g.view()
效果就是这样子:
2.给连接线加个文案
裂变总得标识下级充了多少钱是吧,所以我们需要在连接线上加个信息,标识他充了多少钱。
我们只需要在创建链接线时候加个参数就可以了
g.edge('A', 'B',label="¥100")
效果如下:
给节点搞点花样
有了充钱,那接下了就要区分下节点,毕竟上级节点逼格要高一点,对吧
# 星星
g.node('A', label='node1',shape='star')
# 双圆
g.node('A', label='node1',shape='doublecircle')
复杂一点
展示一下多节点多连接情况的场景
from graphviz import Digraph
f = Digraph('finite_state_machine', filename='fsm.gv')
f.attr(rankdir='LR', size='20,5')
f.attr('node', shape='doublecircle')
f.node('LR_0')
f.node('LR_3')
f.node('LR_4')
f.node('LR_8')
f.attr('node', shape='circle')
f.edge('LR_0', 'LR_2', label='SS(B)')
f.edge('LR_0', 'LR_1', label='SS(S)')
f.edge('LR_1', 'LR_3', label='S($end)')
f.edge('LR_2', 'LR_6', label='SS(b)')
f.edge('LR_2', 'LR_5', label='SS(a)')
f.edge('LR_2', 'LR_4', label='S(A)')
f.edge('LR_5', 'LR_7', label='S(b)')
f.edge('LR_5', 'LR_5', label='S(a)')
f.edge('LR_6', 'LR_6', label='S(b)')
f.edge('LR_6', 'LR_5', label='S(a)')
f.edge('LR_7', 'LR_8', label='S(b)')
f.edge('LR_7', 'LR_5', label='S(a)')
f.edge('LR_8', 'LR_6', label='S(b)')
f.edge('LR_8', 'LR_5', label='S(a)')
f.view()
效果如下
超高级
其实目前学到的用法已经满足我们的需要了,我看社区里面有个超高级的用法,搞个了二叉树出来,也是很厉害了
from graphviz import Digraph, nohtml
g = Digraph('g', filename='btree.gv',
node_attr={'shape': 'record', 'height': '.1'})
g.node('node0', nohtml('<f0> |<f1> G|<f2>'))
g.node('node1', nohtml('<f0> |<f1> E|<f2>'))
g.node('node2', nohtml('<f0> |<f1> B|<f2>'))
g.node('node3', nohtml('<f0> |<f1> F|<f2>'))
g.node('node4', nohtml('<f0> |<f1> R|<f2>'))
g.node('node5', nohtml('<f0> |<f1> H|<f2>'))
g.node('node6', nohtml('<f0> |<f1> Y|<f2>'))
g.node('node7', nohtml('<f0> |<f1> A|<f2>'))
g.node('node8', nohtml('<f0> |<f1> C|<f2>'))
g.edge('node0:f2', 'node4:f1')
g.edge('node0:f0', 'node1:f1')
g.edge('node1:f0', 'node2:f1')
g.edge('node1:f2', 'node3:f1')
g.edge('node2:f2', 'node8:f1')
g.edge('node2:f0', 'node7:f1')
g.edge('node4:f2', 'node6:f1')
g.edge('node4:f0', 'node5:f1')
g.view()
效果图:
一些注意的点
- 节点可以重复定义,不会出现多个节点的情况
- 边/连接定义多个就会出现多个线,需要注意
总结
这个工具还是非常好用的,降低了很多沟通成本,提高了代码的可视化,这比一组表格或者数据表要好看多了