如何通过Bio.Phylo与Matplotlib调整轴实现正确环形进化树?
Biopython Phylo环形进化树布局调整方案
一、调整Phylo.draw布局让树向上生长
Biopython默认的树布局是根在左、叶子在右的左右方向,要改成向上生长(根在下、叶子在上),可以通过Matplotlib的坐标变换实现,无需修改Phylo核心逻辑:
import matplotlib.pyplot as plt from matplotlib.transforms import Affine2D import numpy as np from Bio import Phylo # 加载你的进化树文件(示例为newick格式) tree = Phylo.read("your_tree.nwk", "newick") fig, ax = plt.subplots() # 先绘制树但不显示 Phylo.draw(tree, ax=ax, do_show=False) # 应用坐标旋转变换:将整个树逆时针旋转90度 trans = Affine2D().rotate_deg(90) + ax.transData for line in ax.get_lines(): line.set_transform(trans) # 调整坐标轴范围适配旋转后的树 max_depth = max(tree.depths().values()) ax.set_xlim(-max_depth, 0) ax.set_ylim(0, len(tree.get_terminals())) # 隐藏原坐标轴刻度(可选) ax.set_xticks([]) ax.set_yticks([]) plt.show()
这段代码先按默认布局绘制树,再通过旋转变换把树转成向上生长的方向,最后调整坐标轴范围让树完整显示。
二、修改Matplotlib极坐标轴映射(x为径向,y为角度)
要让极坐标以原树的x轴(进化深度)为径向、y轴(叶子位置)为角度,需要手动交换绘图数据的x/y,并调整极坐标参数:
import matplotlib.pyplot as plt import numpy as np from Bio import Phylo # 加载进化树 tree = Phylo.read("your_tree.nwk", "newick") fig, ax = plt.subplots(subplot_kw={"polar": True}) # 以普通笛卡尔坐标绘制树,暂时隐藏标签避免混乱 Phylo.draw(tree, ax=ax, do_show=False, label_func=lambda _: "") # 遍历所有线条,交换x/y数据并转换角度为极坐标所需的弧度 for line in ax.get_lines(): orig_x, orig_y = line.get_data() # 将原y轴(叶子位置)归一化到0~2π的角度范围 angle = (orig_y - min(orig_y)) / (max(orig_y) - min(orig_y)) * 2 * np.pi # 原x轴(进化深度)作为径向长度 radius = orig_x line.set_data(angle, radius) # 调整极坐标显示:角度起点向上,逆时针排列 ax.set_theta_zero_location("N") ax.set_theta_direction(-1) # 隐藏径向刻度(可选) ax.set_yticklabels([]) # 添加叶子标签(手动对应位置) for idx, tip in enumerate(tree.get_terminals()): tip_angle = (idx / len(tree.get_terminals())) * 2 * np.pi tip_radius = tree.depths()[tip] + 0.1 # 标签略超出末端 ax.text(tip_angle, tip_radius, tip.name, ha="center", va="center") plt.show()
这段代码先在极坐标轴上按默认笛卡尔布局绘制树,然后把每个线条的x/y数据交换,将原y轴的叶子位置转换成极坐标的角度,原x轴的深度作为径向长度,最后调整极坐标的角度方向和添加标签,实现类似ete3的环形树效果。
内容的提问来源于stack exchange,提问作者Roger V.
相关产品推荐
相关产品推荐

