
在数据分析和软件开发中,我们经常需要绘制各种关系图:系统架构图、数据流程图、依赖关系图、决策树等。传统的手动拖拽方式不仅耗时,而且修改起来极其麻烦。今天,我将介绍如何通过Python结合Graphviz,实现“代码即图形”的高效绘图方式。
往期阅读>>>
Python 20 个文本分析的库:效率提升 10 倍的秘密武器
Python 自动化管理Jenkins的15个实用脚本,提升效率
App2Docker:如何无需编写Dockerfile也可以创建容器镜像
Python 自动化识别Nginx配置并导出为excel文件,提升Nginx管理效率
Graphviz不是一个普通的绘图库,而是一个声明式图形可视化工具。你只需要告诉它:“我有这些节点,它们之间这样连接”,至于“怎么画得好看、不交叉、布局合理”这个最头疼的问题,完全交给Graphviz的自动布局引擎。
想象一下:你设计电路图(逻辑),它生成PCB布线图(布局)。这就是Graphviz的哲学。
# 安装Graphviz系统工具(需要先下载安装)# 访问 https://graphviz.org/download/ 下载对应系统版本# 安装Python库pipinstallgraphviz
让我们从一个简单的项目依赖关系图开始:
fromgraphvizimportDigraph# 创建一个有向图project_graph = Digraph(name='项目依赖关系',format='png',encoding='utf-8')# 设置全局参数project_graph.graph_attr.update({'rankdir': 'LR', # 布局方向:从左到右'splines': 'ortho', # 使用直角连线,避免交叉'fontname': 'Microsoft YaHei, SimSun, sans-serif','bgcolor': '#f8f9fa'})# 设置节点默认样式project_graph.node_attr.update({'shape': 'box','style': 'filled,rounded','fillcolor': '#e3f2fd','fontname': 'Microsoft YaHei','fontsize': '11'})# 设置边默认样式project_graph.edge_attr.update({'color': '#455a64','penwidth': '1.2','arrowhead': 'vee','fontname': 'Microsoft YaHei','fontsize': '10'})# 添加项目节点project_graph.node('web_app', 'Web应用')project_graph.node('api_server', 'API服务')project_graph.node('database', '数据库')project_graph.node('cache', 'Redis缓存')project_graph.node('auth_service', '认证服务')# 添加依赖关系project_graph.edge('web_app', 'api_server', label='HTTP请求')project_graph.edge('api_server', 'database', label='SQL查询')project_graph.edge('api_server', 'cache', label='缓存读写')project_graph.edge('web_app', 'auth_service', label='用户认证')project_graph.edge('api_server', 'auth_service', label='权限验证')# 保存并生成图形project_graph.render('project_dependency', view=False, cleanup=True)print("项目依赖关系图已生成:project_dependency.png")
对于数据科学项目,我们可以用Graphviz清晰地展示数据处理流程:
fromgraphvizimportDigraphimportpandasaspddefcreate_data_pipeline_viz():"""创建数据处理流水线可视化"""pipeline = Digraph('数据处理流水线', format='svg')# 全局样式pipeline.graph_attr.update({'rankdir': 'TB', # 从上到下布局'splines': 'ortho','fontname': 'Microsoft YaHei','nodesep': '0.5','ranksep': '0.8' })# 定义节点样式映射node_styles = {'source': {'shape': 'cylinder', 'fillcolor': '#ffccbc'},'process': {'shape': 'box', 'fillcolor': '#c8e6c9'},'analysis': {'shape': 'ellipse', 'fillcolor': '#bbdefb'},'output': {'shape': 'folder', 'fillcolor': '#fff9c4'} }# 添加数据处理节点nodes = [ ('raw_data', '原始数据\nCSV/JSON文件', 'source'), ('clean', '数据清洗\n去重、填充缺失值', 'process'), ('transform', '特征工程\n标准化、编码', 'process'), ('train', '模型训练\nXGBoost/LSTM', 'analysis'), ('evaluate', '模型评估\n准确率、召回率', 'analysis'), ('deploy', '部署上线\nAPI服务', 'output') ]fornode_id, label, node_typeinnodes:style = node_styles.get(node_type, {})pipeline.node(node_id,label,shape=style.get('shape', 'box'),style='filled,rounded',fillcolor=style.get('fillcolor', 'lightgray'),fontname='Microsoft YaHei' )# 连接处理流程pipeline.edges([ ('raw_data', 'clean'), ('clean', 'transform'), ('transform', 'train'), ('train', 'evaluate'), ('evaluate', 'deploy') ])# 添加反馈循环pipeline.edge('evaluate', 'train', label='参数调整',style='dashed',color='#f44336')returnpipeline# 生成并保存pipeline_viz = create_data_pipeline_viz()pipeline_viz.render('data_pipeline', view=False, cleanup=True)
# 确保中文正常显示的三要素viz = Digraph(encoding='utf-8', # 1. Python编码graph_attr={'charset': 'UTF-8'}, # 2. DOT文件编码node_attr={'fontname': 'Microsoft YaHei, SimSun, sans-serif'} # 3. 字体回退链)
# 创建包含表格的复杂节点viz.node('user_profile', label='''<<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR> <TD COLSPAN="2" BGCOLOR="#2196f3"> <FONT COLOR="white"><B>用户画像</B></FONT> </TD> </TR> <TR> <TD>ID</TD> <TD>U1001</TD> </TR> <TR> <TD>注册时间</TD> <TD>2024-03-15</TD> </TR> <TR> <TD>用户等级</TD> <TD>VIP3</TD> </TR></TABLE>>''', shape='none')
defgenerate_dependency_graph(packages):"""根据包依赖数据动态生成图形"""dep_viz = Digraph('包依赖图', format='png')dep_viz.graph_attr.update({'rankdir': 'LR','splines': 'ortho','fontname': 'Microsoft YaHei' })# 添加所有包节点forpkginpackages:dep_viz.node(pkg, pkg)# 添加依赖关系forpkg, depsinpackages.items():fordepindeps:dep_viz.edge(dep, pkg) # 依赖指向被依赖方returndep_viz# 示例数据package_deps = {'my_project': ['requests', 'pandas', 'numpy'],'data_processor': ['pandas', 'numpy'],'api_client': ['requests'],'requests': [],'pandas': ['numpy'],'numpy': []}# 生成图形dependency_viz = generate_dependency_graph(package_deps)dependency_viz.render('package_dependencies', view=False)
defexport_multiple_formats(viz, base_name):"""导出多种格式的图形"""formats = ['png', 'svg', 'pdf']forfmtinformats:viz.format = fmtviz.render(f'{base_name}_{fmt}', view=False, cleanup=True)print(f"已生成: {base_name}.{fmt}")# 同时保存DOT源文件(便于修改)withopen(f'{base_name}.dot', 'w', encoding='utf-8') asf:f.write(viz.source)# 使用示例export_multiple_formats(pipeline_viz, 'data_workflow')
当节点数量超过100个时,需要特别注意性能:
defoptimize_large_graph(viz):"""优化大型图形的性能"""viz.graph_attr.update({'overlap': 'vpsc', # 防止节点重叠'maxiter': '1000', # 增加布局迭代次数'epsilon': '0.0001', # 收敛阈值'splines': 'true', # 大型图可关闭ortho'K': '0.6', # 布局弹簧常数 })viz.node_attr.update({'fixedsize': 'true','width': '0.8','height': '0.5' })returnviz
fromgraphvizimportDigraphfromIPython.displayimportImage, displaydefshow_in_notebook():viz = Digraph()viz.node('A', '开始')viz.node('B', '处理')viz.node('C', '结束')viz.edges(['AB', 'BC'])# 直接显示在Notebook中viz.format = 'png'display(Image(viz.pipe(format='png')))returnviz
importosfromdatetimeimportdatetimedefauto_generate_docs(viz, description):"""自动生成带时间戳的文档"""timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')filename = f'docs/diagram_{timestamp}'# 生成图形viz.render(filename, view=False, cleanup=True)# 生成Markdown文档md_content = f"""# 关系图文档生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}## 描述{description}## 预览## DOT源码```dot{viz.source}
“””
with open(f'{filename}.md', 'w', encoding='utf-8') as f: f.write(md_content)print(f"文档已生成: {filename}.md")return filename
通过Python结合Graphviz,可以实现:
1. 代码驱动绘图:将图形定义转化为可维护的代码
2. 自动布局:告别手动调整节点位置的烦恼
3. 版本控制友好:DOT文件可以像代码一样进行版本管理
4. 批量生成:轻松生成多个变体或不同风格的图形
5. 集成自动化:将图形生成嵌入到CI/CD流程中
这种"声明式"的绘图方式特别适合:
- 需要频繁修改的架构图
- 自动生成的数据流程文档
- 动态变化的系统依赖关系
- 需要版本控制的图形资产
想高效学习Python?下面三本精选好书满足你的不同需求!
《流畅的Python(第2版)》——Python进阶必读!深入讲解高级特性与最佳实践,适合想精进的开发者。
《Python从新手到高手》:初学者首选,系统学习全栈技能。
《Python数据分析:从零基础入门到案例实战》——数据科学利器!手把手教你用Python处理数据,实战案例学完就能用。
三本书均支持先用后付、运费险和7天无理由退货,放心购买!点击“购买”按钮,立即开启你的Python学习之旅吧!
https://ima.qq.com/wiki/?shareId=f2628818f0874da17b71ffa0e5e8408114e7dbad46f1745bbd1cc1365277631c
