2015-09-05 49 views
8

我是一年級醫科學生,我想使用Graphviz創建一個易於解讀的人體解剖結構及其功能關係圖。特別是,我想創建一個包含大約50個肌肉,50個神經,50個動脈,80個骨骼和骨骼過程的圖形,肌肉附着到骨骼過程的近端和遠端點,其中神經支配哪些肌肉,哪些動脈灌注哪些肌肉,等等。人。Graphviz適用於人體解剖結構及其功能關係

對於代表所有這些結構及其所有關係(我知道這將是非常複雜的)的綜合圖像,我認爲圖表可能是表示這些結構及其功能關係的最佳方式,Graphviz看起來像用於製作這種圖形的好軟件,但有不同類型的邊連接結構。例如,嚴格根據宏觀結構的宏觀觀察,似乎腋神經來源於臂叢神經(BP)的後索,其包含來自BP的上,中,下行身的纖維,並且這三條樹幹含有源自脊髓神經C5,C6,C7,C8和T1的每個前部脊柱的神經纖維。然而,儘管有物理外觀,腋神經的電連接性使得它實際上包含起源於脊神經C5和C6前脊髓的神經纖維(見圖像,我應該在這裏解釋所有脊神經的所有神經纖維都是在實際的大體解剖結構中是相同的顏色,所以試圖想像沒有顏色的圖像以獲得關於顏色所示的物理連接與電連接的想法)。因此,爲了準確地表示腋神經和所有來自上游的神經纖維的物理連接性和電連接性,我需要至少兩種不同類型的邊緣:「物理」邊緣和「電」邊緣。我認爲Graphviz可以做這樣的事情,但我對使用Graphviz並不確定最佳的方式來完成這一點(儘管這不是我的主要問題)。

Human brachial plexus

我還需要找到一種方式來表示,如上述,其中神經纖維通過多種結構的路上,這些結構的下游名爲神經所描繪的關係。例如,在上面的圖像中,顏色用於顯示源自C6(藍色)的一組連續的神經纖維並纏繞到以下所有結構:「神經到下頜骨」,「上軀幹」,「側線「,」中位神經「,」橫向胸神經「,」腋神經「和」徑向神經「。

我試圖使用Graphviz來表示一些內容,如下圖所示。

Graphviz representation of some parts of human brachial plexus

我與像DOT語言代碼行創建了下面的(這是一個不完整的代碼段;不我用來創建該圖像的整個DOT文件):

snc05 -- bput -- bplc -- mn[color="#ffde17",penwidth=3]; 
snc06 -- bput -- bplc -- mn[color="#0056e0",penwidth=3]; 
snc07 -- bpmt -- bplc -- mn[color="#ff6f00",penwidth=3]; 
snc08 -- bplt -- bpmc -- mn[color="#be1e2d",penwidth=3]; 
snt01 -- bplt -- bpmc -- mn[color="#00a651",penwidth=3]; 

snc05 -- bput -- bppc -- rn[color="#ffde17",penwidth=3]; 
snc06 -- bput -- bppc -- rn[color="#0056e0",penwidth=3]; 
snc07 -- bpmt -- bppc -- rn[color="#ff6f00",penwidth=3]; 
snc08 -- bplt -- bppc -- rn[color="#be1e2d",penwidth=3]; 
snt01 -- bplt -- bppc -- rn[color="#00a651",penwidth=3]; 

但這種表現的主要問題是C6與臂叢上幹之間有多條藍色邊緣,C5與臂叢上幹之間有多條黃色邊緣,C7與臂叢中間幹之間有多條橙色邊緣,胸罩之間有多條橙色邊緣膽囊叢中間乾和臂叢側索。

我知道爲什麼有多條與上面段落顏色相同的邊。我明確地在DOT文件中創建了它們。而且爲了使邏輯正確(我最終可以用python或其他東西解析這個DOT文件),我確實希望DOT文件包含相同顏色的多條邊。但我不想看到渲染圖像中相同顏色的多個邊緣。

所以我的主要問題是:如何讓Graphviz抑制C6和上(高級)樹幹之間的5個藍色邊緣的渲染,並將它們渲染爲僅1個藍色邊緣?

第二個問題是:我如何強制Graphviz渲染不同顏色的邊緣,使得它們不相互重疊,因此每個不同顏色的邊緣在整個範圍內保持截然不同(從起始節點到相鄰節點)?上圖中出現問題的最佳示例可以在連接上(上)軀幹和後線的兩個(藍色和黃色)邊緣中看到。雖然藍色和黃色邊緣在兩個節點附近是不同的,但是在它們的跨度中間,它們完全重疊,以至於很難看到那裏有兩條邊;藍色幾乎完全遮掩了黃色。我希望找到一種強制Graphviz使藍色和黃色邊緣互不重疊的一般方法(我不希望必須直觀地檢查圖像並更正DOT文件,而是找到某種方式告訴Graphviz不允許邊緣重疊,除非它們可能是相同的顏色)。

以前的Graphviz圖像開始顯示爲什麼這個問題對我很重要,但現在已經在這個工作了更長的時間,下面的圖像顯示它更好。事情變得非常混亂,以至於很難解釋。

Nerves of the upper extremity according to Moore 2ed COA

@Simon感謝解釋(在下面的評論)約GNU head。在OS X上的head行爲有所不同,所以我使用了sed腳本,這消除了我的第一個問題。但是,我認爲您的removeDupEdge腳本可能會對我的.gv文件造成其他問題。

爲了演示,我將從您的示例multiEdge.gv文件開始。做一些細微的變化,我有:

graph { 
    node [style=filled]; 
    a [label="a1",fillcolor=green] 
    b [label="b1",fillcolor=purple] 
    c [label="c1"] 
    d [label="d1"] 
    e [label="e1"] 

    a -- b -- c[color = blue]; 
    a -- b -- c -- d[color = red]; 
    a -- c; 
    a -- b -- c -- d -- e[color = blue]; 
} 

removeDupEdge腳本似乎已處理這兩種性狀線以上嚴重:

$ ./removeDupEdge <multiEdge.gv 
graph { 
    node [label="\N", 
     label=a1]; 
     label=b1]; 
     style=filled 
    ]; 
    a [fillcolor=green, 
    a -- b [color=blue]; 
    a -- b [color=red]; 
    a -- c; 
    b [fillcolor=purple, 
    b -- c [color=blue]; 
    b -- c [color=red]; 
    c [label=c1]; 
    c -- d [color=blue]; 
    c -- d [color=red]; 
    d [label=d1]; 
    d -- e [color=blue]; 
    e [label=e1]; 
} 

我認爲這是不再有效DOT語言代碼。您的removeDupEdge腳本對我來說看起來很有希望,但我不確定如何解決它,因爲我上面展示的示例。我的.gv文件超過700行,我也使用DOT language documentation中允許的C++風格註釋。我不確定評論是否也會爲您的removeDupEdge腳本產生問題。

+0

也許這傢伙有一個答案:http://www.logarithmic.net/pfh/ghost-diagrams(他以令人印象深刻的圖表編程) –

+0

這些鬼圖不是數據可視化,但l系統https:// en .wikipedia.org/wiki/L-system – widged

+0

也許徑向佈局會更好 - http://www.graphviz.org/content/twopi2 – widged

回答

2

(重編輯,以使該方法穩健多屬性節點和邊)

對於第一個問題,GraphViz, grouping the same edges表明使用strict關鍵字從節點之間顯示多個邊緣停止graphviz。但是,這不會讓它在兩個節點之間爲每種顏色顯示一條邊。據我所知,最好的方法是處理graphviz文件,然後顯示它。

例如,假設multiEdge.gv

graph { 
    node [style=filled]; 
    a [label="a1",fillcolor=green] 
    b [label="b1",fillcolor=purple] 
    c [label="c1"] 
    d [label="d1"] 
    e [label="e1"] 

    a -- b -- c[color = blue]; 
    a -- b -- c -- d[color = red]; 
    a -- c; 
    a -- b -- c -- d -- e[color = blue]; 
} 

...這看起來是這樣的:

enter image description here

...我們可以用下面的腳本removeDupEdge處理它:

#!/bin/sh 
neato -Tcanon | perl -p -e 's/,\n/,/' >tmp.tmp 
head -3 tmp.tmp >header.tmp 
tail -1 tmp.tmp >tail.tmp 
tail -n +4 tmp.tmp | sed -n '$ !p' | sort | uniq | cat header.tmp - tail.tmp 

...這首先產生一個版本規範形式的腳本,其中每個邊去只有兩個節點之間。不幸的是,規範形式還會在逗號中以多行結尾放置多屬性節點和元素屬性列表,因此腳本的下一部分將使用perl重新加入以逗號結尾的所有行(感謝對How can you combine all lines that end with a backslash character?的回答)。然後,腳本將頂部三行和規範形式的底部行分別保存爲頁眉和頁腳,然後除了頁眉和頁腳行之外,對它們進行排序,僅保留唯一行,然後將頁眉和頁腳連接回形成合法的xdot文件。結果如下:

$ removeDupEdge <multiEdge.gv 
graph { 
     node [label="\N",    style=filled 
     ]; 
     a -- b [color=blue]; 
     a -- b [color=red]; 
     a -- c; 
     a  [fillcolor=green,    label=a1]; 
     b -- c [color=blue]; 
     b -- c [color=red]; 
     b  [fillcolor=purple,    label=b1]; 
     c -- d [color=blue]; 
     c -- d [color=red]; 
     c  [label=c1]; 
     d -- e [color=blue]; 
     d  [label=d1]; 
     e  [label=e1]; 
} 

我們可以然後顯示它:

$ removeDupEdge <multiEdge.gv | neato -Tpng -omultiEdge.png 

...獲得:

enter image description here

...這隻能說明一個副本每個相同的邊緣。

通過在sort之前插入sed 's/ */ /g',可以使腳本更穩健一些,因爲在排序和比較行之前,這將從xdot文件中刪除非重要空格。但是,它也會從(比如說)節點標籤中刪除多個空格,這可能不合意。

關於原始xdot源文件中的註釋,這不會引起問題,因爲它們被標準化進程刪除。

+2

這是我想要的解決方案。除了也許我已經用Perl或者tcl(或者甚至是javascript)寫了它。你甚至可以將分組的行加粗以表示它們被分組(如電子電路圖中的總線) – slebetman

+1

用Perl,Tcl或Python編寫(這將是我的首選),修改重複邊的屬性可以相當簡單使它們更厚。例如,我的答案[什麼是使用graphvis繪製大圖的最佳方式](http://stackoverflow.com/questions/16173764/what-is-the-best-way-to-draw-large-graph- using-graphvis/16311864#16311864)使用Python腳本修改邊的權重。 – Simon

+0

非常感謝您的回答。這聽起來像是對我來說很好的解決方案,但是當我嘗試它時,運行removeDupEdge腳本時出現錯誤:「head:非法行數 - -1」。我以爲「head -n-1」一定是這裏的罪魁禍首,但是當我將這部分代碼改爲「head -n 1」(刪除短劃線)時,我的腳本運行multiEdge.gv與您顯示的輸出不同。 – Osteoboon