(1時間4,000円の伴走型ビデオチャット指導も受付中!)
Pythonで描くデータの地図:Graphvizではじめる可視化入門
![]()
【Yuki】
Hirokiくん、こんにちは。今日は、複雑なデータや物事のつながりを、「図」として美しく描き出す方法についてお話ししようと思います……。プログラミングをしていると、関数の呼び出し関係やデータの構造など、頭の中だけでは整理しきれないことが出てきますよね。
![]()
【Hiroki】
Yukiさん、こんにちは!はい、まさにそうです。コードが長くなってくると、どこがどう繋がっているのか分からなくなることがあります。図に描ければいいなと思うんですけど、手書きだと修正が大変で……。
![]()
【Yuki】
そうですよね。そこで役に立つのが、Graphviz(グラフビズ)というツールです。これは「DOT言語」というテキスト形式のデータを読み込んで、自動的にきれいなグラフや図を作成してくれるソフトウェアなんです。PythonにはこのGraphvizを簡単に扱えるライブラリがあって、コードを書くだけで複雑な図が生成できるんですよ。
![]()
【Hiroki】
コードで図が描けるんですか?それは便利そうですね。でも、設定とかが難しそうなイメージがあります。
![]()
【Yuki】
少しだけ準備が必要ですが、一度環境を整えてしまえば、あとはとてもシンプルだと思います……。今日は、その準備から基本的な使い方まで、ゆっくり一緒に見ていきましょう。
Graphvizを使うための準備
![]()
【Yuki】
まず、GraphvizをPythonで使うには、2つのステップが必要です。1つ目はGraphviz本体(ソフトウェア)のインストール、2つ目はPython用のライブラリのインストールです。
![]()
【Hiroki】
本体とライブラリ、両方が必要なんですね。
![]()
【Yuki】
そうなんです。Pythonのライブラリだけでは図を描画する「エンジン」が含まれていないので、本体が必要になります。Windowsなら公式サイトやパッケージマネージャーから、MacならHomebrewなどでインストールできます。本体を入れたら、次はPython側で以下のコマンドを実行します。
pip install graphviz
![]()
【Hiroki】
なるほど。本体をインストールして、パス(環境変数)を通しておくのがポイントですね。準備ができたら、どうやって使い始めるんですか?
最初のグラフを描いてみる
![]()
【Yuki】
まずは、一番シンプルな「有向グラフ」を描いてみましょう。有向グラフというのは、矢印で方向が示されたグラフのことです。以下のコードを見てみてください。
from graphviz import Digraph
# インスタンスの作成
dot = Digraph(comment='はじめてのグラフ')
# ノード(点)の追加
dot.node('A', 'Python')
dot.node('B', 'Graphviz')
dot.node('C', '可視化成功!')
# エッジ(線)の追加
dot.edge('A', 'B')
dot.edge('B', 'C')
# 保存と表示
dot.render('test-output/first_graph', format='png', cleanup=True)
print("グラフを出力しました。")
![]()
【Hiroki】
わあ、意外と短いコードですね。nodeが要素で、edgeがその繋がりを指しているのが直感的にわかります。
![]()
【Yuki】
そうですね。Digraphは「Directed Graph」の略で、矢印のあるグラフを作るときに使います。逆に、矢印のない繋がりを描きたいときは、Graphクラスを使います。dot.renderの引数でformat='png'と指定すれば画像として保存されますし、PDFなどにも対応しているんですよ。
![]()
【Hiroki】
cleanup=Trueというのは何ですか?
![]()
【Yuki】
それは、描画の過程で生成される一時的な中間ファイル(.gvファイル)を、画像生成後に自動で削除してくれる設定です。フォルダが散らからないので、入れておくといいかもしれません……。
見た目を自分好みにカスタマイズする
![]()
【Yuki】
ただ図を描くだけでなく、色をつけたり形を変えたりすることもできます。「属性(Attributes)」を設定することで、図の印象はずいぶんと変わります。わたしも、少しでも見やすくなるようにフォントや色を調整するのが好きなんです。
![]()
【Hiroki】
色が変わると、重要な部分が目立って分かりやすくなりそうですね。どうやって設定するんですか?
![]()
【Yuki】
個別のノードに設定することもできますし、グラフ全体にまとめて設定することもできます。例えば、こんな感じです。
from graphviz import Digraph
dot = Digraph()
# 全体の属性設定
dot.attr(rankdir='LR') # グラフの向きを左から右にする
dot.attr('node', shape='box', style='filled', color='lightblue', fontname='MS Gothic')
# ノードの追加
dot.node('start', '開始', shape='ellipse', color='pink')
dot.node('process', '処理中')
dot.node('end', '終了', shape='doublecircle')
# エッジの追加
dot.edge('start', 'process', label='実行')
dot.edge('process', 'end', label='完了')
dot.render('test-output/styled_graph', format='png', cleanup=True)
![]()
【Hiroki】
rankdir='LR'とすると、横方向の図になるんですね。デフォルトだと上から下でしたっけ?
![]()
【Yuki】
はい、デフォルトは上から下(TB: Top to Bottom)です。左から右(LR: Left to Right)にすると、フローチャートなどは読みやすくなることが多いと思います……。また、nodeという名前に対して属性を設定すると、それ以降に追加される全てのノードにそのデザインが適用されるので、統一感を出すのに便利ですよ。
![]()
【Hiroki】
fontnameでフォントも指定できるんですね。日本語を使うときは、日本語対応のフォントを指定しないと文字化けしてしまうことがあるので、注意が必要ですね。
![]()
【Yuki】
その通りです。よく気が付きましたね、Hirokiくん。Windowsなら「MS Gothic」や「Yu Gothic」、Macなら「Hiragino Kaku Gothic ProN」などを指定するのが一般的です。
複雑な構造をまとめる「サブグラフ」
![]()
【Hiroki】
もっと複雑な、例えば「チームA」と「チームB」の中での繋がり、みたいなものを表現することはできますか?
![]()
【Yuki】
もちろんです。「サブグラフ(Subgraph)」や「クラスター(Cluster)」という機能を使えば、特定のグループを枠で囲むことができます。これを使うと、情報の整理がぐっと楽になるはずです。
from graphviz import Digraph
dot = Digraph()
# チームAのクラスター
with dot.subgraph(name='cluster_0') as c:
c.attr(style='filled', color='lightgrey')
c.node_attr.update(style='filled', color='white')
c.edges([('A1', 'A2'), ('A2', 'A3')])
c.attr(label='チームA')
# チームBのクラスター
with dot.subgraph(name='cluster_1') as c:
c.attr(color='blue')
c.node_attr.update(style='filled', color='lightcyan')
c.edges([('B1', 'B2'), ('B2', 'B3')])
c.attr(label='チームB')
# チーム間の繋がり
dot.edge('A3', 'B1')
dot.render('test-output/subgraph_sample', format='png', cleanup=True)
![]()
【Hiroki】
なるほど、with dot.subgraphの中で定義するんですね。クラスターにするときは、名前の先頭に cluster_ と付けるのがルールなんですか?
![]()
【Yuki】
はい、よく知っていますね……!Graphvizの仕様で、名前が cluster で始まるサブグラフだけが、四角い枠で囲まれる仕組みになっているんです。これを知らないと、「枠が表示されないな……」と悩んでしまう原因になるので、覚えておくといいかもしれません。
実践:条件分岐を描いてみる
![]()
【Hiroki】
だんだん使い方が分かってきました。これを応用して、プログラムの条件分岐(if文)みたいなものを図にすることはできますか?
![]()
【Yuki】
いいアイディアですね。実際に簡単な「今日の行動決定フロー」を作ってみましょうか。最新のAI技術の解説でも、推論のステップを説明するのにこうした図がよく使われます。
from graphviz import Digraph
def create_decision_tree():
d = Digraph(format='png')
d.attr(fontname='MS Gothic')
d.node_attr.update(fontname='MS Gothic')
d.edge_attr.update(fontname='MS Gothic')
# ノード定義
d.node('start', '外を見る', shape='invhouse')
d.node('q1', '雨は降っている?', shape='diamond')
d.node('q2', '気温は低い?', shape='diamond')
d.node('action1', '傘を持って出かける', shape='box')
d.node('action2', 'コートを着て出かける', shape='box')
d.node('action3', '軽装で出かける', shape='box')
# エッジ定義
d.edge('start', 'q1')
d.edge('q1', 'action1', label='Yes')
d.edge('q1', 'q2', label='No')
d.edge('q2', 'action2', label='Yes')
d.edge('q2', 'action3', label='No')
return d
# 実行
tree = create_decision_tree()
tree.render('test-output/decision_flow', cleanup=True)
![]()
【Hiroki】
ひし形のノードが「条件分岐」っぽくてかっこいいです!こうしてコードに落とし込むと、ロジックのミスにも気づきやすそうですね。
![]()
【Yuki】
そうですね。誰かの役に立つために作られた小さなスクリプトやツールは、こうして可視化されることで、より多くの人に理解してもらえるようになると思うんです……。わたしも、自分の考えを整理するときによくGraphvizを使います。
高度なレイアウトエンジンについて
![]()
【Hiroki】
ちなみに、ノードがすごく増えたとき、重なったりして見づらくなることはないんですか?
![]()
【Yuki】
鋭い質問ですね。Graphvizには複数の「レイアウトエンジン」が用意されていて、用途に合わせて切り替えることができます。
- dot: 階層的なグラフ(フローチャートなど)に最適。
- neato: 「バネモデル」を用いた配置。無向グラフに強い。
- fdp: neatoに似ていますが、大きなグラフに向いています。
- twopi: 放射状のレイアウト。
- circo: 円状のレイアウト。
デフォルトは dot ですが、例えば dot = Digraph(engine='neato') のように指定することで、配置のアルゴリズムを変更できるんですよ。
![]()
【Hiroki】
へぇ、用途によってエンジンを使い分けるんですね。ネットワーク構成図とかなら neato や circo が面白そうです。
まとめとアドバイス
![]()
【Yuki】
今日はPythonからGraphvizを使って、図を生成する方法を学びました。最後に、ポイントを整理しておきますね。
- 本体のインストールを忘れずに: Pythonライブラリだけでは動きません。
- ノードとエッジ:
node()で点を作り、edge()で線を引きます。 - 属性で装飾:
shapeやcolorで見栄えを整えましょう。 - サブグラフ:
cluster_から始まる名前でグループ化できます。 - 日本語フォント:
fontnameを適切に設定しましょう。
![]()
【Hiroki】
ありがとうございます、Yukiさん!今まで手書きで苦労していたのが嘘みたいに楽になりそうです。
![]()
【Yuki】
喜んでもらえてよかったです……。もし、もっと詳しく知りたくなったら、公式サイトのドキュメントを見てみてください。英語ですが、属性のリストなどが詳しく載っています。
User Guide — graphviz 0.20.1 documentation
![]()
【Hiroki】
読んでみます!これを使って、今作っているプログラムの構造図を書いてみますね。
![]()
【Yuki】
ええ、ぜひ挑戦してみてください。きっと、今まで見えていなかった新しい発見があると思います……。もし詰まってしまったら、いつでも聞いてくださいね。夜は比較的起きているので、力になれるはずですから。
![]()
【Hiroki】
はい!また教えてください。
![]()
【Yuki】
……ふふ、頑張ってくださいね。応援しています。
参考資料 - Graphviz 公式サイト - Python-graphviz GitHub リポジトリ - Graphviz 属性リファレンス
「Graphviz」のサンプルコードを見る
この記事では基礎を解説しましたが、実務においては「もっと複雑なデータを扱いたい」「独自のシステムに組み込みたい」といった、個別の課題に直面することも多いはずです。
「自分で書く時間は最小限に抑え、プロの品質でツールを完成させたい」という方は、ぜひ一度ご相談ください。
- 専門家の知見に基づいた、保守性の高いコード設計
- AIの専門家による、Gemini API等の最新AIを組み合わせた高度な自動化
- ChatGPT等が生成したコードのデバッグ・最適化
「教わる」だけでなく「形にする」パートナーとして、フリーランスエンジニアのmei_13が最短ルートでの解決をサポートします。
初心者から始められるPythonレッスン
● 月額4,000円で質問し放題!!
● 完全オンライン
● 翌日までには必ず返信
● 挫折しない独自の学習メソッド
● 圧倒的高評価!!
● テキストベースで時間を選ばない
● 4,000円/60分の伴走型ビデオチャット指導も可能
● 高品質なサンプルコード
詳細はこちら

