Python Tree库绘制多叉树的用法介绍

2023-11-02

Python Tree库绘制多叉树的用法介绍

Tree 库是一个 Python 的第三方库。这个库主要用于生成树和绘制树的图形。

一、安装Tree

pip install Tree

使用 Tree 库需要配合 PIL 库来实现绘图。

二、官方案例

先看一下 PyPI 里 Tree 库提供的 demo 。PyPI地址:https://pypi.org/project/Tree/

# coding=utf-8
from Tree.core import Tree
from math import radians as rad
from PIL import Image


def main():
    branches = ((.5, rad(-30)), (.6, rad(30)), (.4, rad(60)))
    tree = Tree(pos=(0, 0, 0, -500), branches=branches)
    tree.grow(10)
    tree.move_in_rectangle()
    im = Image.new("RGB", tree.get_size(), (239, 239, 239))
    tree.draw_on(im, (85, 25, 0, 128, 53, 21), (0, 62, 21), 10)
    im.show()


if __name__ == '__main__':
    main()

运行结果:

运行代码,生成了一棵三叉树,然后用 PIL 将这棵树展示成了一张图片。接下来介绍 Tree 库的用法。

三、Tree库介绍

Tree 库分为三个部分,core.py,utils.py和draw.py。

utils.py中实现了节点类Node和颜色转换函数。

draw.py中实现了绘制图形的类Drawer。

core.py中实现了生成树的类Tree和生成分支的函数。

三个部分是耦合的,使用时不需要直接调用utils.py和draw.py中的类和函数,直接使用core.py中的Tree类就行了。

from Tree.core import Tree

在 Tree 库中,多处使用到了Python标准库 math 和第三方库 PIL。不仅如此,当我们调用 Tree 库时,也需要借助 math 库和 PIL 库来生成树的图片。

math库的使用可以参考:https://blog.csdn.net/weixin_43790276/article/details/98476264

PIL库的使用可以参考:https://blog.csdn.net/weixin_43790276/article/details/108478270

四、Tree库的使用

实例化一个Tree类的对象,即可生成一棵树。在初始化一棵树时,有3个参数,pos,branches和sigma。

pos是一个长度为4的元组(列表也可以),分别表示树的起始点和结束点的横纵像素坐标(x0, y0, x1, y1),源码中会根据这两个坐标用勾股定理计算出树的长度(在树没有生长时只有树干),起始点和结束点的位置关系会决定树的生长方向,可以通过坐标的正负值来调整。如果传入的元组长度小于4会报索引越界(找不到足够的数据),如果元组长度大于4则取前4个值,多的数据无效。

branches是一个列表或元组,列表中有多少个值,树生长时就有多少个分支。每一个分支的参数也是一个列表或元组,参数中需要两个数据,第一个表示树枝相对于父枝干的长度变化系数(一般小于1,树枝比树干短),第二个表示树枝相对于父枝干的偏移角度,角度是弧度制(数字角度可以用math库中的radians转换)。在初始化一棵树时,branches如果不传值默认是None,这样源码中计算分支时会报错,如果branches传一个空列表,则使用PIL展示树时会因无法扩展而报错,所以必须传入非空的branches参数。

sigma是一个元组(列表也可以,不过会提示不符合PEP规范),元组中有两个值,第一个用于调整分支的长度,第二个用于调整分支的角度(乘math中的pi)。使用sigma参数不易控制预期效果,所以保持默认的(0, 0)即可,一般不传值。

grow(times=1): 用于使树生长,默认生长1次,即在树干的基础上生长一次,最后一次是树叶,其他的是枝干。虽然默认生长1次,但在后面调用draw_on()方法绘图时,会有除0报错,所以最小需要生长两次,传值应该大于等于2。

age属性表示树的年龄,树grow()了多少次,age就是多少。

move_in_rectangle(): 用于移动树的位置,使树的位置自适应画布(自动将图片移动到画布中心),是一个辅助绘图的方法。

get_size(): 用于获取树的尺寸,返回结果是一个元组,分别表示树的宽和高(width, height)。

使用PIL中的new()函数创建一块画布,用于绘图,有三个参数。第一个参数表示图片的模式,使用“RGB”(red,green,blue三原色的缩写,表示真彩色图像)即可。第二个参数表示画布的大小(按像素计算),因为树从树干生长后,尺寸会变化,所以使用get_size()动态获取当前树的尺寸。第三个参数表示画布的颜色,默认值为0,黑色画布,可以根据需要修改。

draw_on(canvas, stem_color, leaf_color, thickness, ages=None): 将树的结构绘制到画布上,需要4个参数。

canvas, 画布。传入使用PIL库new()出来的画布(也可以使用其他绘图的库)。

stem_color, 表示树干的颜色和枝干的颜色变换梯度。传入一个元组(RGB颜色可以用长度为3的元组表示),如果传入的元组长度为3,则所有枝干的颜色一样,没有渐变,如果传入的元组长度为6,则会根据枝干的年龄age来进行颜色渐变(参考draw.py中的_get_color(age)源码),元组的长度小于6且不为3会报索引越界,长度大于6则后面的数据无效。

leaf_color, 树叶的颜色。传入一个长度为3的元组,长度小于3会报传参错误,大于3则后面的数据无效,这里也可以传入一个16进制的颜色编码。

thickness, 树干的粗细。传入一个整数,值越大,树干越粗。

基本的方法和属性介绍完了,现在看一个简单的例子。

# coding=utf-8
from Tree.core import Tree
from math import radians
from PIL import Image


pos = [0, 0, 0, -300]
branches = [[0.58, radians(-45)], [0.58, radians(45)]]
tree = Tree(pos=pos, branches=branches)
tree.grow(5)
print('tree age is: ', tree.age)
tree.move_in_rectangle()
image = Image.new("RGB", tree.get_size(), 0)
tree.draw_on(image, (80, 20, 10, 120, 60, 30), '#003E15', 15)
image.show()

运行结果:

tree age is:  5

五、Tree库的其他方法介绍

print('树干长度:', tree.length)
print('树叶长度:', tree.get_branch_length())
print(tree.get_branch_length(age=1))
print(tree.get_rectangle())

运行结果:

树干长度: 300.0
树叶长度: 19.690703039999992
174.0
(0.0, 0.0, 626.4380061192694, 613.2190030596347)

length属性表示树干的长度。

get_branch_length(): 返回指定年龄的枝干长度,不指定年龄则返回树叶的长度。指定的年龄可以无限大(会根据变化系数推导结果)。

get_rectangle(): 树经过多次生长后,返回树占用的矩形坐标。

print('树的节点数:', tree.get_node_sum())
print(tree.get_node_sum(3))
# print(tree.nodes)
print(tree.get_nodes())
# print(tree.get_branches())
delta = (10, 10, 10, 10)
tree.move(delta)

运行结果:

树的节点数: 63
15
[[(313.2190030596347, 313.2190030596347)], [(190.18242313317546, 190.1824231331754), (436.255582986094, 190.1824231331754)], [(89.26242313317545, 190.18242313317535), (190.18242313317543, 89.26242313317539), (436.255582986094, 89.26242313317539), (537.175582986094, 190.1824231331754)], [(47.87291764591453, 231.5719286204362), (47.87291764591458, 148.79291764591443), (148.79291764591454, 47.87291764591453), (231.57192862043632, 47.87291764591453), (394.8660774988331, 47.87291764591453), (477.64508847335486, 47.87291764591453), (578.5650884733549, 148.79291764591449), (578.5650884733549, 231.57192862043632)], [(47.87291764591453, 265.5214166204362), (13.923429645914553, 231.5719286204362), (13.92342964591461, 148.79291764591443), (47.87291764591458, 114.84342964591445), (114.84342964591457, 47.87291764591453), (148.79291764591454, 13.923429645914553), (231.57192862043632, 13.923429645914553), (265.5214166204363, 47.87291764591453), (360.9165894988331, 47.87291764591453), (394.8660774988331, 13.923429645914553), (477.64508847335486, 13.923429645914553), (511.59457647335483, 47.87291764591453), (578.5650884733549, 114.84342964591451), (612.5145764733549, 148.79291764591449), (612.5145764733549, 231.57192862043632), (578.5650884733549, 265.5214166204363)], [(61.79634729182908, 279.44484626635074), (33.949487999999974, 279.44484626635074), (0.0, 245.49535826635076), (0.0, 217.64849897452166), (5.684341886080802e-14, 162.71634729182898), (5.684341886080802e-14, 134.86948799999988), (33.94948800000003, 100.91999999999985), (61.796347291829136, 100.91999999999985), (100.92000000000002, 61.79634729182908), (100.92000000000002, 33.949487999999974), (134.869488, 0.0), (162.7163472918291, 0.0), (217.64849897452174, 0.0), (245.49535826635088, 0.0), (279.44484626635085, 33.949487999999974), (279.44484626635085, 61.79634729182908), (346.99315985291855, 61.79634729182908), (346.99315985291855, 33.949487999999974), (380.9426478529185, 0.0), (408.7895071447477, 0.0), (463.7216588274403, 0.0), (491.5685181192694, 0.0), (525.5180061192693, 33.949487999999974), (525.5180061192693, 61.79634729182908), (564.6416588274403, 100.91999999999996), (592.4885181192694, 100.91999999999996), (626.4380061192694, 134.86948799999993), (626.4380061192694, 162.71634729182904), (626.4380061192694, 217.64849897452177), (626.4380061192694, 245.49535826635088), (592.4885181192694, 279.44484626635085), (564.6416588274403, 279.44484626635085)]]

get_node_sum(): 返回从树干到指定年龄的节点总数,不指定年龄则返回当前树的节点数。指定的年龄可以无限大(会根据分支数推导结果)。

nodes属性表示当前树中的所有节点对象,每个年龄的节点构成一个列表。

get_nodes(): 返回当前树中的所有节点坐标,每个年龄的节点构成一个列表。

get_branches(): 返回当前树中的所有枝干坐标,坐标的格式为(x0, y0, x1, y1),每个年龄的枝干构成一个列表。此方法与branches属性没有关系,branches的值是初始化时传入的参数。

move(delta): 移动树,传入一个delta参数,参数格式与pos相同(x0, y0, x1, y1),四个坐标值按delta的值进行平移。

六、Tree库的灵活使用

1. 画一棵好看一点的树

# coding=utf-8
from Tree.core import Tree
from math import radians
from PIL import Image


branches = [[0.7, radians(-50)], [0.45, radians(10)], [0.6, radians(30)]]
tree = Tree(pos=(0, 0, 0, -300), branches=branches)
tree.grow(9)
tree.move_in_rectangle()
image = Image.new("RGB", tree.get_size(), (250, 250, 250))
tree.draw_on(image, (80, 20, 10, 120, 60, 30), '#003E15', 12)
image.show()

运行结果:

2. 不受限于树,也可以绘制其他图形

# coding=utf-8
from Tree.core import Tree
from math import radians
from PIL import Image


tree = Tree(pos=(0, 0, 0, -100), branches=[[1.1, radians(30)]])
tree.grow(24)
tree.move_in_rectangle()
tree.move((100, 100, 100, 100))
size = tuple([s+200 for s in tree.get_size()])
image = Image.new("RGB", size, (250, 250, 250))
tree.draw_on(image, (255, 0, 0), (255, 0, 0), 15)
image.show()

运行结果:

树的生长和绘图很耗内存,树生长的次数较大的话,内存就不够了。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python Tree库绘制多叉树的用法介绍 的相关文章

  • 访问使用 ElementTree 解析的 xml 文件中的嵌套子级

    我是 xml 解析新手 这个xml文件 http ratings food gov uk OpenDataFiles FHRS408en GB xml有以下树 FHRSEstablishment gt Header gt gt Establ
  • 用C语言创建进程树

    我将如何创建一个看起来像深度为 N 的平衡三元树的流程层次结构 意味着每个进程有 3 个子进程 因此深度 N 的树中将有 3 N 1 2 个进程 要创建新进程 我只想使用 fork 这是我到目前为止所拥有的 但我认为它不起作用 因为我不处理
  • 如何在 Extjs 4.1 中使用 treecombo

    我找到了导师http www sencha com forum showthread php 198856 Ext ux TreeCombo http www sencha com forum showthread php 198856 E
  • 使用 javascript 获取 DOM 树

    我正在开发一个小脚本分析 DOMHTML 页面和在屏幕上写下节点树 这是一个简单的函数 称为递归地获取所有节点及其子节点 每个节点的信息存储在一个数组中 自定义对象 我已经得到了所有节点在 DOM 中 但不是如何在树上画画通过嵌套列表 JS
  • 将路径数组转换为 UL 列表

    我的数据库中有一个表 其中包含我网站页面的各种路径 每条路径仅列出一次 我目前有一系列非常长且复杂的查询和 PHP 来提取所有这些并将数据重写到无序列表中 为我的网站创建菜单 似乎有一种相对简单的循环方法可以更有效地工作 但我似乎无法让任何
  • D3.js 在径向树中的元素之间添加链接(分层边缘捆绑元素)

    几个月前 我尝试过使用 d3 js 将分层边缘捆绑和径向 Reingold Tilford 树结合起来 https stackoverflow com questions 39150514 d3 js combining hierarchi
  • 范围内的第 K 个最小值

    给定一个整数数组和一些查询操作 查询操作有2种类型1 将第i个索引的值更新为x 2 给定 2 个整数 找到该范围内的第 k 个最小值 例如 如果 2 个整数是 i 和 j 我们必须找出 i 和 j 之间的第 k 个最小值 我可以使用线段树找
  • 从物化路径构建 JSON 树

    我计划在 MongoDB 中使用物化路径来表示树 并且需要将物化路径转换回 JSON 树 前任 物化路径 var input id 0 path javascript id 1 path javascript database id 2 p
  • 对整数树求和 (Haskell)

    我正在尝试创建一个对非二叉整数树的值求和的函数 datastructures hs data Tree a Empty Node a Tree a deriving Eq Show myNums Num a gt Tree a myNums
  • rpart - 查找修剪树的 cp 值将返回的叶子数量

    我有一个要求 需要根据分类变量 具有超过 5 个类别值 与连续变量的关联将其分为 5 组 为了实现这一目标 我正在使用rpart with annova 方法 例如我的分类变量是type有代码1 2 3 4 5 6 7 8 9 10 11
  • 如何在 R 中将树转换为树状图?

    如何将树 Java 程序的输出 转换为 R 中的树状图 目前 我正在使用给出的建议将树转换为 Newick 格式here https stackoverflow com questions 2612579 converting a tree
  • B 树和 2-3-4 树之间的区别

    B 树和 2 3 4 树有什么区别 另外 你如何找到每个的最大和最小高度 链接到维基百科 http en wikipedia org wiki 2 3 4 tree and引用 2 3 4 树是 4 阶 B 树 A 2 3 4 is a B
  • 最大函数c树高度

    c 中是否有 max 函数 所以我可以做这样的事情来计算树高 或者也许有更好的方法来计算树高 int height struct node tree if tree NULL return 0 return 1 max height tre
  • 二叉树的列表实现是否可扩展?

    我正在写一个简单的编解码器 该树将被预先计算 一旦构建就不会发生任何变化 它只会被搜索 平衡二叉树的所有叶节点都是信号值 内部节点是近似压缩表示 如果我有很大的叶节点值 使用 stl 矢量的列表实现是否可扩展 目前我不知道有多大 列出实现
  • 以 BFS 风格将深度的嵌套字典(森林)写入文本文件

    继续我的旧问题 将深度巨大的嵌套字典 森林 写入文本文件 https stackoverflow com questions 51500003 writing nested dictionary forest of a huge depth
  • 构建具有继承的通用树

    我正在构建一个通用的Tree
  • 创建二叉树的时间复杂度

    我正在尝试从提供的源创建一棵树 要添加到树中的 2 个节点 以及应添加这 2 个新闻节点的节点 为了找到该节点在树中的位置 我使用了中序遍历 该遍历的时间复杂度为 O n 因此 如果要在树中添加 n 个节点 则创建整个树的时间复杂度为 O
  • 如何递归探索Python嵌套字典? [复制]

    这个问题在这里已经有答案了 我很好奇是否有一种方法可以在 python 中递归地探索嵌套字典 我的意思是 假设我们有一个如下示例 d a b c 1 2 3 获取最里面字典的内容需要什么代码 c 1 2 3 遍历a and b 在这种情况下
  • 二叉搜索树是平衡的吗?

    这已经讨论过了here https stackoverflow com questions 742844 how to determine if binary tree is balanced 但我在下面有一个实现 线程中从未讨论过 pub
  • 为什么在算法中使用子树大小来选择二叉树中的随机节点?

    我偶然发现了从二叉树中选择随机节点的算法的几种实现 它们都使用子树大小属性 但是 我不明白为什么知道子树大小有帮助 这是实现A https stackoverflow com a 32011526 and B https www geeks

随机推荐

  • 从零开始搭建物联网平台(三)数模设计

    首先 我们先从数模设计开始 这是一个系统的核心和精髓 决定了系统的架构和扩展控件 ETCloud的数模共有22张表 三个模块 一 用户模块 用户模块主要由企业表 用户表 角色表 权限表构成 1 数据权限 用户共分为三大类 model use
  • 力扣算法题解析

    一 278题 第一个错误的版本 难度 简单 1 题目描述 你是产品经理 目前正在带领一个团队开发新的产品 不幸的是 你的产品的最新版本没有通过质量检测 由于每个版本都是基于之前的版本开发的 所以错误的版本之后的所有版本都是错的 假设你有 n
  • stm32Cubemx:串口的空闲中断和接收中断------stm32f407zgt6

    介绍串口的接收中断与空闲中断 这两种中断都是在串口进行接收时可能会发生的中断 串口接收中断即每当串口完成一次接收之后触发一次中断 在 STM32 中相应的中断处理函数为 USARTx IRQHandler 中断回调函数为 HAL UART
  • 2023数据要素专题研究报告

    数据要素是实际参与社会生产活动的 完成确权的数据资源 数字化的文本 图形等数据经过权属确定后即为数据资产 再经过数据处理 分析后 形成数据产品并参与社会生产经营 对其他生产要素赋能并发挥数据自身价值 完成数据的价值闭环 根据国务院印发的 关
  • Neo4j CQl语句(持续更新)

    1 清空所有数据 MATCH n OPTIONAL MATCH n r DELETE n r 2 删除一个节点及其所有的关系 MATCH r WHERE id r 11 DETACH DELETE r 3 删除一个节点 DELETE 通过属
  • Mac Safari 此连接非私人连接

    1 问题 连接公司vpn的时候 Mac弹出此连接非私人连接 点击访问此网站后输入密码将证书手动设为可信后 又弹出了此连接非私人连接 之后进入了无限循环无论怎样都无法访问该网页 2 解决方案 2 1 点击页面上查看此证书 记住证书名字 可以看
  • 自制GUI

    包含了 sqlmap GUI Xray GUI dirmap GUI
  • selenium测试框架快速搭建(UI自动化测试)

    一 介绍 selenium目前主流的web自动化测试框架 支持多种编程语言Java pythan go js等 selenium 提供一系列的api 供我们使用 因此在web测试时我们要点页面中的某一个按钮 那么我们只需要获取页面 然后根据
  • js控制获得焦点与失去焦点样式

    function focusInput focusClass normalClass var elements document getElementsByTagName input for var i 0 i lt elements le
  • Vue项目保存代码之后页面自动更新

    Vue项目保存代码之后页面自动更新 想要在代码中保存之后 页面自动刷新 命令行敲如下代码 npm install webpack dev server 下载了这个东西就不用每次都手动刷新了 我也不知道这个是干嘛的 留在以后研究研究
  • Chromium OS autotest

    autotest三种主要测试手段 直接调用系统命令 相当于直接运行shell命令 通过dbus进行method call 通过加载插件到browser的方式 运行js代码 以js代码来调用C 方法 通过extension来运行js代码 目的
  • XSS闯关——第五关:level5

    第五关 level5 输入语句测试 gt 观察源代码发现字符被替换 把部分字符换成大写尝试 gt 一样的结果 采用html事件方法 失败 同样是字符被替换 使用伪链接方式假造一个超链接尝试 gt a href link a 点击后执行脚本
  • Laravel Collection 常用方法(1)

    我的个人博客 逐步前行STEP 1 first 返回集合第一个通过指定测试的元素 collect 1 2 3 4 gt first 1 collect 1 2 3 4 gt first function value key return v
  • 深度学习deep learning

    一 简介 深度学习是包含多个隐层的机器学习模型 核心是基于训练的方式 从海量数据中挖掘有用信息 实现分类与预测 早期的深度学习模型 编码器 循环神经网络 深度置信网络 卷积神经网络 衍生模型 堆叠降噪自编码器 稀疏自编码器 降噪自编码器 深
  • mysql 集成测试_使用Go进行集成测试的MySQL Docker容器

    使用Go进行集成测试的MySQL Docker容器 原文链接 https itnext io mysql docker container for integration testing using go f784b70a03b 作者 Mi
  • 【Linux】在Xilinx平台上实现UVC Gadget(2)- 解决dwc3驱动bug

    Linux 在Xilinx平台上实现UVC Gadget 2 解决dwc3驱动bug 一 bug描述 二 具体修改方法 1 找到内核源码位置并复制到其他目录 2 Petalinux里面设置使用自定义内核源码 1 选第2个Linux Comp
  • 数列分段

    描述 对于给定的一个长度为N的正整数数列A i 现要将其分成M M N 段 并要求每段连续 且每段和的最大值最小 关于最大值最小 例如一数列4 2 4 5 1要分成3段 将其如下分段 4 2 4 5 1 第一段和为6 第2段和为9 第3段和
  • MySQL查询语句的执行顺序

    SQL语句执行顺序 FROM ON JOIN WHERE GROUP BY AGG FUNC WITH HAVING SELECT UNION DISTINCT ORDER BY LIMIT 在实际执行过程中 每个步骤都会为下一个步骤生成一
  • [django项目] 后台菜单管理功能

    后台菜单管理功能 菜单的管理功能其实就是 对菜单的增删改查 I 业务功能分析 1 gt 业务需求分析 后台首页菜单根据用户权限动态生成 不同菜单对应不同的功能视图 菜单的增删改查 2 gt 功能分析 菜单列表 添加菜单 修改菜单 删除菜单
  • Python Tree库绘制多叉树的用法介绍

    Python Tree库绘制多叉树的用法介绍 Tree 库是一个 Python 的第三方库 这个库主要用于生成树和绘制树的图形 一 安装Tree pip install Tree 使用 Tree 库需要配合 PIL 库来实现绘图 二 官方案