グラフとかを出力する方法いろいろ
グラフ理論の意味でのグラフを出力する/できるツールたちの紹介。
グラフを並べて観察したい -> ちょうどtexでグラフ書いてたところだったのでlatex+xypicをsystem(3)から使う $\to$ 1000個単位でpngを生成するには遅すぎて色々探す、などした結果のまとめ。
グラフをひとつ固定してその部分グラフばかり考えていたので、(自動レイアウトだと目的からずれるため)わりと汎用的。競技プログラミングで幾何の問題解いてる時にも使えそう。
graphviz
DOT言語で表現されたグラフをpngやsvgとして描画してくれる。 もちろん自動でレイアウトしてくれる。 知る限り最も汎用的なツール。
逆に、頂点座標を指定するなどは基本的にできない。 レイアウトに不満があるならsvgで出力してinkscape等で修正すると良いようだ。
DOT言語の例
graph graphname {
    a -- b -- c;
    b -- d;
}
digraph graphname {
    a -> z;
    b -> z;
    c -> z;
    z -> a;
}
graph graphname {
    a -- b -- c -- d -- e -- f -- a;
    a -- c -- e -- a;
    b -- d -- f -- b;
    a -- d;
    b -- e;
    c -- f;
}
- dot 
- twopi 
- circo 
使用
たいていはコマンドから。dot neato twopi circo … といったレイアウトに対応した名前のコマンドを叩く。
$ dot -T svg foo.dot > foo.svg
$ neato -T svg foo.dot > foo.svg
$ circo -T svg foo.dot > foo.svg
c言語のライブラリとしても呼びだせる。
#include <graphviz/gvc.h>
int main(void) {
    GVC_t *gvc = gvContext();
    graph_t *g = agread(stdin, 0);
    gvLayout(gvc, g, "dot");
    gvRender(gvc, g, "svg", stdout);
    gvFreeLayout(gvc, g);
    agclose(g);
    gvFreeContext(gvc);
    return 0;
}
$ cc -l gvc -l cgraph a.c
$ ./a.out < foo.dot > foo.svg
参考
latex + tikz
手で直接書く場合や、数式を放り込みたい場合、座標を指定したい場合に。
グラフ特化ではなくてもう少し汎用的な道具。ちょっと遅い。
\draw (0,0) grid (42,42);が便利。
xypic含め可換図式とかも書ける。
$ pdflatex -shell-escape foo.tex #=> foo.pdf & foo.png
$ pdf2svg foo.pdf foo.svg # optional
\documentclass[png]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}[every node/.style={circle,draw}]
    \node (A) at (14, 4) {};
    \node (B) at ( 7, 0) {};
    \node (C) at ( 0, 4) {};
    \node (D) at ( 0,12) {};
    \node (E) at ( 7,16) {};
    \node (F) at (14,12) {};
    \foreach \u \v in {A/B,A/C,A/D,A/E,A/F,B/C,B/D,B/E,B/F,C/D,C/E,C/F,D/E,D/F,E/F}
        \draw (\u) -- (\v);
\end{tikzpicture}
\end{document}
参考
- TikZ 覚書
- http://www.opt.mist.i.u-tokyo.ac.jp/~tasuku/tikz.html
- http://tex.stackexchange.com/questions/121638/tex-figure-to-png
latex + xypic
tikzと似たもの。しかしtikzのほうがよいらしいと聞く。
\documentclass[png]{standalone}
\usepackage[all]{xy}
\begin{document}
\begin{xy}
    (14, 4)*{\circ}="A",
    ( 7, 0)*{\circ}="B",
    ( 0, 4)*{\circ}="C",
    ( 0,12)*{\circ}="D",
    ( 7,16)*{\circ}="E",
    (14,12)*{\circ}="F",
    { "A" \ar @{-} "B" },
    { "A" \ar @{-} "C" },
    { "A" \ar @{-} "D" },
    { "A" \ar @{-} "E" },
    { "A" \ar @{-} "F" },
    { "B" \ar @{-} "C" },
    { "B" \ar @{-} "D" },
    { "B" \ar @{-} "E" },
    { "B" \ar @{-} "F" },
    { "C" \ar @{-} "D" },
    { "C" \ar @{-} "E" },
    { "C" \ar @{-} "F" },
    { "D" \ar @{-} "E" },
    { "D" \ar @{-} "F" },
    { "E" \ar @{-} "F" },
\end{xy}
\end{document}
参考
.svg 直出力
直接書くのも難しくない。特に速度と容量の面で有利。でも多少の使い難さはある。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     width="160" height="180">
    <g transform="translate(10,10) scale(10,10)" fill="none" stroke="black" stroke-width="0.1">
        <path d="M 14  4 L  7  0" />
        <path d="M 14  4 L  0  4" />
        <path d="M 14  4 L  0 12" />
        <path d="M 14  4 L  7 16" />
        <path d="M 14  4 L 14 12" />
        <path d="M  7  0 L  0  4" />
        <path d="M  7  0 L  0 12" />
        <path d="M  7  0 L  7 16" />
        <path d="M  7  0 L 14 12" />
        <path d="M  0  4 L  0 12" />
        <path d="M  0  4 L  7 16" />
        <path d="M  0  4 L 14 12" />
        <path d="M  0 12 L  7 16" />
        <path d="M  0 12 L 14 12" />
        <path d="M  7 16 L 14 12" />
    </g>
</svg>
他
他に調べたり検討したりしたやつ。