改善Graphviz布局

24

当涉及到制作图形时,我会陷入完美主义麻烦。如果视觉对称性没有被充分探索,我就很难理解发生了什么。我也是一个非常视觉化的学习者,我喜欢简化我学到的东西并在纸上画出来。

Graphviz是一个不错的自动绘图工具,但它可能会更好。让我们以一个好的图形(一个状态机)为例。暂且不论质量(它可以用更好的工具重新绘制),这个状态机几乎完美,除了我会把它逆时针旋转45度以使对称性明显。然后读者应该会花更少的时间来弄清楚q1和q2状态的相似之处以及它们的不同之处。我认为,在它旁边没有其他图形的情况下,有一种最佳的表示方式。

http://gallery.hd.org/_exhibits/maths/math-finite-state-machine-DHD.gif
(来源:gallery.hd.org)

现在让我们看一个不太完美的描述:

http://linux.softpedia.com/screenshots/Graphviz_1.png
(来源:softpedia.com)

这看起来像是Graphviz生成的东西。是的,边缘很平滑,但是这太令人困惑了!它看起来像是一个思维导图,而不是一个成品图表,可以供人们使用。我认为人类眼睛渴望(不少于)对称性。是的,层次结构等也是重要因素。

我很惊讶没有更好的算法可用。有些人根本不是视觉学习者,他们可以通过阅读符号来理解抽象概念。但我不行!

那么,我的问题是什么?嗯,是否有更好的免费软件可用于绘制中小型图形?也许?

谢谢!

请告诉我如何改进这篇文章。

P.S. 我花了10分钟在dia中画出一个相似的克隆版本。它还不完美,但很方便制作,因为一切都可以对齐网格(我错过了一些小细节,但不想重新上传)。LR_0需要从上面添加“开始--->”以让用户更快地掌握起始状态。

有限状态机


3
你能否用代码的术语来定义“美”是什么?你感到惊讶的是,目前并没有更好的算法存在,但是当涉及到创建任意图形时,“更好”的定义并不十分明确 :) 你似乎渴望对称,但你也承认其他人可能更喜欢强调层次结构、平滑边缘等方面。 - Peter Recore
1
graphviz有很多选项可以改变布局、线条等(尽管从文档中几乎不可能弄清楚如何工作)。例如,您可以尝试将rankdir=LR;添加到图形中以更改布局。 - nos
在第一个图中,LR_2 也通过 SS(a) 连接到 LR_5,而在第二个图中,它通过 S(A) 连接到另一个名为 LR_2 的节点。 - MERose
5个回答

23
在尝试了多次绘制并未得到您认为最好的布局之后,您在这里提出了问题:“有没有更好的免费软件可以绘制小到中等规模的图形。”您给出评估布局算法的唯一标准是它们与“代表该图表的单一最佳方法”有多接近。当然,“最好”的评判留给您决定。
这与用给定的编程语言解决问题、失败,然后寻求更好的编程语言几乎相同。
图形绘制算法的核心是优化程序,生成和评估解决方案(此处的“解决方案”是指每个节点的坐标,它们组成一个布局)。根据最小化单个标准或一系列排名标准来评估这些解决方案-即最小化图的一个或多个属性,例如穿越的总边数,或者节点间距离的总和(或两者的组合,或这两个因素的加权组合),或接近对称构型。Graphviz由六种不同的布局算法组成(dot,neato,fdp,sfdp,twopi和circo)。其中,似乎您只使用了dot;但是,考虑到其严格对称性约束条件,twopi和circo可能是更好的选择,这似乎与您对正确绘制图形的想法相匹配。
其次,您问题的文本是关于“图”和图形绘制的。在阅读了您的完整描述后,我不认为您的问题与这两个概念有任何关系。除了一般的图形绘制算法(如graphviz)之外,还有一些特定领域的布局算法,例如Hasse图(用于表示偏序集合),Barabasi-Albert图(无标度网络)和Erdos-Renyi(随机图)。每个算法根据领域提供的标准和约束条件生成图形布局--这应该告诉您,在所有领域中,并不存在单一的"最佳"布局。尽管您在问题中使用了术语"图形",但您的描述表明您的问题与绘制状态机有关--这是一种高度独特的图形类型。通常,一般的图形绘制算法往往不擅长绘制此类专门的图形,因为算法对领域一无所知。实际上,我不知道任何状态图的布局算法--就像不存在流程图的布局算法(虽然不同,但相似)。工作流方面,您可以在graphviz中绘制图形,然后将其导入Omnigraffle进行微调--在Omnigraffle中,您将拥有对节点和边缘位置的精细控制。

5
一些软件允许用户实时调整布局算法,只要用鼠标移动节点即可。这种方法可以大大帮助您处理较大的图形。
我主要了解 Gephi(声明:我是一名开发者)。

3

TikZ生成美丽的图形布局。您可以使用手动布局,让您指定最少的提示,或者您可以请求自动布局。默认设置很好,并且还有钩子可以进行微调。

使用半手动布局,您不必声明每个细节,因为您可以

  • 将节点声明为相对于其他节点的“上方”,“右下方”等位置。
  • 通过将它们输入为矩阵,在光栅上放置节点:如果要留出一些位置,则非常方便。
  • 轻松指定边缘应该进入、离开、弯曲或拐角的方向

对于自动布局,TikZ的graphdrawing库具有一些相当流畅的算法

这是一个手动布局的示例和用于获取它的TeX代码:

example graph

\usepackage{pgf}
\usepackage{tikz}
\usetikzlibrary{arrows,automata}
\usepackage[latin1]{inputenc}
\begin{document}
\begin{tikzpicture}[->,>=stealth',shorten >=1pt,auto,node distance=2.8cm,
                    semithick]
  \tikzstyle{every state}=[fill=red,draw=none,text=white]

  \node[initial,state] (A)                    {$q_a$};
  \node[state]         (B) [above right of=A] {$q_b$};
  \node[state]         (D) [below right of=A] {$q_d$};
  \node[state]         (C) [below right of=B] {$q_c$};
  \node[state]         (E) [below of=D]       {$q_e$};

  \path (A) edge              node {0,1,L} (B)
            edge              node {1,1,R} (C)
        (B) edge [loop above] node {1,1,L} (B)
            edge              node {0,1,L} (C)
        (C) edge              node {0,1,L} (D)
            edge [bend left]  node {1,0,R} (E)
        (D) edge [loop below] node {1,1,R} (D)
            edge              node {0,1,R} (A)
        (E) edge [bend left]  node {1,0,R} (A);
\end{tikzpicture}
\end{document}

什么是TikZ?它是LaTeX的某个包吗?LaTeX是免费的吗?Homebrew不知道“tlmgr”公式。 - Nakilon

3

我知道一些选项:

  • Prefuse - 他们有一个旧版的Java版本。最新版本是Flash,具有一些不错的布局。它被称为Prefuse Flare演示页面展示了一些它的布局功能。
  • JUNG包括许多布局选项,以及强大的图形分析功能。这里有一些示例
  • Networkx还包括众多布局功能。其中一些列在这里

2

Graphviz可以生成您指定的图表。
图片:
使用Graphviz制作的有限状态机图 脚本:

digraph {
    ranksep=1;
    nodesep=0.5;

    node [shape=circle]

    Start [margin=0 width=0 shape=plaintext]
    q0 [shape = doublecircle label=<<I>q</I><SUB>0</SUB>>]
    q1 [label=<<I>q</I><SUB>1</SUB>>]
    q2 [label=<<I>q</I><SUB>2</SUB>>]
    q3 [label=<<I>q</I><SUB>3</SUB>>]

    Start -> q0
    q1 -> q0 [xlabel="1"]
    q0 -> q1 [xlabel="0"]
    q1 -> q3 [label=" 0"]
    q3:se -> q3:e [label=" 0,1"]
    q2 -> q0 [xlabel="0 "]
    q0 -> q2 [xlabel="1 "]
    q2 -> q3 [label="1"]

    {rank=same; Start; q0; q1}
    {rank=same; q2; q3}
}

Source answer


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接