Graphviz用于人体解剖结构及其功能关系

Ost*_*oon 8 graphviz

我是一名一年级的医科学生,我想用Graphviz创建一个易于理解的人体解剖结构图及其功能关系图.特别是,我想创建一个包含大约50个肌肉,50个神经,50个动脉,80个骨骼和骨骼过程的图形,肌肉附着到骨骼过程的近端和远端点,神经支配哪些肌肉,动脉灌注哪个肌肉,等等.人.

对于一个代表所有这些结构及其所有关系的综合图像(我知道这将非常复杂)我认为图形可能是表示这些结构及其功能关系的最佳方式,而Graphviz似乎是一个很好的制作软件这样的图形,但有不同类型的边连接结构.例如,严格地基于肉眼观察总体结构,似乎腋神经来自臂丛神经(BP)的后索,其包含来自BP的上,中,下中枢的纤维,以及这三个中继线.包含来自脊柱神经C5,C6,C7,C8和T1的每个前部rami的神经纤维.然而,尽管有外表,腋神经的电连接是这样的,它实际上包含起源于脊柱神经C5和C6的前部rami的神经纤维(见图像,我应该在这里解释所有脊髓神经的所有神经纤维在实际中都是相同的颜色)大体解剖,所以试着想象没有颜色的图像来了解物理连接与电气连接的关系,如颜色所示.因此,为了准确表示腋神经及其衍生的所有上游神经纤维的物理连通性和电连接性,我需要至少两种不同类型的边缘:"物理"边缘和"电"边缘.我认为Graphviz可以做那种事,但我'

人类臂丛神经

我还需要找到一种方法来表示上面描述的关系,其中神经纤维在通往这些结构下游的命名神经的途中经过多个结构.例如,在上图中,颜色用于显示一组连续的神经纤维,这些神经纤维起源于C6(蓝色)并且绕行所有以下结构:"神经到锁骨下","上躯干","侧脐带","中位神经","侧胸神经","腋神经"和"桡神经".

我试图用Graphviz表示其中一些,如下图所示.

Graphviz表示人类臂丛神经的某些部分

我使用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];
Run Code Online (Sandbox Code Playgroud)

但这种表现的主要问题是C6和臂丛上躯干之间有多个蓝色边缘,C5和臂丛上躯干之间有多个黄色边缘,C7和臂丛中间躯干之间有多个橙色边缘臂丛中间躯干和臂丛神经侧索之间有多个橙色边缘.

我知道为什么有多个边缘颜色与上面的段落相同.我在DOT文件中明确创建了它们.并且为了使逻辑正确(我最终可能用python或其他东西解析这个DOT文件),我确实希望DOT文件包含相同颜色的多个边.但我不想在渲染图像中看到相同颜色的多个边缘.

所以我的主要问题是:如何让Graphviz抑制C6和上(上)干线之间的5个蓝色边缘的渲染,并将它们渲染为仅1个蓝色边缘?

第二个问题是:如何强制Graphviz渲染不同颜色的边缘,使它们不会相互重叠,因此每个不同颜色的边缘在整个范围内(从始发节点到相邻节点)保持不同?在上图中的问题的最好例子可以在连接上(上)躯干和后脐带的两个(蓝色和黄色)边缘中看到.虽然蓝色和黄色边缘在两个节点附近是不同的,但是在它们的跨度的中间,它们完全重叠,很难看出那里有两条边; 蓝色几乎完全掩盖了黄色.我想找到一种强制Graphviz使蓝色和黄色边缘完全不重叠的一般方法(我不希望看到图像并纠正DOT文件,

之前的Graphviz图像开始显示为什么这个问题对我来说很重要,但现在已经对此工作了更长时间,下面的图像显示它更好.事情变得如此混乱,以至于难以解释.

根据Moore 2ed COA的上肢神经

@Simon感谢您解释(在下面的评论中)关于GNU head.head在OS X上的行为有所不同,所以我使用了你的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];
}
Run Code Online (Sandbox Code Playgroud)

你的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];
}
Run Code Online (Sandbox Code Playgroud)

我认为这不再是有效的DOT语言代码.你的removeDupEdge脚本看起来很有希望,但我不知道如何解决它我上面展示的例子.我的.gv文件超过700行,我也使用DOT语言文档中允许的C++样式注释.我不确定评论是否removeDupEdge也会为您的脚本带来问题.

Sim*_*mon 2

(经过大量编辑以使该过程对多属性节点和边具有鲁棒性)

关于第一个问题,GraphViz,对相同的边进行分组表明使用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];
}
Run Code Online (Sandbox Code Playgroud)

...看起来像这样:

在此输入图像描述

...我们可以使用以下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
Run Code Online (Sandbox Code Playgroud)

...它首先生成规范形式的脚本版本,其中每条边仅在两个节点之间。不幸的是,规范形式还将多属性节点和元素属性列表放在以逗号结尾的多行上,因此脚本的下一部分用于perl重新连接以逗号结尾的所有行(感谢如何组合所有行的答案)以反斜杠字符结尾?)。然后,该脚本将规范形式的前三行和底行分别保存为页眉和页脚,然后对除页眉和页脚之外的所有行进行排序,仅保留唯一的行,然后将页眉和页脚连接回形成法律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];
}
Run Code Online (Sandbox Code Playgroud)

然后我们可以用以下命令显示它:

$ removeDupEdge <multiEdge.gv | neato -Tpng -omultiEdge.png
Run Code Online (Sandbox Code Playgroud)

... 要得到:

在此输入图像描述

...仅显示每个相同边的一个副本。

sed 's/ */ /g'通过在 之前插入,可以使脚本更加健壮,因为这会在排序和比较行之前sort从文件中删除不重要的空格。xdot然而,它也会从(比如说)节点标签中删除多个空格,这可能是不可取的。

关于原始xdot来源中的注释,这不会造成问题,因为它们已被规范化过程删除。

  • 这是我想要的解决方案。除非我可能用 Perl 或 tcl(甚至 javascript)编写它。您甚至可以使分组线更粗以表示它们已分组(就像电子原理图中的总线) (2认同)