绘制层次结构图

news/2024/11/15 22:42:53/文章来源:https://www.cnblogs.com/epicblue/p/18548794

绘制层次结构图

WPS的智能图形要收费,先做个免费的不美观的版本。

基于
matplotlib,networkx,graphviz,pydot

按需修改
输入内容
input_data 为输入的文本。

外观
rankdir 为指定方向。
mpatches.Rectangle 为节点外形。

比例
缩放matplotlib窗口,调整节点长宽。
调整字体大小,当前为 plt.text(fontsize=10)。

代码
import matplotlib.pyplot as plt
import networkx as nx
import matplotlib.patches as mpatches

plt.rcParams['font.sans-serif'] = ['SimHei'] # 正常显示中文
plt.rcParams['axes.unicode_minus'] = False # 正常显示负号

def parse_hierarchy(input_str):
"""
解析组织架构的层级输入,生成树结构。
"""
lines = input_str.strip().split("\n")
root = None
stack = [] # 用于追踪当前的父层级节点
hierarchy = {}

for line in lines:# 计算当前行的缩进级别stripped_line = line.lstrip("- ").strip()level = (len(line) - len(line.lstrip("- "))) // 2# 创建当前节点if root is None:root = stripped_linehierarchy[root] = []stack.append((root, level))else:while stack and stack[-1][1] >= level:  # 回退到上一层级节点stack.pop()if stack:parent, _ = stack[-1]hierarchy[parent].append(stripped_line)else:# 如果栈为空但仍有节点,则说明输入格式有问题raise ValueError(f"错误的层级结构:无法找到父节点来连接 {stripped_line}")hierarchy[stripped_line] = []stack.append((stripped_line, level))return root, hierarchy

def plot_organization_chart(root, hierarchy, rankdir = "TB"):
G = nx.DiGraph()

def add_edges(parent, children):for child in children:G.add_edge(parent, child)add_edges(child, hierarchy.get(child, []))add_edges(root, hierarchy[root])# 创建一个 Pydot 的图对象
dot = nx.drawing.nx_pydot.to_pydot(G)# 设置图的方向
dot.set_rankdir(rankdir)  # 'LR' 为从左到右,'TB' 为从上到下# Pydot 的图对象 倒腾到 G
G = nx.drawing.nx_pydot.from_pydot(dot)# 使用层次布局定位节点
pos = nx.drawing.nx_pydot.graphviz_layout(G, prog='dot')# 缩小节点间距
def scale_pos(pos, scale_x=1.0, scale_y=1.0):return {node: (x * scale_x, y * scale_y) for node, (x, y) in pos.items()}# 调整缩放比例以减少节点之间的间距
pos = scale_pos(pos, scale_x=0.5, scale_y=0.5)plt.figure(figsize=(10, 6))# 创建长方形节点
def draw_rect_node(node, pos):x, y = pos[node]rect_width, rect_height = 40, 15  # 矩形宽度和高度rect = mpatches.Rectangle((x - rect_width / 2, y - rect_height / 2),rect_width, rect_height,edgecolor='black', facecolor='lightblue', alpha=0.8)plt.gca().add_patch(rect)  # 添加矩形到当前轴plt.text(x, y, node, ha='center', va='center', fontsize=10, fontweight='bold', color='black')# 绘制节点和矩形
rect_width, rect_height = 40, 15
for node in G.nodes():draw_rect_node(node, pos)for parent, child in G.edges():x0, y0 = pos[parent]x1, y1 = pos[child]if rankdir == "TB" or rankdir == "BT":# 计算起点和终点,避开矩形区域if y0 > y1:  # 从上到下start_y = y0 - rect_height / 2end_y = y1 + rect_height / 2else:  # 从下到上start_y = y0 + rect_height / 2end_y = y1 - rect_height / 2# 保持 x 坐标不变start_x = x0end_x = x1y_mid = (start_y + end_y) / 2  # 中间的水平线 y 坐标# 绘制边plt.plot([start_x, start_x], [start_y, y_mid], "k-", linewidth=0.8)  # 垂直线plt.plot([start_x, end_x], [y_mid, y_mid], "k-", linewidth=0.8)      # 水平线plt.plot([end_x, end_x], [y_mid, end_y], "k-", linewidth=0.8)        # 垂直线else:# 计算起点和终点,避开矩形区域if x0 < x1:  # 从左到右start_x = x0 + rect_width / 2end_x = x1 - rect_width / 2else:  # 从右到左 (虽然这里不太可能出现,但为了代码的完整性,还是加上)start_x = x0 - rect_width / 2end_x = x1 + rect_width / 2# 保持 y 坐标不变start_y = y0end_y = y1x_mid = (start_x + end_x) / 2  # 中间的垂直线 x 坐标# 绘制边plt.plot([start_x, x_mid], [start_y, start_y], "k-", linewidth=0.8)  # 水平线plt.plot([x_mid, x_mid], [start_y, end_y], "k-", linewidth=0.8)      # 垂直线plt.plot([x_mid, end_x], [end_y, end_y], "k-", linewidth=0.8)        # 水平线plt.title("Organization Chart", fontsize=14)
plt.axis("off")
plt.tight_layout()
plt.show()

输入的层次结构文本

input_data = """
顶层节点

  • 一级节点1
    • 二级节点1
    • 二级节点2
    • 二级节点3
    • 二级节点4
      • 三级节点1
      • 三级节点2
      • 三级节点3
  • 一级节点2
    • 二级节点5
    • 二级节点6
      """

try:
root, hierarchy = parse_hierarchy(input_data)
plot_organization_chart(root, hierarchy, "LR")
except ValueError as e:
print(f"输入解析错误:{e}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/834285.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

项目冲刺11.15

这个作业属于哪个课程 计科22级34班这个作业要求在哪里 作业要求这个作业的目标 进行为期七天的项目冲刺并记录前言 本篇博客是项目冲刺的第七篇,七篇博客的汇总如下:博客汇总第一篇博客第二篇博客第三篇博客第四篇博客第五篇博客第六篇博客第七篇博客团队简介队名 拖延是你不…

Latex 安装

使用的开发环境是 VSCode. Latex 在编译时需要用到宏包. 宏包到底是啥? 有啥作用? 从何处下载? Latex 软件的安装:texlive: 一次性下载所有的宏包. 磁盘需求较大, 约 7 ~ 8 G.miktex: 仅下载必要的宏包, 编译时补充下载宏包. 磁盘需求较小, 约几百 M.清华大学开源软件镜像站…

20222424 2024-2025-1 《网络与系统攻防技术》实验五实验报告

20222424 2024-2025-1 《网络与系统攻防技术》实验五实验报告 1.实验内容 (1)从www.besti.edu.cn、baidu.com、sina.com.cn中选择一个DNS域名进行查询,获取如下信息:DNS注册人及联系方式 该域名对应IP地址 IP地址注册人及联系方式 IP地址所在国家、城市和具体地理位置 PS:…

Windows程序设计指南

Windows程序设计指南“到Petzold的书中找找”——仍然是解决Windows程式开发各种疑难杂症时的灵丹妙药。在第五版的《Windows程式开发设计指南》中,作者身为倍受敬重的WindowsPioneerAward(Windows开路先锋奖)得主,依据最新版本Windows作业系统,以可靠的取材资料校定这一本…

Windows高级调试

Windows高级调试中文版文档摘要: 本书《Windows高级调试》主要讲解Windows高级调试技术和工具,包括调试器简介、调试器揭密、符号文件与源文件的管理、栈内存破坏、堆内存破坏、安全、进程间通信、资源泄漏、同步、编写定制的调试扩展、64位调试、事后调试、Windows Vista基础…

iman——冲刺日志(第四天)

又一阉割版 团队成员分工与进度 📝👥组别 成员 完成的任务 完成任务所用时间 (小时) 剩余时间 (小时)前端 阿依娜孜 完成了行程概览地图中标记连线与探索功能的删除与添加。 3 2前端 郭剑敏 实现了地图标点的驾车路线绘制功能。 3 1前端 王梓铭 优化了主页与导航栏布局,提…

1.11--06:月度开销

http://noi.openjudge.cn/ch0111/06/月度开销题目传送门思路 给定连续N天的开销,需要将这些天分成M个财政周期,使得开销最多的财政周期的开销尽可能少。 首先,我们可以确定一个财政周期的长度l,即将N天平均分成M个财政周期。这样每个财政周期的长度就是N/M。 然后,我们需要…

SIM Jacker攻击分析

攻击者使用普通手机发送特殊构造的短信即可远程定位目标,危害较大。sim卡的使用在手机上的使用非常普遍,所以一旦SIM卡上出现什么问题就会造成非常大的影响。在19年的报告纰漏中,在全球估算共有10亿设备的sim卡容易遭受SIMJacker攻击,这篇也是比较浅显的对整个攻击进行分析…

shell动态修改yml配置实例

yq安装https://github.com/mikefarah/yq/tree/master每个yq版本支持的选项参数都不一样修改Dockerfile[root@instance base-tlog-test]# vi Dockerfile FROM 192.168.30.113/library/java:latest ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime &am…

『模拟赛』NOIP2024加赛5

Rank 反向挂分大王A. 暴力操作(opt) 签,但是没有人签。 都想到了二分和更新 c 值,但是 c 多多少少没更到最优。 首先还是调和级数预处理,倒序取 min。然后考虑到超过 \(m\) 的也有可能产生更小的代价,因此 \(\mathcal{O(n)}\) 枚举一遍找到最小的 \(j\) 使 \(i\times j\g…

[Moectf2024 ezMaze]

去壳 分析:迷宫分析10 * a2 - 10:Y (a1 - 1) / 8 :X 表示按字节处理迷宫迷宫以十六进制压缩,但迷宫是80 * 56的二进制迷宫 dump下来保存,转二进制,用bin(maze[2:]).zfill(8) 脚本(bfs): from collections import deque maze = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…

有理逼近AAA算法

用于有理逼近的AAA算法,可以有效防止伪极点现象用于有理逼近的AAA算法The AAA Algorithm for Rational Approximation, Yuji Nakatsukasa, Olivier Ste, and Lloyd N. Trefethen, SIAM Journal on Scientific Computing 2018 40:3, A1494-A1522, https://doi.org/10.1137/16M1…