GraPhlAn:最美进化树或层级分类树学习笔记
文章目錄
- Graphlan可視化進化樹
- GraPhlAn簡介
- 素顏vs美化
- 認識軟件參數
- 分支控制,一般不做控制
- 組合命令控制注釋陰影的半徑
- 一般全局參數
- 節點基本參數
- 節點對應的形狀
- 節點注釋
- 枝條參數
- 環參數
- 進化樹實戰
- 構建OTU豐度和物種文件說明
- 準備需要展示的數據
- 構建三列注釋文件,主要是節點注釋
- 構建四列注釋文件,主要是環注釋
- 總體環修飾 指標可以保存基本小修即可
- graphlan出圖,三條命令三張圖
- 問題:分支節點未命名或無法命名
- 參考文獻
- 作者簡介
- 猜你喜歡
- 寫在后面
Graphlan可視化進化樹
撰文:文濤 南京農業的大學
責編:劉永鑫 中科院遺傳發育所
GraPhlAn簡介
總體來講,Graphlan是一個可視化進化樹和基于分類等級繪制層級分類樹的工具??梢灾谱鞣诸悩涫撬煌赗包ggtree和iTOL的地方。然就進化樹而言,iTOL功能最為全面,ggtree最容易上手,從功能上來講graphlan很多地方不如iTOL,比如,iTOL無限制添加的數據集,外環可以制作各種圖形包括箱線圖等,可以使用多種符號填充外環,但是Graphlan就不能這么隨便了,只能使用兩個符號填充外環。再多的環屬性也就是設置環數量和顏色,透明度了。ggtree最容易上手,但是就一張圈圖來說,它不能添加除了熱圖以外的其他圖形,但是在非圈圖的模式下,可以對多種數據進行合并,方法將更為簡單,操作也容易一些。
素顏vs美化
下面通過我們的實戰,將這個原始的圖形通過graphlan大法,改變到下面的樣子
完全認不出來了吧,這就是美顏的重要性。
認識軟件參數
參數雖多,你也不需要記住,只要認識即可,而且都是字面意思,懂英文看一遍全懂了,需要時可以來查。大多時間我們是在別人基礎上修改,能看懂代碼即可。
熟悉grahlan注釋參數-全局參數,
一般全局參數使用方式為:參數名 + 參數值
分支控制,一般不做控制
branch_bracket_depth 0##控制一個分支塊的聚集程度,值越大,樹枝越集中 branch_bracket_width 0 0###控制一個分支點延伸出來的分支線的長度,設定大了會反向延長超多分支點。 annotation_background_alpha :只能設置全部的陰影的透明度組合命令控制注釋陰影的半徑
一下兩個指標設置為負值,且兩者均設置為-0.7,會大大減小注陰影半徑
annotation_background_separation -0.40 annotation_background_offset -0.34一般全局參數
title:設置圖片題目 title_font_size:60 題目字體大小 total_plotted_degrees 350:這個設置整個圓圈的展看角度,不會設置超過360度,一般設置一個比360度小一點的值是為了添加標簽使用(例如:對環添加標簽ring_label)。 start_rotation 270:對圓圈圖進行旋轉的起始位置;注意圖形下方為270°,左方為0°。 class_legend_font_size 圖例大小設置 ## 全局注釋 annotation_background_alpha 0.02:全部注釋背景透明度; annotation_background_width 0.03 注釋背景寬度 annotation_font_size:設置注釋字體大小 annotation_legend_font_size 設置圖上容不下時,代表字母的對應注釋的字體大小branch_thickness:全局樹枝的粗細設置 branch_color :設置全局樹枝顏色 ignore_branch_len 10:控制全局樹伸展和大小 clade_marker_size:全局的點的尺寸 clade_marker_edge_width:全局的點的邊緣寬度 clade_separation 0.5 進化樹分枝簇的緊湊程度ring_internal_separator_thickness 0.01 設置環與環之間的厚度 ring_separator_color :設置環間隔的顏色,結合厚度設置選項增多ring_width:設置在這個環上每個點所占有的寬度; ring_height:設置環與環之間的距離,默認環與環之間的距離為1; ring_shape:對分類樹外面每層的空間設置形狀填充,有不多的中形狀可以選擇。v:正v字型;^:v字型; ring_alpha 0.01:這是對每個葉節點占據的位置不透明度,最大值為1。值越高顏色越深,當然需要結合設置顏色ring_color ring_color:每條環的顏色設置全局的環參數,必須建立在葉節點對應的shape上,不可只設置全局參數,尤其是全局ring color,僅僅設置該參數是無法進行全環上色的。默認節點shape是R,也就是整個葉節點對應的方塊。
節點基本參數
節點參數使用方式: 節點名稱 + 參數名稱 + 參數值
#節點基本參數 clade_marker_size 節點的大小,從1到200都可以設置 clade_marker_color:顏色:默認無色,r:紅色;b:藍色(基本為顏色首字母) clade_marker_shape:形狀:默認圓形,*:代表五角星,h:代表六邊形 clade_marker_label:設置點內部寫一個標簽,后面跟上標簽內容 clade_marker_font_color:設置點內標簽的字體顏色 clade_marker_edge_color #555555 控制節點的顏色 clade_marker_edge_width 1.2#節點的邊的寬度節點對應的形狀
這些標簽有我們熟悉的點,圈,各個方向的三角,五邊形,五角星,鉆石等。具體符號和對應名稱如下:
'.' : point marker ',' : pixel marker 'o' : circle marker v' : triangle_down marker '^' : triangle_up marker '<' : triangle_left marker '>' : triangle_right marker '1' : tri_down marker '2' : tri_up marker '3' : tri_left marker '4' : tri_right marker 's' : square marker 'p' : pentagon marker '*' : star marker 'h' : hexagon1 marker 'H' : hexagon2 marker '+' : plus marker 'x' : x marker 'D' : diamond marker 'd' : thin_diamond marker '|' : vline marker '_' : hline marker節點注釋
#節點注釋 annotation_background_color annotation_background_alpha 0.02:注釋背景透明度; annotation_background_width 0.03 注釋背景寬度 annotation_font_size:設置注釋字體大小 annotation_legend_font_size設置圖上容不下,設置成代表字母的對應注釋的注釋字體大小枝條參數
branch_thickness 枝條的厚度 branch_color 枝條顏色 branch_color_from_ancestor:使用上級分支的顏色環參數
ring_internal_separator_thickness 0.01 設置環與環之間的厚度 ring_separator_color :設置環間隔的顏色,結合厚度設置選項增多ring_width:設置在這個環上每個點所占有的寬度; ring_heigh:設置環與環之間的距離,默認環與環之間的距離為1; ring_shape:對分類樹外面每層的空間設置形狀填充,有不多的形狀可以選擇。v:正v字型;^:^字型; ring_alpha 0.01:這是對每個葉節點占據的位置不透明度,最大值為1。值越高顏色越深,當然需要結合設置顏色ring_color ring_color:每條環的顏色進化樹實戰
使用材料
分析要求
構建OTU豐度和物種文件說明
上面我們見過軟件的參數,每個節點都要注釋,如果手動搞,可能真要3天至半個月畫個美顏樹。只要是批量操作且有規律,我們就可以用編程來實現。
使用R語言構造注釋文件,這里我們明確,基于GraPhlAn的注釋文件按照注釋占有列數量我分為一下三個部分:
由于注釋文件編寫耗費很大時間,Excel適合編寫的也僅僅只有占兩列的數據,和總環的參數。這部分編寫完成之后每次繪圖基本只根據不同的實驗,會小范圍修改。參考模板:annot1.txt
首先根據之前要求,準備要處理文件
并確定工作目錄包括所需的OTU表、物種注釋、實驗設計等文件,文件名與代碼中不對應請自行修改。
測試數據和代碼下載鏈接,后臺回復“graphlan”獲取
準備需要展示的數據
OTU表和實驗設計的讀取、交叉篩選和標準化
# 讀取OTU表 otu = read.table("otu_table.txt", sep="\t",row.names= 1,header=T, check.names=F) head(otu) # 讀入實驗設計 design = read.table("metadata.txt", header=T, row.names= 1, sep="\t") head(design, n=12L) # 交叉篩選,保持實驗設計和OTU中樣本對應 idx = rownames(design) %in% colnames(otu) sub_design = design[idx,] # 過濾OTU表 OTU = otu[,rownames(design)] head(OTU) OTU = as.matrix(OTU)# 原始reads count表標準化 norm = t(t(OTU)/colSums(OTU,na=T)) #* 100 可 normalization to total 100 # 轉置并轉換為數據框 library(dplyr) norm1 = norm %>% t() %>% as.data.frame() norm1[1:3,1:3]計算分組均值
# 數據分組計算平均值 otutab.split = split(norm1,as.factor(sub_design$SampleType_RS)) otutab.apply = lapply(otutab.split,function(x)colSums(x)) norm2 = do.call(rbind,otutab.apply) %>% t() # OTU表后面添加分組均值 OTU_all= cbind(as.data.frame(norm),norm2) head(OTU_all)追加物種注釋
# 讀取OTU對應的物種注釋 # 9列,分別為ID,界門綱目科屬種和置信度 tax = read.delim("rep_seqs_tax.txt", sep="\t",row.names= 1,header=F, check.names=F) # 只保留物種7級分類 tax = tax[1:7] head(tax) # 添加分類級列名:界門綱目科屬種 colnames(tax) =c("kingdom","phylum","class","order","family","genus","species")# OTU表再添加物種注釋 index = merge(OTU_all,tax, by="row.names",all=F) row.names(index) = index$Row.names index$Row.names = NULL head(index)上面,我們制作OTU對應豐度、平均豐度和物種注釋的數據
映射豐度至顏色
# 設定顏色梯度,橙-白-綠三色過濾 colorg = colorRampPalette(c( "#D95F02", "white","#1B9E77"))(12) # 通用繪圖縮放方法 Generic plot scaling methods library("scales") # 顯示顏色和對應16進制RGB代碼 show_col(colorg)# 建立12種顏色的數據框 c = data.frame(id = c(1:12),col = colorg) # 提取前面OTU中12個樣品的豐度部分 a = index[1:12]for(i in 1:nrow(a)){a[i,1:12] = match(colnames(a[i,1:12]), colnames(sort(a[i,1:12])))} # 填充顏色:替換豐度順序為對應的顏色 for(i in 1:nrow(a)){aa = a[i,]aa = as.data.frame(aa)colnames(aa) = aa[1,]ccc =t(c[colnames(aa),]) a[i,] = ccc[2,]} head(a) out = cbind(index,a) head(out)映射分組為開關
##組比對映射形狀 HH = c(rep("A",nrow(out))) LL = c(rep("A",nrow(out))) # 兩組比較,大的標為v,小的為空 for(i in 1:nrow(out)){if(out[i,13] > out[i,14]){HH[i] ="v"LL[i] =" "}else if(out[i,13] == out[i,14]){HH[i] =" "LL[i] =" "}else if(out[i,13] < out[i,14]){HH[i] =" "LL[i] ="^"}} # 繼續追加至表末 out2 = cbind(out,HH,LL) head(out2)差異分析
###下一步添加差異分析結果 # 安裝bioconductor包安裝工具 # if (!requireNamespace("BiocManager", quietly = TRUE)) # install.packages("BiocManager") # 安裝差異比較包DESeq2 # BiocManager::install("DESeq2", version = "3.8") # BiocManager::install("GenomeInfoDb", version = "3.8") # BiocManager::install("S4Vctors", version = "3.8") library(DESeq2) library(limma) # BiocManager::install("pasilla", version = "3.8") library(pasilla) # library(DESeq) head(OTU ) count = OTU count=as.matrix(count)#######首先比較發病和健康中的差異############# # 讀入矩陣和實驗設計,指定分類 dds = DESeqDataSetFromMatrix(countData = count,colData = sub_design,design = ~ SampleType_RS)dds2 = DESeq(dds) ##第二步,標準化 resultsNames(dds2) # 將結果用results()函數來獲取,賦值給res變量 res = results(dds2, contrast=c("SampleType_RS","BL", "BH"),alpha=0.05) # summary一下,看一下結果的概要信息 summary(res) # 按校正P值和差異倍數,添加顏色 res$level = as.factor(ifelse(res$padj < 0.05 & res$log2FoldChange > 1, "#D95F02",ifelse(res$padj < 0.05 & res$log2FoldChange < -1, "#1B9E77"," "))) head(res) # 提取篩選的顯著差異,添加至otu表 res1 = as.data.frame(res[ncol(res)]) OTU_TAX_all = merge(out2,res1, by="row.names",all=F) head(OTU_TAX_all) dim(OTU_TAX_all) row.names(OTU_TAX_all) = OTU_TAX_all$Row.names OTU_TAX_all$Row.names = NULL構建三列注釋文件,主要是節點注釋
##構建進化樹節點屬性注釋文件 # head(OTU_TAX_all) pcol = c(rep("A",nrow(OTU_TAX_all))) psha = c(rep("A",nrow(OTU_TAX_all))) # 按門水平手動設置顏色和形狀 for(i in 1:nrow(OTU_TAX_all)){if(OTU_TAX_all[i,16] == "p__Acidobacteria"){pcol[i] ="#B0171F"psha[i] ="*"}else if(OTU_TAX_all[i,16] == "p__Proteobacteria"){pcol[i] ="#D15FEE"psha[i] ="o"}else if(OTU_TAX_all[i,16] == "p__Acidobacteria"){pcol[i] ="#B0171F"psha[i] ="*"}else if(OTU_TAX_all[i,16] == "p__Verrucomicrobia"){pcol[i] ="#00CD00"psha[i] ="*"}else if(OTU_TAX_all[i,16] == "p__Cyanobacteria"){pcol[i] ="#87CEFA"psha[i] ="*"}else if(OTU_TAX_all[i,16] == "p__Actinobacteria"){pcol[i] ="#FEC80A"psha[i] ="*"}else if(OTU_TAX_all[i,16] == "p__Bacteroidetes"){pcol[i] ="#EE6A50"psha[i] ="*"}else if(OTU_TAX_all[i,16] == "p__Chloroflexi"){pcol[i] ="#7B68EE"psha[i] ="D"}else if(OTU_TAX_all[i,16] == "p__Gemmatimonadetes"){pcol[i] ="#9ACD32"psha[i] ="*"}else if(OTU_TAX_all[i,16] == "p__Firmicutes"){pcol[i] ="#8DEEEE"psha[i] ="*"}else {pcol[i] ="#006400"psha[i] ="*"} } # OTUID對應物種顏色形狀數據框 ano4 = cbind(row.names(OTU_TAX_all),pcol,psha) # head(ano4) ano4 = as.data.frame(ano4)生成三列的graphlan要求結點注釋文件
# 節點顏色映射 ste1 = data.frame(a = ano4$V1,b = c(rep("clade_marker_color",nrow(OTU_TAX_all))),c = ano4$pcol) head(ste1) # 節點形狀映射 ste2 = data.frame(a = ano4$V1,b = c(rep("clade_marker_shape",nrow(OTU_TAX_all))),c = ano4$psha) head(ste2) # 節點陰影映射顏色,同節點顏色 ste3 = data.frame(a = ano4$V1,b = c(rep("annotation_background_color",nrow(OTU_TAX_all))),c = ano4$pcol) head(ste3) # 注釋透明度,淡色,如0.1透明 ste4 = data.frame(a = ano4$V1,b = c(rep("annotation_background_alpha",nrow(OTU_TAX_all))),c = c(rep(0.1,nrow(OTU_TAX_all)))) head(ste4) ste4$c = as.factor(ste4$c) # 節點大小,這里統一寫10,LEfSe中按豐度大小變化 ste5 = data.frame(a = ano4$V1,b = c(rep("clade_marker_size",nrow(OTU_TAX_all))),c = c(rep(10,nrow(OTU_TAX_all)))) head(ste5) ste5$c = as.factor(ste5$c)# 保存文件 ste_all = rbind(ste1,ste2,ste3,ste4,ste5) head(ste_all) # 保存統計結果,有waring正常 write.table(ste_all, "annot2.txt", append = F, quote = F, sep="\t", eol = "\n", na = "NA", dec = ".", row.names = F, col.names = F)構建四列注釋文件,主要是環注釋
# 構建單樣品豐度映射文件,共12列 # 提取之前按豐度構建的顏色矩陣 anno1 = OTU_TAX_all[22:33] head(anno1) # 設置樣本對應環編號 colnames(anno1 ) = c(1:3,7:12,4:6) anno1$id = row.names(anno1) library("reshape2") # 構建3列文件,ID,環編號,對應顏色 anno11 = melt(anno1,id.vars = "id",variable.name = "ring",value.name = "color") # 添加第4列,類型 anno11$ringcolor = c(rep("ring_color",nrow(anno11))) # 調整列的序列,前兩列為ID和類型,其它在后面 anno11 = select(anno11,id,ringcolor,everything()) head(anno11) ##構建平均豐度標志映射文件 anno2 = data.frame(OTU_TAX_all$LL,OTU_TAX_all$HH,row.names = row.names(OTU_TAX_all)) head(anno2) # 位置為13/14圈 colnames(anno2 ) = c(13,14) anno2$id = row.names(anno2) anno22 = melt(anno2,id.vars = "id",variable.name = "ring",value.name = "shape") anno22$ringshape = c(rep("ring_shape",nrow(anno22))) anno22 = select(anno22,id,ringshape,everything()) # 只保留有差異,即有形狀標記的行 anno222 = anno22[anno22$shape %in% c("^","v"),] head(anno222) ##構建差異分析顏色標記文件 anno3 = data.frame(id = row.names(OTU_TAX_all),ringcolor = c(rep("ring_color",nrow(OTU_TAX_all))),ring =c(rep(15,nrow(OTU_TAX_all))),color = OTU_TAX_all$level ) anno3$ring = as.factor(anno3$ring) head(anno3) anno33 = anno3[anno3$color %in% c("#D95F02","#1B9E77"),] # 合并1,3批的顏色注釋 head(anno11);dim(anno11) ann_all = rbind(anno11,anno33) # 第二批為形狀,需改列名再合并 colnames(anno222) = colnames(ann_all) ann_all2 = rbind(ann_all,anno222) head(ann_all2) # 添加物種豐度總體特征 # 計算所有樣品的均值 norm$mean = apply(norm,1,mean) head(norm) # 計算平方根,標準化數據更均勻 norm$mean = sqrt(norm$mean) norm$mean = sqrt(norm$mean)# 第16列行高度展示豐度的4次方根 ste6 = data.frame(a = ano4$V1,b = c(rep("ring_height",nrow(OTU_TAX_all))),c = c(rep(16,nrow(OTU_TAX_all))),d = norm$mean) head(ste6) ste6$c = as.factor(ste6$c) # 統一列名,并合并 colnames(ste6) = colnames(ann_all2) ann_all3 = rbind(ann_all2,ste6) head(ann_all3) # 保存文件 write.table(ann_all3, "annot3.txt", append = F, quote = F, sep="\t", eol = "\n", na = "NA", dec = ".", row.names = F, col.names = F)總體環修飾 指標可以保存基本小修即可
title Metagenomic title_font_size 12 total_plotted_degrees 350 start_rotation 270 branch_bracket_depth 0 branch_bracket_width 0 branch_color g branch_thickness 0.5 ignore_branch_len 0 clade_marker_size 0.6 clade_marker_edge_width 0.35 class_legend_font_size 9 annotation_background_separation -0.4 annotation_background_offset -0.33 annotation_background_width 0.03 annotation_background_alpha 0.01 annotation_font_size 8 annotation_legend_font_size 9 ring_internal_separator_thickness 1 0.3 ring_internal_separator_thickness 2 0.3 ring_internal_separator_thickness 3 0.1 ring_internal_separator_thickness 4 0.1 ring_internal_separator_thickness 5 0.1 ring_internal_separator_thickness 6 0.1 ring_internal_separator_thickness 7 0.1 ring_internal_separator_thickness 8 0.1 ring_internal_separator_thickness 9 0.1 ring_internal_separator_thickness 10 0.1 ring_internal_separator_thickness 11 0.1 ring_internal_separator_thickness 12 0.1 ring_internal_separator_thickness 13 0.1 ring_internal_separator_thickness 14 0.1 ring_internal_separator_thickness 15 0.1 ring_internal_separator_thickness 16 0.1 ring_separator_color 1 y ring_separator_color 2 y ring_separator_color 3 b ring_separator_color 4 b ring_separator_color 5 b ring_separator_color 6 b ring_separator_color 7 b ring_separator_color 8 b ring_separator_color 9 b ring_separator_color 10 b ring_separator_color 11 b ring_separator_color 12 b ring_separator_color 13 r ring_separator_color 14 b ring_separator_color 15 r ring_separator_color 16 r ring_width 1 0.3 ring_height 1 0.5 ring_height 2 0.1 ring_height 3 0.1 ring_height 4 0.1 ring_height 5 0.1 ring_height 6 0.1 ring_height 7 0.1 ring_height 8 0.1 ring_height 9 0.1 ring_height 10 0.1 ring_height 11 0.1 ring_height 12 0.1 ring_height 13 0.1 ring_height 14 0.1 ring_height 15 0.1 ring_height 16 0.1graphlan出圖,三條命令三張圖
注:如果沒有graphlan,需要在linux服務器上,按官網或conda安裝
推薦conda一條命令安裝conda install graphlan
基于結點顏色、形狀、背景色+透明度(annon2.txt)美化進化樹(rep_set.tree)
# 進化樹結合注釋 graphlan_annotate.py --annot annot2.txt rep_set.tree 1.xml # 繪制150dpi的PNG graphlan.py --dpi 150 1.xml 1.png # 繪制矢量圖PDF graphlan.py 1.xml 1.pdf在上圖的基礎上,外圈添加豐度(anno3.txt),包括12個樣品,各組中高/低,極是否顯著
graphlan_annotate.py --annot annot3.txt 1.xml 2.xml graphlan.py --dpi 150 2.xml 2.png graphlan.py 2.xml 2.pdf添加基本全局參數,調圖形樣式
graphlan_annotate.py --annot annot1.txt 2.xml 3.xml graphlan.py --dpi 300 3.xml 3.png graphlan.py 3.xml 3.pdf問題:分支節點未命名或無法命名
在擴增子分析中,我們經常構建的無根進化樹,有沒有根倒是無所謂,但是這些使用Fastree構建的進化樹有共同的特征,就是除了葉節點,其余分支節點命名無法在graphlan指明。
進化樹文件局部示例:
((((((((('OTU_512':0.01655,'OTU_592':0.05858)==1.000:0.15061==,((('OTU_409':0.05856,但是這里我們可以看到分支節點名為1.000,但是在注釋文件中通過這個節點無法添加相應的操作。
參考文獻
Asnicar F, Weingart G, Tickle T L, et al. Compact graphical representation of phylogenetic data and metadata with GraPhlAn[J]. PeerJ, 2015, 3: e1029. http://huttenhower.sph.harvard.edu/GraPhlAn
作者簡介
文濤:2016年就讀于南京農業大學。榮拜資源院沈其榮教授課題組,研究方向為根際微生物生態,具體為植物介導下根際小分子代謝組同土壤微生物群落在防控土傳病害方面的相互作用。關注宏基因組和代謝組。大家有興趣可以通過2018203048@njau.edu.cn交流。歡迎打擾!
猜你喜歡
- 10000+: 菌群分析
寶寶與貓狗 提DNA發Nature 實驗分析誰對結果影響大 Cell微生物專刊 腸道指揮大腦 - 系列教程:微生物組入門 Biostar 微生物組 宏基因組
- 專業技能:生信寶典 學術圖表 高分文章 不可或缺的人
- 一文讀懂:宏基因組 寄生蟲益處 進化樹
- 必備技能:提問 搜索 Endnote
- 文獻閱讀 熱心腸 SemanticScholar Geenmedical
- 擴增子分析:圖表解讀 分析流程 統計繪圖
- 16S功能預測 PICRUSt FAPROTAX Bugbase Tax4Fun
- 在線工具:16S預測培養基 生信繪圖
- 科研經驗:云筆記 云協作 公眾號
- 編程模板: Shell R Perl
- 生物科普: 腸道細菌 人體上的生命 生命大躍進 細胞暗戰 人體奧秘
寫在后面
為鼓勵讀者交流、快速解決科研困難,我們建立了“宏基因組”專業討論群,目前己有國內外5000+ 一線科研人員加入。參與討論,獲得專業解答,歡迎分享此文至朋友圈,并掃碼加主編好友帶你入群,務必備注“姓名-單位-研究方向-職稱/年級”。技術問題尋求幫助,首先閱讀《如何優雅的提問》學習解決問題思路,仍末解決群內討論,問題不私聊,幫助同行。
學習擴增子、宏基因組科研思路和分析實戰,關注“宏基因組”
點擊閱讀原文,跳轉最新文章目錄閱讀
https://mp.weixin.qq.com/s/5jQspEvH5_4Xmart22gjMA
總結
以上是生活随笔為你收集整理的GraPhlAn:最美进化树或层级分类树学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在线学ajax,ajax学习
- 下一篇: 软件项目管理(二)