2017-07-20 46 views
1

我試圖用R程序包igraph生成樹狀圖。我開始與鄰接矩陣Y,看起來像這樣:生成igraph佈局時修復y座標

Y <- matrix(c(1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, 
       1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0, 
       0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, 
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0, 
       0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0, 
       0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, 
       0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, 
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,1, 
       0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, 
       0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, 
       0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, 
       0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1), 
       ncol=25) 

然後,我創建使用

g <- graph_from_adjacency_matrix(Y,mode="undirected",diag=F) 

現在我要繪製一個樹狀圖與第一節點之上的曲線圖樹,爲此我做

L <- layout.reingold.tilford(g,root=1) 
plot.igraph(g,layout=L) 

結果看起來非常接近我所期待的,但現在我想使用自定義y座標爲頂點。原因是我想讓y軸有意義:我有一個score值爲每個頂點,我希望y座標與該分數成正比。當然,我可以簡單地使用

L[,2] <- score 

的問題是,這樣做這樣做,我搞砸了劇情,讓重疊的頂點和交叉邊緣,這是不可取的。我可以通過用tkplot手動調整x座標來解決這個問題,但最終我需要自動生成幾個圖並手動逐個檢查它們是不可行的。

所以問題是,是否有任何方法可以使用預定義的y座標爲頂點獲得「最優」樹形圖表示?

希望我已經清楚了。在此先感謝您的時間!

Ĵ

編輯:這是我所得到的,如果我dput我的圖表變量g(注意,由於頂點屬性的scores已添加,並且可以通過V(g)$scores被accesed)

> dput(g)  
structure(list(25, FALSE, c(1, 2, 5, 4, 6, 3, 12, 8, 11, 13, 
14, 17, 7, 9, 19, 20, 10, 18, 22, 24, 15, 16, 21, 23), c(0, 0, 
0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 8, 13, 13, 
16, 16), c(0, 1, 5, 3, 2, 4, 12, 7, 13, 16, 8, 6, 9, 10, 20, 
21, 11, 17, 14, 15, 22, 18, 23, 19), c(0, 1, 2, 3, 4, 5, 6, 7, 
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23), 
    c(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
    16, 17, 18, 19, 20, 21, 22, 23, 24), c(0, 3, 5, 7, 9, 12, 
    14, 14, 16, 20, 20, 20, 20, 20, 22, 22, 22, 24, 24, 24, 24, 
    24, 24, 24, 24, 24), list(c(1, 0, 1), structure(list(), .Names = character(0)), 
     structure(list(name = c("GO:0008150", "GO:0050896", "GO:0044699", 
     "GO:0044767", "GO:0051716", "GO:0016043", "GO:0002544", 
     "GO:0071822", "GO:0048513", "GO:0007044", "GO:0007517", 
     "GO:0030855", "GO:0006816", "GO:0007165", "GO:0042178", 
     "GO:0007169", "GO:0009966", "GO:0070458", "GO:0090131", 
     "GO:0007052", "GO:0006335", "GO:2000587", "GO:0045653", 
     "GO:0070372", "GO:0003257"), scores = c(0, 0.301029995663981, 
     0.301029995663981, 0.602059991327962, 0.602059991327962, 
     0.602059991327962, 0.778151250383644, 0.778151250383644, 
     1, 1.04139268515822, 1.07918124604762, 1.07918124604762, 
     1.11394335230684, 1.11394335230684, 1.14612803567824, 
     1.20411998265592, 1.23044892137827, 1.25527250510331, 
     1.25527250510331, 1.27875360095283, 1.39794000867204, 
     1.50514997831991, 1.63346845557959, 1.70757017609794, 
     1.96378782734556), color = c("black", "black", "black", 
     "black", "black", "black", "red", "black", "black", "red", 
     "red", "red", "red", "black", "red", "red", "black", 
     "red", "red", "red", "red", "red", "red", "red", "red" 
     )), .Names = c("name", "scores", "color")), list()), 
    <environment>), class = "igraph") 
+0

您可以輸入您的數據嗎?您可能需要'layout_with_sugiyama',將'scores'傳遞給'layers'參數。但是如果沒有這些數據就不能測試。 – paqmo

+0

我剛剛編輯了添加'g'變量的'dput'的問題。我也嘗試過'L <-layout_with_sugiyama(g,layers = V(g)$ scores)',然後用'plot.igraph(g,layout = L $ layout)'進行繪圖,並且確實將頂點置於由'scores'指定的y位置,我仍然在邊緣之間出現一些醜陋的交叉點... –

回答

0

由於layout_with_sugiyama沒有工作,我會建議更多的黑客,或更確切地說兩個黑客,一個建築在另一個。

首先,稍微清洗一下。使用克你的dput版本,我得到警告

graph was created by an old(er) igraph version. 
Call upgrade_graph() on it to use with the current igraph version 
For now we convert it on the fly... 

於是我開始g = upgrade_graph(g)
接下來,當我繪製的圖表,我覺得很難,因爲 海軍文本上閱讀黑色節點。所以,我正在改變你的節點灰色。 如果你願意,你可以不發表。
V(g)$color[V(g)$color == "black"] = "#888888"

現在我們需要佈置圖形。我將開始爲您 萊因戈爾德-蒂爾福德
L <- layout.reingold.tilford(g,root=1)
做但是,這並不用你scores。當然,一個佈局,只給 x-y位置的節點,所以黑客頭號是隻是用你的分數覆蓋y值的 。

L2 = L 
L2[,2] = V(g)$scores 
plot(g,layout=L2) 

該地塊有點擁擠到繪圖區域的中心。所以我會 擺脫邊緣。

par(mar=rep(0,4)) 
plot(g,layout=L2) 

First plot of graph

這是不是太糟糕,但也有一些節點的標籤仍然重疊。 黑客的第二個問題是我只是將這些「手動」移動。

L3 = L2 
L3[18,1] = -2.2 
L3[19,1] = -1.1 
L3[12,1] = 0 
L3[13,1] = 1 
plot(g,layout=L3) 

此時,高度與您的分數成正比並且沒有標籤重疊。

Cleaner Plot