首页 > 其他分享 >绘制层次结构图

绘制层次结构图

时间:2024-11-15 22:29:16浏览次数:1  
标签:plt end hierarchy start 层次结构 绘制 节点 rect

绘制层次结构图

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_line
        hierarchy[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 / 2
            end_y = y1 + rect_height / 2
        else:  # 从下到上
            start_y = y0 + rect_height / 2
            end_y = y1 - rect_height / 2

        # 保持 x 坐标不变
        start_x = x0
        end_x = x1

        y_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 / 2
            end_x = x1 - rect_width / 2
        else:  # 从右到左 (虽然这里不太可能出现,但为了代码的完整性,还是加上)
            start_x = x0 - rect_width / 2
            end_x = x1 + rect_width / 2

        # 保持 y 坐标不变
        start_y = y0
        end_y = y1

        x_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}")

标签:plt,end,hierarchy,start,层次结构,绘制,节点,rect
From: https://www.cnblogs.com/epicblue/p/18548794

相关文章

  • QT中使用图表之QChart绘制饼图
    饼图没有坐标轴,也不需要坐标轴使用的系列是QPieSeries饼图里面一个一个的块称为切片举例:绘制一个饼图,点击对应切片可以让切片分离1、创建图表视图并开启抗锯齿//1、创建图表视图QChartView*view=newQChartView(this);//开启抗锯齿view->setRenderHint(QPainte......
  • 16章15节:五大ROC曲线扩展包的对比,和其它评估曲线的绘制
    在机器学习和统计建模中,评估模型性能是至关重要的步骤。为了帮助研究人员和数据科学家更好地评估和可视化分类模型的效果,R语言提供了多个扩展包。本文将介绍几种常见的扩展包,主要包括ROCR、PROC、PRROC、以及ROCit等。首先,我们将详细探讨ROCR包的功能,重点介绍如何利用该包绘制R......
  • 2- R语言基本图形绘制之直方图——基于ggplot2
      直方图通过在x轴上将值域分割为一定数量的数据桶,在y轴上显示相应值的频数,展示了连续型变量的分布。  ggplot(data,aes(x=contvar))+geom_histogram()  #data是一个数据框;contvar是一个连续型变量。  下面我们使用ggplot包中的mpg数据框,分析2008年117个汽......
  • View绘制流程;
    ......
  • Origin图表技巧之绘制带辅助面的3D折线图
    折线图是科研中经常用到的图表之一,它通过线的升降变化显示数据的变化趋势,今天给大家分享绘制三维折线图的操作方法:操作步骤:1、先打开Origin2024软件,然后在Book1中输入如下示例数据:2、鼠标右击将C(Y)和E(Y)列设置为Z:3、将数据调整为XYZ型数据,如下:4、先选中所有数据:5......
  • 在线性坐标系中绘制对数函数图象
    本文记述了用Matplotlib在线性坐标系中绘制对数函数图象的例子。代码主体内容如下:...defmain():fig,ax=plt.subplots(figsize=(8,8))#1ax=configure_axes(ax,'LogarithmicFunction',8,3,1,0.25,1,0.25)#2x=np.linspace(......
  • [js] 突发奇想, 使用canvas绘制一个动态的扫描仪
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</title&g......
  • Python绘制循环渐变圆
    通过改变颜色,圆的半径,及旋转角度来形成圆图形importturtleimportcolorsysascs#导入颜色转换模块#设置显示屏幕screen=turtle.Screen()screen.title("渐变色的圆")screen.bgcolor('#AFEEEE')#设置画笔p=turtle.Turtle()p.pensize(1)p.speed(0)#设置......
  • 如何在Typora中绘制流程图
    如何在Typora中绘制流程图在撰写文档时,清晰的流程图能极大地提升信息传递的效率。Typora是一款优秀的Markdown编辑器,支持通过Mermaid语法快速绘制流程图。本文将介绍如何在Typora中创建和自定义流程图,帮助你用更直观的方式呈现逻辑结构和流程。目录Typora环境配置Mermai......
  • win32窗口绘制
    目录win32窗口绘制win32在WM_PAINT消息类型中绘制窗口窗口绘图基本流程开始绘画基本图形绘制1、画点设置指定点的颜色2、画线(直线、弧线)3、绘制封闭图形(能使用画刷填充的图形)GDI绘图对象位图绘制文本绘制TextOut:将文字绘制在指定坐标位置,只能绘制单行字符串,不能换行DrawText:在......