scientific-schematics について
scientific-schematics は、論文、ポスター、技術文書向けの科学図を作成するスキルです。図の種類に応じた Python ライブラリを提案し、ベクター形式での出力、品質確認、文書への組み込みを案内します。
主な機能
- 01ニューラルネットワークやシステム図の作成
- 02フローチャート・回路図・生物経路の描画
- 03図の種類に応じたライブラリ選択
- 04SVG・PDF・EPS での出力
- 05アクセシビリティと出版基準の案内
活用シーン
- 01論文用モデル構成図の作成
- 02研究ワークフロー図の描画
- 03回路図や生物経路図の作成
- 04LaTeX 文書での図の参照
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jimmc414/ kosmos --skill scientific-schematicsインストール後、Claude Code で/scientific-schematicsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/block_diagram_template.texcircuit_template.texflowchart_template.texpathway_template.textikz_styles.texreferences/best_practices.mddiagram_types.mdpython_libraries.mdtikz_guide.mdscripts/circuit_generator.pycompile_tikz.pygenerate_flowchart.pypathway_diagram.py詳細
科学的な模式図と図表
概要
科学的な模式図や図表は、複雑な概念を論文掲載に適した明快な視覚表現へと変換します。最先端のPythonライブラリを使用して、ニューラルネットワークのアーキテクチャ、フローチャート、回路図、生物学的経路、システム図を生成します。すべての図はSVG/EPSファイルとして作成され、figures/サブフォルダーに保存され、論文やポスターから参照されます。LaTeXに直接埋め込むことはありません。
ゼロショット図表生成ワークフロー
すべての図表で使用する標準的なワークフロー:
- 要件を分析する - 図表の種類と構成要素を特定します
- 最適なライブラリを選ぶ - 図表の種類に適した最良のツールを選択します
- ベクター画像を生成する - 適切な間隔とレイアウトでSVG/EPSを作成します
- figures/に保存する - 説明的な名前を付けて
figures/サブフォルダーに保存します - 品質を確認する - 重なりがないこと、コントラストが良好であること、解像度が適切であることを確認します
- ドキュメントから参照する - LaTeXで
\includegraphics{figures/diagram_name.pdf}を使用します
重要な原則: まず独立したベクター画像を生成し、その後ドキュメントに組み込みます。
このスキルを使用する場面
このスキルは、次のような場合に使用します。
- ニューラルネットワークのアーキテクチャ図(Transformer、CNN、RNNなど)を作成する
- システムアーキテクチャ図やデータフロー図を示す
- 研究デザインの方法論を示すフローチャート(CONSORT、PRISMA)を描く
- アルゴリズムのワークフローや処理パイプラインを視覚化する
- 回路図や電気回路の模式図を作成する
- 生物学的経路や分子間相互作用を描写する
- ネットワークトポロジーや階層構造を生成する
- 概念的なフレームワークや理論モデルを図示する
- 技術論文向けのブロック図を作成する
図表の種類別おすすめライブラリ
図表の種類に適した最適なライブラリを選びます。
ニューラルネットワークのアーキテクチャ(Transformer、CNNなど)
おすすめのライブラリ: Pythonのpygraphvizまたはpydot経由で使用するgraphviz
- 優れた自動レイアウトアルゴリズム
- すっきりとしたプロフェッショナルな外観
- 層の積み重ねや接続の表現に最適
- 複雑な交差接続も適切に処理
代替案: 位置を慎重に調整したカスタムmatplotlib
- 配置を正確に制御できます
- 高度にカスタマイズされたデザインに適しています
- 手動での位置調整が多く必要です
フローチャートとプロセス図
おすすめのライブラリ: dotまたはflowchartレイアウトを使用するgraphviz
- 最適な位置を自動で設定
- 標準的なフローチャートの図形
- すっきりとした矢印の配置
- 重なりの問題を最小限に抑制
代替案: diagramsライブラリ(クラウド/システムアーキテクチャ形式向け)
回路図
おすすめのライブラリ: schemdraw
- 電気回路に特化
- 豊富なコンポーネントライブラリ
- 配線を自動で配置
- プロフェッショナルなエンジニアリング標準の出力
生物学的経路
おすすめのライブラリ: カスタムレンダリングを使用するnetworkx
- グラフベースの経路表現
- アルゴリズムによるレイアウト
- ノードとエッジのスタイルを柔軟に設定
ブロック図とシステムアーキテクチャ
おすすめのライブラリ: graphvizまたはdiagrams
- すっきりとした階層レイアウト
- 間隔を自動調整
- プロフェッショナルな外観
よく使われる図表のゼロショット作成例
例1:Transformerアーキテクチャ(ニューラルネットワーク)
「Attention Is All You Need」のようなTransformerエンコーダー・デコーダー図を作成します。
import graphviz
from pathlib import Path
def create_transformer_diagram(output_dir='figures'):
"""
Create a Transformer architecture diagram.
Zero-shot generation with automatic layout.
"""
Path(output_dir).mkdir(exist_ok=True)
# Create directed graph with TB (top-to-bottom) layout
dot = graphviz.Digraph(
'transformer',
format='pdf',
graph_attr={
'rankdir': 'BT', # Bottom to top (like the original paper)
'splines': 'ortho', # Orthogonal edges
'nodesep': '0.5',
'ranksep': '0.8',
'bgcolor': 'white',
'dpi': '300'
},
node_attr={
'shape': 'box',
'style': 'rounded,filled',
'fillcolor': 'lightgray',
'fontname': 'Arial',
'fontsize': '11',
'width': '2.5',
'height': '0.5'
},
edge_attr={
'color': 'black',
'penwidth': '1.5'
}
)
# ENCODER STACK (left side)
with dot.subgraph(name='cluster_encoder') as enc:
enc.attr(label='Encoder', fontsize='14', fontname='Arial-Bold')
enc.attr(style='rounded', color='blue', penwidth='2')
# Encoder layers (bottom to top)
enc.node('enc_input_emb', 'Input Embedding', fillcolor='#E8F4F8')
enc.node('enc_pos', 'Positional Encoding', fillcolor='#E8F4F8')
enc.node('enc_mha', 'Multi-Head\nAttention', fillcolor='#B3D9E6')
enc.node('enc_an1', 'Add & Norm', fillcolor='#CCE5FF')
enc.node('enc_ff', 'Feed Forward', fillcolor='#B3D9E6')
enc.node('enc_an2', 'Add & Norm', fillcolor='#CCE5FF')
# Encoder flow
enc.edge('enc_input_emb', 'enc_pos')
enc.edge('enc_pos', 'enc_mha')
enc.edge('enc_mha', 'enc_an1')
enc.edge('enc_an1', 'enc_ff')
enc.edge('enc_ff', 'enc_an2')
# DECODER STACK (right side)
with dot.subgraph(name='cluster_decoder') as dec:
dec.attr(label='Decoder', fontsize='14', fontname='Arial-Bold')
dec.attr(style='rounded', color='red', penwidth='2')
# Decoder layers (bottom to top)
dec.node('dec_output_emb', 'Output Embedding', fillcolor='#FFE8E8')
dec.node('dec_pos', 'Positional Encoding', fillcolor='#FFE8E8')
dec.node('dec_mmha', 'Masked Self-\nAttention', fillcolor='#FFB3B3')
dec.node('dec_an1', 'Add & Norm', fillcolor='#FFCCCC')
dec.node('dec_cross', 'Cross-Attention', fillcolor='#FFB3B3')
dec.node('dec_an2', 'Add & Norm', fillcolor='#FFCCCC')
dec.node('dec_ff', 'Feed Forward', fillcolor='#FFB3B3')
dec.node('dec_an3', 'Add & Norm', fillcolor='#FFCCCC')
dec.node('dec_linear', 'Linear & Softmax', fillcolor='#FF9999')
dec.node('dec_output', 'Output\nProbabilities', fillcolor='#FFE8E8')
# Decoder flow
dec.edge('dec_output_emb', 'dec_pos')
dec.edge('dec_pos', 'dec_mmha')
dec.edge('dec_mmha', 'dec_an1')
dec.edge('dec_an1', 'dec_cross')
dec.edge('dec_cross', 'dec_an2')
dec.edge('dec_an2', 'dec_ff')
dec.edge('dec_ff', 'dec_an3')
dec.edge('dec_an3', 'dec_linear')
dec.edge('dec_linear', 'dec_output')
# Cross-attention connection (encoder to decoder)
dot.edge('enc_an2', 'dec_cross',
style='dashed',
color='purple',
label=' context ',
fontsize='9')
# Input and output labels
dot.node('input_seq', 'Input Sequence',
shape='ellipse', fillcolor='lightgreen')
dot.node('target_seq', 'Target Sequence',
shape='ellipse', fillcolor='lightgreen')
dot.edge('input_seq', 'enc_input_emb')
dot.edge('target_seq', 'dec_output_emb')
# Render to files
output_path = f'{output_dir}/transformer_architecture'
dot.render(output_path, cleanup=True)
# Also save as SVG and EPS
dot.format = 'svg'
dot.render(output_path, cleanup=True)
dot.format = 'eps'
dot.render(output_path, cleanup=True)
print(f"✓ Transformer diagram created:")
print(f" - {output_path}.pdf")
print(f" - {output_path}.svg")
print(f" - {output_path}.eps")
return f"{output_path}.pdf"
# Usage
if __name__ == '__main__':
diagram_path = create_transformer_diagram('figures')
# Run quality checks
from quality_checker import run_quality_checks
run_quality_checks(diagram_path.replace('.pdf', '.png'))
LaTeXへの組み込み:
\begin{figure}[htbp]
\centering
\includegraphics[width=0.9\textwidth]{figures/transformer_architecture.pdf}
\caption{Transformer encoder-decoder architecture showing multi-head attention,
feed-forward layers, and cross-attention mechanism.}
\label{fig:transformer}
\end{figure}
例2:シンプルなフローチャート(CONSORT形式)
import graphviz
from pathlib import Path
def create_consort_flowchart(output_dir='figures'):
"""Create a CONSORT participant flow diagram."""
Path(output_dir).mkdir(exist_ok=True)
dot = graphviz.Digraph(
'consort',
format='pdf',
graph_attr={
'rankdir': 'TB',
'splines': 'ortho',
'nodesep': '0.6',
'ranksep': '0.8',
'bgcolor': 'white'
},
node_attr={
'shape': 'box',
'style': 'rounded,filled',
'fillcolor': '#E8F4F8',
'fontname': 'Arial',
'fontsize': '10',
'width': '3',
'height': '0.6'
}
)
# Enrollment
dot.node('assessed', 'Assessed for eligibility\n(n=500)')
dot.node('excluded', 'Excluded (n=150)\n• Age < 18: n=80\n• Declined: n=50\n• Other: n=20')
dot.node('randomized', 'Randomized\n(n=350)')
# Allocation
dot.node('treatment', 'Allocated to treatment\n(n=175)', fillcolor='#C8E6C9')
dot.node('control', 'Allocated to control\n(n=175)', fillcolor='#FFECB3')
# Follow-up
dot.node('treat_lost', 'Lost to follow-up (n=15)', fillcolor='#FFCDD2')
dot.node('ctrl_lost', 'Lost to follow-up (n=10)', fillcolor='#FFCDD2')
# Analysis
dot.node('treat_analyzed', 'Analyzed (n=160)', fillcolor='#C8E6C9')
dot.node('ctrl_analyzed', 'Analyzed (n=165)', fillcolor='#FFECB3')
# Connect nodes
dot.edge('assessed', 'excluded')
dot.edge('assessed', 'randomized')
dot.edge('randomized', 'treatment')
dot.edge('randomized', 'control')
dot.edge('treatment', 'treat_lost')
dot.edge('treatment', 'treat_analyzed')
dot.edge('control', 'ctrl_lost')
dot.edge('control', 'ctrl_analyzed')
# Render
output_path = f'{output_dir}/consort_flowchart'
dot.render(output_path, cleanup=True)
print(f"✓ CONSORT flowchart created: {output_path}.pdf")
return f"{output_path}.pdf"
例3:CNNアーキテクチャ
def create_cnn_architecture(output_dir='figures'):
"""Create a CNN architecture diagram."""
dot = graphviz.Digraph(
'cnn',
format='pdf',
graph_attr={'rankdir': 'LR', 'bgcolor': 'white'}
)
# Define layers
layers = [
('input', 'Input\n32×32×3', '#FFE8E8'),
('conv1', 'Conv 3×3\n32 filters', '#B3D9E6'),
('pool1', 'MaxPool\n2×2', '#FFE5B3'),
('conv2', 'Conv 3×3\n64 filters', '#B3D9E6'),
('pool2', 'MaxPool\n2×2', '#FFE5B3'),
('flatten', 'Flatten', '#D4E8D4'),
('fc1', 'FC 128', '#C8B3E6'),
('fc2', 'FC 10', '#C8B3E6'),
('softmax', 'Softmax', '#FFC8C8')
]
# Create nodes
for node_id, label, color in layers:
dot.node(node_id, label,
shape='box', style='rounded,filled',
fillcolor=color, fontname='Arial')
# Connect layers
for i in range(len(layers) - 1):
dot.edge(layers[i][0], layers[i+1][0])
output_path = f'{output_dir}/cnn_architecture'
dot.render(output_path, cleanup=True)
print(f"✓ CNN diagram created: {output_path}.pdf")
return f"{output_path}.pdf"
主な機能
1. 対応する図の種類
ニューラルネットワークアーキテクチャ
- Transformer エンコーダー・デコーダーモデル
- 畳み込みニューラルネットワーク(CNN)
- リカレントネットワーク(LSTM、GRU)
- アテンション機構とその派生形
- カスタム深層学習アーキテクチャ
方法論のフローチャート
- CONSORT 参加者フロー図
- PRISMA システマティックレビューのフロー図
- データ処理パイプライン
- アルゴリズムのワークフロー
- 被験者登録フロー
回路図
- アナログおよびデジタル電子回路
- 信号処理ブロック図
- 制御システム図
生物学的な図
- シグナル伝達経路
- 代謝経路図
- 遺伝子制御ネットワーク
- タンパク質相互作用ネットワーク
システムアーキテクチャ図
- ソフトウェアアーキテクチャとコンポーネント
- データフロー図
- ネットワークトポロジー図
- 階層型組織図
必要なライブラリとインストール
主なライブラリ:Graphviz(図の90%に推奨)
Graphviz は、自動レイアウト、きれいな描画、重なりが発生しないことから、ほとんどの科学図に最適なツールです。
インストール:
# Install Graphviz binary (required)
# macOS
brew install graphviz
# Ubuntu/Debian
sudo apt-get install graphviz
# Install Python bindings
pip install graphviz
Graphviz が最適な理由:
- ✓ 最適なレイアウトを自動生成(手動での配置は不要)
- ✓ レイアウトアルゴリズムによって重なりを確実に防止
- ✓ そのまま使えるプロフェッショナルな外観
- ✓ 複雑な階層や相互接続に対応
- ✓ SVG、PDF、EPS 形式でのネイティブ出力
- ✓ 最小限のコードで最高品質を実現
特化型ライブラリ
Schemdraw - 回路図専用
pip install schemdraw
NetworkX - 複雑なネットワークの分析と可視化
pip install networkx matplotlib
Matplotlib - カスタムの手動図(正確な制御が必要な場合)
pip install matplotlib
ゼロショットで図を作成するクイックスタートガイド
どの種類の図でも、次の手順に沿って体系的に進めてください。
手順 1:図の構造を特定する
次の点を確認してください。
- 階層構造ですか? →
rankdir='TB'または'BT'(上から下、または下から上)を使います - 順序のある流れですか? →
rankdir='LR'(左から右)を使います - 並列分岐がありますか? → サブグラフ/クラスターを使います
- 相互接続がありますか? → Graphviz が自動的に処理します
手順 2:基本テンプレートを設定する
次のテンプレートを使い、必要に応じてカスタマイズしてください。
import graphviz
from pathlib import Path
def create_diagram(output_dir='figures', diagram_name='my_diagram'):
"""Universal diagram creation template."""
Path(output_dir).mkdir(exist_ok=True, parents=True)
dot = graphviz.Digraph(
name=diagram_name,
format='pdf',
graph_attr={
'rankdir': 'TB', # TB, BT, LR, or RL
'splines': 'ortho', # ortho (straight) or curved
'nodesep': '0.6', # horizontal spacing
'ranksep': '0.8', # vertical spacing
'bgcolor': 'white',
'dpi': '300'
},
node_attr={
'shape': 'box', # box, ellipse, diamond, etc.
'style': 'rounded,filled',
'fillcolor': 'lightgray',
'fontname': 'Arial',
'fontsize': '11',
'margin': '0.2',
'width': '2', # minimum width
'height': '0.5' # minimum height
},
edge_attr={
'color': 'black',
'penwidth': '1.5',
'arrowsize': '0.8'
}
)
# Add your nodes and edges here
dot.node('node1', 'Label 1')
dot.node('node2', 'Label 2')
dot.edge('node1', 'node2')
# Render to multiple formats
output_path = f'{output_dir}/{diagram_name}'
dot.render(output_path, cleanup=True) # PDF
dot.format = 'svg'
dot.render(output_path, cleanup=True) # SVG
dot.format = 'eps'
dot.render(output_path, cleanup=True) # EPS
print(f"✓ Diagram saved: {output_path}.{{pdf,svg,eps}}")
return f"{output_path}.pdf"
手順 3:分かりやすいラベルを付けてノードを追加する
ベストプラクティス:
- 説明的なノード ID を使います。
'n1'ではなく'encoder_layer1'のようにします - 複数行のラベルには
\nを使います - 関連するコンポーネントをグループ化するには塗りつぶし色を使います
- ラベルは簡潔にします(1 行あたり最大 3~5 語)
# Good node definitions
dot.node('input_layer', 'Input Layer\n(512 dims)', fillcolor='#E8F4F8')
dot.node('attention', 'Multi-Head\nAttention', fillcolor='#B3D9E6')
dot.node('output', 'Output', fillcolor='#C8E6C9')
手順 4:エッジでノードを接続する
エッジの種類:
# Standard arrow
dot.edge('node1', 'node2')
# Dashed line (for information flow)
dot.edge('encoder', 'decoder', style='dashed')
# Bidirectional
dot.edge('node1', 'node2', dir='both')
# With label
dot.edge('layer1', 'layer2', label=' ReLU ')
# Different color
dot.edge('input', 'output', color='red', penwidth='2')
手順 5:グループ化にサブグラフを使う
並列構造(Encoder/Decoder など)の場合:
# Encoder cluster
with dot.subgraph(name='cluster_encoder') as enc:
enc.attr(label='Encoder', style='rounded', color='blue')
enc.node('enc1', 'Encoder Layer 1')
enc.node('enc2', 'Encoder Layer 2')
enc.edge('enc1', 'enc2')
# Decoder cluster
with dot.subgraph(name='cluster_decoder') as dec:
dec.attr(label='Decoder', style='rounded', color='red')
dec.node('dec1', 'Decoder Layer 1')
dec.node('dec2', 'Decoder Layer 2')
dec.edge('dec1', 'dec2')
# Cross-connection between clusters
dot.edge('enc2', 'dec1', style='dashed', color='purple')
手順 6:レンダリングして確認する
# Always render to PDF (for LaTeX) and SVG (for web/slides)
output_path = f'{output_dir}/{diagram_name}'
# PDF for papers
dot.format = 'pdf'
dot.render(output_path, cleanup=True)
# SVG for posters/slides
dot.format = 'svg'
dot.render(output_path, cleanup=True)
# EPS for some journals
dot.format = 'eps'
dot.render(output_path, cleanup=True)
Graphviz の主な属性クイックリファレンス
グラフ属性(全体のレイアウト)
graph_attr={
'rankdir': 'TB', # Direction: TB, BT, LR, RL
'splines': 'ortho', # Edge style: ortho, curved, line, polyline
'nodesep': '0.5', # Space between nodes (inches)
'ranksep': '0.8', # Space between ranks (inches)
'bgcolor': 'white', # Background color
'dpi': '300', # Resolution for raster output
'compound': 'true', # Allow edges between clusters
'concentrate': 'true' # Merge multiple edges
}
ノード属性(ボックス/形状)
node_attr={
'shape': 'box', # box, ellipse, circle, diamond, plaintext
'style': 'rounded,filled', # rounded, filled, dashed, bold
'fillcolor': '#E8F4F8', # Fill color (hex or name)
'color': 'black', # Border color
'penwidth': '1.5', # Border width
'fontname': 'Arial', # Font family
'fontsize': '11', # Font size (points)
'fontcolor': 'black', # Text color
'width': '2', # Minimum width (inches)
'height': '0.5', # Minimum height (inches)
'margin': '0.2' # Internal padding
}
エッジ属性(矢印/接続)
edge_attr={
'color': 'black', # Line color
'penwidth': '1.5', # Line width
'style': 'solid', # solid, dashed, dotted, bold
'arrowsize': '1.0', # Arrow head size
'dir': 'forward', # forward, back, both, none
'arrowhead': 'normal' # normal, vee, diamond, dot, none
}
色覚多様性に配慮したパレット
アクセシビリティを確保するには、次の色セットを使ってください。
Okabe-Ito パレット(8 色)
OKABE_ITO = {
'orange': '#E69F00',
'sky_blue': '#56B4E9',
'green': '#009E73',
'yellow': '#F0E442',
'blue': '#0072B2',
'vermillion': '#D55E00',
'purple': '#CC79A7',
'black': '#000000'
}
明るい背景(塗りつぶしノード用)
LIGHT_FILLS = {
'blue': '#E8F4F8',
'green': '#E8F5E9',
'orange': '#FFF3E0',
'purple': '#F3E5F5',
'red': '#FFEBEE',
'yellow': '#FFFDE7',
'gray': '#F5F5F5'
}
4. 論文出版の基準
すべての図は、科学論文の出版におけるベストプラクティスに従います。
ベクター形式での出力
- LaTeX への組み込みには PDF(推奨)
- Web やプレゼンテーションには SVG
- 旧式の出版システムには EPS
- フォールバックとして高解像度 PNG(300 DPI 以上)
色覚多様性に配慮したデザイン
- カテゴリ要素には Okabe-Ito パレット
- 連続データには知覚的に均一なカラーマップ
- 冗長な符号化(形状+色)
- グレースケールでの互換性を確認
タイポグラフィの基準
- 一貫性を保つため、サンセリフフォント(Arial、Helvetica)を使用
- 最終的な印刷サイズで最小 7~8 pt の文字
- 単位を含む、明瞭で読みやすいラベル
- 全体を通して一貫した表記法
アクセシビリティ
- 要素間の高いコントラスト
- 適切な線幅(最小 0.5~1 pt)
- 明確な視覚的階層
- 説明的なキャプションと代替テキスト
出版ガイドラインの詳細については、references/best_practices.md を参照してください。
クイックスタートの例
例 1:TikZ を使った簡単なフローチャート
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, arrows.meta}
% Load colorblind-safe colors
\input{tikz_styles.tex}
\begin{document}
\begin{figure}[h]
\centering
\begin{tikzpicture}[
node distance=2cm,
process/.style={rectangle, rounded corners, draw=black, thick,
fill=okabe-blue!20, minimum width=3cm, minimum height=1cm},
decision/.style={diamond, draw=black, thick, fill=okabe-orange!20,
minimum width=2cm, aspect=2},
arrow/.style={-Stealth, thick}
]
% Nodes
\node (start) [process] {Screen Participants\\(n=500)};
\node (exclude) [process, below of=start] {Exclude (n=150)\\Age $<$ 18 years};
\node (randomize) [process, below of=exclude] {Randomize (n=350)};
\node (treatment) [process, below left=1.5cm and 2cm of randomize]
{Treatment Group\\(n=175)};
\node (control) [process, below right=1.5cm and 2cm of randomize]
{Control Group\\(n=175)};
\node (analyze) [process, below=3cm of randomize] {Analyze Data};
% Arrows
\draw [arrow] (start) -- (exclude);
\draw [arrow] (exclude) -- (randomize);
\draw [arrow] (randomize) -| (treatment);
\draw [arrow] (randomize) -| (control);
\draw [arrow] (treatment) |- (analyze);
\draw [arrow] (control) |- (analyze);
\end{tikzpicture}
\caption{Study participant flow diagram following CONSORT guidelines.}
\label{fig:consort}
\end{figure}
\end{document}
例 2:Schemdraw を使用した回路図
import schemdraw
import schemdraw.elements as elm
# Create drawing with colorblind-safe colors
d = schemdraw.Drawing()
# Voltage source
d += elm.SourceV().label('$V_s$')
# Resistors in series
d += elm.Resistor().right().label('$R_1$\n1kΩ')
d += elm.Resistor().label('$R_2$\n2kΩ')
# Capacitor
d += elm.Capacitor().down().label('$C_1$\n10µF')
# Close the circuit
d += elm.Line().left().tox(d.elements[0].start)
# Add ground
d += elm.Ground()
# Save as vector graphics
d.save('circuit_diagram.svg')
d.save('circuit_diagram.pdf')
例 3:Python を使用した生物学的経路
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
# Okabe-Ito colorblind-safe palette
colors = {
'protein': '#56B4E9', # Blue
'gene': '#009E73', # Green
'process': '#F0E442', # Yellow
'inhibition': '#D55E00' # Orange
}
fig, ax = plt.subplots(figsize=(8, 6))
# Define proteins as rounded rectangles
proteins = [
('Receptor', 1, 5),
('Kinase A', 3, 5),
('Kinase B', 5, 5),
('TF', 7, 5),
('Gene', 7, 3)
]
for name, x, y in proteins:
color = colors['gene'] if name == 'Gene' else colors['protein']
box = FancyBboxPatch((x-0.4, y-0.3), 0.8, 0.6,
boxstyle="round,pad=0.1",
facecolor=color, edgecolor='black', linewidth=2)
ax.add_patch(box)
ax.text(x, y, name, ha='center', va='center', fontsize=10, fontweight='bold')
# Add activation arrows
arrows = [
(1.5, 5, 2.5, 5, 'black'), # Receptor -> Kinase A
(3.5, 5, 4.5, 5, 'black'), # Kinase A -> Kinase B
(5.5, 5, 6.5, 5, 'black'), # Kinase B -> TF
(7, 4.7, 7, 3.6, 'black') # TF -> Gene
]
for x1, y1, x2, y2, color in arrows:
arrow = FancyArrowPatch((x1, y1), (x2, y2),
arrowstyle='->', mutation_scale=20,
linewidth=2, color=color)
ax.add_patch(arrow)
# Configure axes
ax.set_xlim(0, 8.5)
ax.set_ylim(2, 6)
ax.set_aspect('equal')
ax.axis('off')
plt.tight_layout()
plt.savefig('signaling_pathway.pdf', bbox_inches='tight', dpi=300)
plt.savefig('signaling_pathway.png', bbox_inches='tight', dpi=300)
本番ワークフロー(コンセプトから公開まで)
すべての図で、次の体系的なワークフローに従ってください。
フェーズ 1:分析(2 分)
-
図の種類を特定する - 何を可視化しますか?
- ニューラルネットワークのアーキテクチャですか? → graphviz を使用します
- フローチャート(CONSORT、PRISMA)ですか? → graphviz を使用します
- 回路図ですか? → schemdraw を使用します
- 複雑なネットワークですか? → networkx + graphviz を使用します
-
レイアウトの方向を決定する
- 垂直方向の流れ(上から下)ですか? →
rankdir='TB' - 下から上(Transformer のような形式)ですか? →
rankdir='BT' - 左から右への順序ですか? →
rankdir='LR' - 右から左ですか? →
rankdir='RL'
- 垂直方向の流れ(上から下)ですか? →
-
グループ分けを特定する
- 並列構造(エンコーダー/デコーダー)ですか? → クラスター/サブグラフを使用します
- 順次構造のみですか? → シンプルなノードチェーンを使用します
- 相互接続がありますか? → Graphviz が自動的に処理します
フェーズ 2:実装(10~15 分)
図の 95% で共通する標準的な手順:
import graphviz
from pathlib import Path
# 1. Set up output directory
output_dir = 'figures'
Path(output_dir).mkdir(exist_ok=True, parents=True)
# 2. Create diagram with base template
dot = graphviz.Digraph(
'my_diagram',
format='pdf',
graph_attr={
'rankdir': 'TB', # Adjust based on Phase 1
'splines': 'ortho', # Clean orthogonal edges
'nodesep': '0.6', # Good default spacing
'ranksep': '0.8',
'bgcolor': 'white',
'dpi': '300'
},
node_attr={
'shape': 'box',
'style': 'rounded,filled',
'fillcolor': 'lightgray',
'fontname': 'Arial',
'fontsize': '11'
},
edge_attr={'color': 'black', 'penwidth': '1.5'}
)
# 3. Add nodes (with descriptive IDs and clear labels)
dot.node('input', 'Input Layer', fillcolor='#E8F4F8')
dot.node('hidden', 'Hidden Layer', fillcolor='#B3D9E6')
dot.node('output', 'Output Layer', fillcolor='#C8E6C9')
# 4. Add edges
dot.edge('input', 'hidden')
dot.edge('hidden', 'output')
# 5. Render to figures/ folder
output_path = f'{output_dir}/my_diagram'
dot.render(output_path, cleanup=True) # Creates PDF
dot.format = 'svg'
dot.render(output_path, cleanup=True) # Creates SVG
dot.format = 'eps'
dot.render(output_path, cleanup=True) # Creates EPS
print(f"✓ Saved to: {output_path}.{{pdf,svg,eps}}")
フェーズ 3:品質確認(5 分)
自動チェック:
# Convert PDF to PNG for quality checking
from pdf2image import convert_from_path
pages = convert_from_path(f'{output_path}.pdf', dpi=300)
pages[0].save(f'{output_path}.png')
# Run quality checks
from quality_checker import run_quality_checks
report = run_quality_checks(f'{output_path}.png')
if report['overall_status'] != 'PASS':
print("⚠️ Issues detected - review quality_reports/")
# Adjust spacing: increase nodesep or ranksep
# Adjust colors: check accessibility report
else:
print("✓ Quality checks passed!")
手動確認:
- ビューアーで PDF を開き、重なりがないか確認します
- テキストが読みやすいことを確認します(100% に拡大します)
- 配置と間隔が適切に見えることを確認します
- 色を区別できることを確認します
フェーズ 4:LaTeX への統合(2 分)
LaTeX ドキュメント内で:
% In preamble
\usepackage{graphicx}
% In document
\begin{figure}[htbp]
\centering
\includegraphics[width=0.8\textwidth]{figures/my_diagram.pdf}
\caption{Clear, descriptive caption explaining all components and abbreviations.
Define any non-standard notation used in the diagram.}
\label{fig:my_diagram}
\end{figure}
% Reference in text
As shown in Figure~\ref{fig:my_diagram}, the architecture consists of...
ポスターの場合(beamer):
\begin{frame}{Architecture}
\begin{center}
\includegraphics[width=0.9\textwidth]{figures/my_diagram.pdf}
\end{center}
\end{frame}
フェーズ 5:バージョン管理(1 分)
必ずコミットするもの:
- Python ソースコード(
create_my_diagram.py) - 生成された出力(
figures/my_diagram.{pdf,svg,eps}) - 品質レポート(
my_diagram_quality_reports/)
git add create_my_diagram.py
git add figures/my_diagram.*
git add my_diagram_quality_reports/
git commit -m "Add architecture diagram with quality verification"
よくある問題のトラブルシューティング
Graphviz 固有の問題
問題: ノードが重なっている、または間隔が狭すぎる
# Solution: Increase spacing
graph_attr={
'nodesep': '1.0', # Increase from default 0.6
'ranksep': '1.2' # Increase from default 0.8
}
問題: エッジがわかりにくく交差している
# Solution 1: Use orthogonal splines
graph_attr={'splines': 'ortho'}
# Solution 2: Adjust rank direction
graph_attr={'rankdir': 'LR'} # Try different directions
問題: ラベルが途切れている、または小さすぎる
# Solution: Adjust node size and font
node_attr={
'fontsize': '12', # Increase from 11
'margin': '0.3', # More internal padding
'width': '2.5', # Wider boxes
'height': '0.6' # Taller boxes
}
問題: クラスター/サブグラフが表示されない
# Solution: Cluster names MUST start with 'cluster_'
with dot.subgraph(name='cluster_encoder') as enc: # ✓ Correct
enc.attr(label='Encoder')
with dot.subgraph(name='encoder') as enc: # ✗ Won't show as cluster
enc.attr(label='Encoder')
問題: クラスターをまたぐエッジが機能しない
# Solution: Enable compound edges
dot.attr(compound='true')
# Then use lhead/ltail for cluster connections
dot.edge('node1', 'node2', lhead='cluster_decoder')
問題: Graphviz が見つからないというエラーが表示される
# Solution: Install graphviz binary (not just Python package)
# macOS
brew install graphviz
# Ubuntu
sudo apt-get install graphviz
# Then install Python bindings
pip install graphviz
視覚的な品質の問題
問題: 色覚多様性に配慮した色になっていない
# Solution: Use Okabe-Ito palette
COLORS = {
'blue': '#56B4E9',
'green': '#009E73',
'orange': '#E69F00',
'purple': '#CC79A7'
}
dot.node('n1', 'Node', fillcolor=COLORS['blue'])
問題: 印刷するとテキストが小さすぎる
# Solution: Increase font size and DPI
node_attr={'fontsize': '12'} # Minimum 11-12 for print
graph_attr={'dpi': '300'} # Publication quality
問題: PDF のサイズが大きすぎる
# Solution 1: Use simpler edge routing
graph_attr={'splines': 'line'} # Simpler than 'ortho'
# Solution 2: Reduce DPI for drafts
graph_attr={'dpi': '150'} # For drafts only
ワークフローの問題
問題: 変更後に図を再生成する必要がある
# Solution: Make diagram generation a function
def create_diagram(params):
# ... diagram code ...
return output_path
# Easy to regenerate with different parameters
create_diagram({'nodesep': '0.8', 'ranksep': '1.0'})
問題: 図が論文中の図のスタイルと一致しない
# Solution: Create a reusable style configuration
PAPER_STYLE = {
'graph_attr': {
'rankdir': 'TB',
'bgcolor': 'white',
'dpi': '300'
},
'node_attr': {
'fontname': 'Arial',
'fontsize': '11',
'style': 'rounded,filled',
'fillcolor': '#E8F4F8'
},
'edge_attr': {
'color': 'black',
'penwidth': '1.5'
}
}
# Use for all diagrams
dot = graphviz.Digraph(**PAPER_STYLE)
視覚的な確認と品質管理
すべての図で、自動視覚品質チェックを実施し、重なりを防ぎ、読みやすさを確保し、アクセシビリティを確認します。この多段階の確認プロセスでは、コンピュータービジョン技術を使用して一般的な問題を検出します。
ステージ 1:重なりの検出
明瞭さを損なう要素の重なりを自動的に検出します。
import numpy as np
from PIL import Image
import json
from pathlib import Path
def detect_overlaps(image_path, threshold=0.95):
"""
Detect potential overlapping regions in a diagram.
Args:
image_path: Path to the rendered diagram (PNG/PDF)
threshold: Similarity threshold for detecting overlaps (0-1)
Returns:
dict: Overlap report with locations and severity
"""
# Load image
img = Image.open(image_path).convert('RGB')
img_array = np.array(img)
# Detect dense regions (potential overlaps)
gray = np.mean(img_array, axis=2)
# Edge detection to find boundaries
from scipy.ndimage import sobel
edges_x = sobel(gray, axis=0)
edges_y = sobel(gray, axis=1)
edge_magnitude = np.hypot(edges_x, edges_y)
# Find regions with high edge density (overlaps)
from scipy.ndimage import label, find_objects
binary_edges = edge_magnitude > np.percentile(edge_magnitude, 85)
labeled_regions, num_features = label(binary_edges)
overlaps = []
slices = find_objects(labeled_regions)
for i, slice_obj in enumerate(slices):
if slice_obj is not None:
region = edge_magnitude[slice_obj]
density = np.mean(region)
# High density suggests potential overlap
if density > threshold * np.max(edge_magnitude):
y_center = (slice_obj[0].start + slice_obj[0].stop) // 2
x_center = (slice_obj[1].start + slice_obj[1].stop) // 2
overlaps.append({
'region_id': i + 1,
'position': (x_center, y_center),
'density': float(density),
'severity': 'high' if density > 0.98 * np.max(edge_magnitude) else 'medium'
})
report = {
'image': str(image_path),
'overlaps_detected': len(overlaps),
'overlap_regions': overlaps,
'status': 'PASS' if len(overlaps) == 0 else 'WARNING'
}
return report
def save_overlap_report(report, output_path='overlap_report.json'):
"""Save overlap detection report to JSON."""
with open(output_path, 'w') as f:
json.dump(report, indent=2, fp=f)
print(f"Overlap Report: {report['status']}")
print(f" - Overlaps detected: {report['overlaps_detected']}")
if report['overlap_regions']:
print(" - Regions requiring review:")
for region in report['overlap_regions']:
print(f" * Region {region['region_id']}: "
f"Position {region['position']}, Severity: {region['severity']}")
ステージ 2:コントラストとアクセシビリティの確認
色覚多様性のある読者に対するアクセシビリティ基準を図が満たしていることを確認します。
def verify_accessibility(image_path):
"""
Verify diagram meets accessibility standards.
Checks:
- Sufficient contrast ratios
- Grayscale readability
- Text size adequacy
"""
from PIL import ImageFilter, ImageStat
img = Image.open(image_path).convert('RGB')
# Test 1: Grayscale conversion
grayscale = img.convert('L')
gray_stat = ImageStat.Stat(grayscale)
# Calculate contrast (std dev of grayscale)
contrast = gray_stat.stddev[0]
min_contrast = 30 # Minimum standard deviation for good contrast
# Test 2: Color distribution
rgb_array = np.array(img)
unique_colors = len(np.unique(rgb_array.reshape(-1, 3), axis=0))
# Test 3: Simulate common color blindness (deuteranopia)
def simulate_colorblind(img_array):
# Simplified deuteranopia simulation
colorblind = img_array.copy().astype(float)
colorblind[:, :, 0] = 0.625 * img_array[:, :, 0] + 0.375 * img_array[:, :, 1]
colorblind[:, :, 1] = 0.7 * img_array[:, :, 1] + 0.3 * img_array[:, :, 0]
return colorblind.astype(np.uint8)
colorblind_img = simulate_colorblind(np.array(img))
cb_image = Image.fromarray(colorblind_img)
cb_gray = cb_image.convert('L')
cb_stat = ImageStat.Stat(cb_gray)
cb_contrast = cb_stat.stddev[0]
report = {
'image': str(image_path),
'checks': {
'grayscale_contrast': {
'value': contrast,
'threshold': min_contrast,
'status': 'PASS' if contrast >= min_contrast else 'FAIL'
},
'colorblind_contrast': {
'value': cb_contrast,
'threshold': min_contrast * 0.8,
'status': 'PASS' if cb_contrast >= min_contrast * 0.8 else 'FAIL'
},
'color_diversity': {
'unique_colors': unique_colors,
'status': 'INFO'
}
},
'overall_status': 'PASS' if (contrast >= min_contrast and
cb_contrast >= min_contrast * 0.8) else 'FAIL'
}
return report
def save_accessibility_report(report, output_path='accessibility_report.json'):
"""Save accessibility report to JSON."""
with open(output_path, 'w') as f:
json.dump(report, indent=2, fp=f)
print(f"Accessibility Report: {report['overall_status']}")
for check_name, check_data in report['checks'].items():
print(f" - {check_name}: {check_data['status']}")
if 'value' in check_data and 'threshold' in check_data:
print(f" Value: {check_data['value']:.2f}, Threshold: {check_data['threshold']:.2f}")
ステージ 3:テキストサイズと解像度の検証
出版時のサイズでテキストが読みやすいことを確認します。
def validate_resolution(image_path, target_dpi=300, min_text_size_pt=7):
"""
Validate image resolution and estimated text size.
Args:
image_path: Path to diagram image
target_dpi: Target DPI for publication (default 300)
min_text_size_pt: Minimum acceptable text size in points
"""
from PIL import Image
import pytesseract
img = Image.open(image_path)
# Check DPI
dpi = img.info.get('dpi', (72, 72))
actual_dpi = dpi[0] if isinstance(dpi, tuple) else dpi
# Estimate text size (simplified - assumes text detection)
# For production, use OCR or PDF text extraction
width, height = img.size
dpi_ratio = actual_dpi / 72 # Convert to screen pixels
# Calculate physical size in inches
width_inches = width / actual_dpi if actual_dpi > 0 else width / 72
height_inches = height / actual_dpi if actual_dpi > 0 else height / 72
report = {
'image': str(image_path),
'resolution': {
'dpi': actual_dpi,
'target_dpi': target_dpi,
'status': 'PASS' if actual_dpi >= target_dpi else 'WARNING'
},
'dimensions': {
'pixels': {'width': width, 'height': height},
'inches': {'width': round(width_inches, 2),
'height': round(height_inches, 2)}
},
'recommendations': []
}
if actual_dpi < target_dpi:
report['recommendations'].append(
f"Increase resolution to {target_dpi} DPI for publication quality"
)
if width_inches > 7:
report['recommendations'].append(
"Image width exceeds typical single-column width (7 inches)"
)
return report
ステージ 4:包括的な品質チェックパイプライン
すべての確認ステージを順番に実行します。
def run_quality_checks(image_path, output_dir='quality_reports'):
"""
Run comprehensive quality checks on diagram.
Args:
image_path: Path to diagram to verify
output_dir: Directory to save reports
Returns:
dict: Comprehensive quality report
"""
import os
from datetime import datetime
Path(output_dir).mkdir(exist_ok=True)
print(f"Running quality checks on: {image_path}")
print("=" * 60)
# Stage 1: Overlap Detection
print("\n[Stage 1/4] Detecting overlaps...")
overlap_report = detect_overlaps(image_path)
save_overlap_report(
overlap_report,
f"{output_dir}/overlap_report.json"
)
# Stage 2: Accessibility
print("\n[Stage 2/4] Verifying accessibility...")
accessibility_report = verify_accessibility(image_path)
save_accessibility_report(
accessibility_report,
f"{output_dir}/accessibility_report.json"
)
# Stage 3: Resolution
print("\n[Stage 3/4] Validating resolution...")
resolution_report = validate_resolution(image_path)
with open(f"{output_dir}/resolution_report.json", 'w') as f:
json.dump(resolution_report, f, indent=2)
# Stage 4: Generate visual report
print("\n[Stage 4/4] Generating visual report...")
create_visual_report(
image_path,
overlap_report,
accessibility_report,
f"{output_dir}/visual_report.png"
)
# Comprehensive summary
all_pass = (
overlap_report['status'] != 'FAIL' and
accessibility_report['overall_status'] != 'FAIL' and
resolution_report['resolution']['status'] != 'FAIL'
)
summary = {
'timestamp': datetime.now().isoformat(),
'image': str(image_path),
'overall_status': 'PASS' if all_pass else 'NEEDS REVIEW',
'stage_results': {
'overlap_detection': overlap_report['status'],
'accessibility': accessibility_report['overall_status'],
'resolution': resolution_report['resolution']['status']
},
'reports_saved_to': output_dir
}
with open(f"{output_dir}/summary.json", 'w') as f:
json.dump(summary, f, indent=2)
print("\n" + "=" * 60)
print(f"OVERALL STATUS: {summary['overall_status']}")
print(f"Reports saved to: {output_dir}/")
print("=" * 60)
return summary
def create_visual_report(image_path, overlap_report, accessibility_report, output_path):
"""Create visual report with annotations."""
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
# Load original image
img = Image.open(image_path)
# Panel 1: Original with overlap markers
axes[0].imshow(img)
axes[0].set_title('Overlap Detection', fontsize=12, fontweight='bold')
if overlap_report['overlap_regions']:
for region in overlap_report['overlap_regions']:
x, y = region['position']
color = 'red' if region['severity'] == 'high' else 'orange'
circle = Circle((x, y), 20, color=color, fill=False, linewidth=2)
axes[0].add_patch(circle)
axes[0].axis('off')
axes[0].text(0.02, 0.98, f"Status: {overlap_report['status']}",
transform=axes[0].transAxes, fontsize=10,
verticalalignment='top', bbox=dict(boxstyle='round',
facecolor='wheat', alpha=0.5))
# Panel 2: Grayscale version
gray_img = img.convert('L')
axes[1].imshow(gray_img, cmap='gray')
axes[1].set_title('Grayscale Preview', fontsize=12, fontweight='bold')
axes[1].axis('off')
gray_status = accessibility_report['checks']['grayscale_contrast']['status']
axes[1].text(0.02, 0.98, f"Status: {gray_status}",
transform=axes[1].transAxes, fontsize=10,
verticalalignment='top', bbox=dict(boxstyle='round',
facecolor='wheat', alpha=0.5))
# Panel 3: Colorblind simulation
img_array = np.array(img)
colorblind = img_array.copy().astype(float)
colorblind[:, :, 0] = 0.625 * img_array[:, :, 0] + 0.375 * img_array[:, :, 1]
colorblind[:, :, 1] = 0.7 * img_array[:, :, 1] + 0.3 * img_array[:, :, 0]
axes[2].imshow(colorblind.astype(np.uint8))
axes[2].set_title('Colorblind Simulation', fontsize=12, fontweight='bold')
axes[2].axis('off')
cb_status = accessibility_report['checks']['colorblind_contrast']['status']
axes[2].text(0.02, 0.98, f"Status: {cb_status}",
transform=axes[2].transAxes, fontsize=10,
verticalalignment='top', bbox=dict(boxstyle='round',
facecolor='wheat', alpha=0.5))
plt.tight_layout()
plt.savefig(output_path, dpi=150, bbox_inches='tight')
print(f"Visual report saved: {output_path}")
plt.close()
使用例:確認を含む完全なワークフロー
品質を十分に確認しながら図を作成する方法を紹介します。
import matplotlib.pyplot as plt
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
# Step 1: Create diagram
def create_flowchart_with_verification(output_base='flowchart'):
"""Create flowchart with automated quality checks."""
# Okabe-Ito colorblind-safe palette
colors = {
'process': '#56B4E9', # Blue
'decision': '#E69F00', # Orange
'data': '#009E73', # Green
'terminal': '#CC79A7' # Purple
}
fig, ax = plt.subplots(figsize=(8, 10))
# Define flowchart elements with careful spacing
elements = [
('Start', 4, 9, 'terminal'),
('Input Data', 4, 7.5, 'data'),
('Process A', 4, 6, 'process'),
('Decision?', 4, 4.5, 'decision'),
('Process B1', 2, 3, 'process'),
('Process B2', 6, 3, 'process'),
('Output', 4, 1.5, 'data'),
('End', 4, 0, 'terminal')
]
# Draw boxes with adequate spacing
box_positions = {}
for label, x, y, element_type in elements:
color = colors[element_type]
width, height = (1.2, 0.6) if element_type != 'decision' else (1.5, 1.0)
box = FancyBboxPatch(
(x - width/2, y - height/2), width, height,
boxstyle="round,pad=0.1" if element_type != 'decision' else "round,pad=0.05",
facecolor=color, edgecolor='black', linewidth=2
)
ax.add_patch(box)
ax.text(x, y, label, ha='center', va='center',
fontsize=10, fontweight='bold')
box_positions[label] = (x, y)
# Draw arrows with proper spacing
arrows = [
('Start', 'Input Data'),
('Input Data', 'Process A'),
('Process A', 'Decision?'),
('Decision?', 'Process B1'),
('Decision?', 'Process B2'),
('Process B1', 'Output'),
('Process B2', 'Output'),
('Output', 'End')
]
for start, end in arrows:
x1, y1 = box_positions[start]
x2, y2 = box_positions[end]
# Calculate arrow start/end points to avoid overlap
if x1 == x2: # Vertical arrow
y1_adj = y1 - 0.3 if y2 < y1 else y1 + 0.3
y2_adj = y2 + 0.3 if y2 < y1 else y2 - 0.3
arrow = FancyArrowPatch(
(x1, y1_adj), (x2, y2_adj),
arrowstyle='->', mutation_scale=20, linewidth=2, color='black'
)
else: # Diagonal arrow
arrow = FancyArrowPatch(
(x1, y1 - 0.5), (x2, y2 + 0.3),
arrowstyle='->', mutation_scale=20, linewidth=2, color='black'
)
ax.add_patch(arrow)
ax.set_xlim(0, 8)
ax.set_ylim(-0.5, 9.5)
ax.set_aspect('equal')
ax.axis('off')
plt.tight_layout()
# Save in multiple formats
plt.savefig(f'{output_base}.pdf', bbox_inches='tight', dpi=300)
plt.savefig(f'{output_base}.png', bbox_inches='tight', dpi=300)
plt.savefig(f'{output_base}.svg', bbox_inches='tight')
print(f"Diagram saved: {output_base}.pdf/.png/.svg")
plt.close()
# Step 2: Run quality checks
print("\nRunning quality verification...")
quality_report = run_quality_checks(
f'{output_base}.png',
output_dir=f'{output_base}_quality_reports'
)
# Step 3: Review and iterate if needed
if quality_report['overall_status'] != 'PASS':
print("\n⚠️ Diagram needs review. Check quality reports for details.")
return False
else:
print("\n✓ Diagram passed all quality checks!")
return True
# Run complete workflow
if __name__ == '__main__':
success = create_flowchart_with_verification('my_flowchart')
反復的な改善ループ
複雑な図では、反復的な改善プロセスを使用します。
def iterative_diagram_refinement(create_function, max_iterations=3):
"""
Iteratively refine diagram until it passes quality checks.
Args:
create_function: Function that creates and saves diagram
max_iterations: Maximum refinement attempts
"""
for iteration in range(1, max_iterations + 1):
print(f"\n{'='*60}")
print(f"ITERATION {iteration}/{max_iterations}")
print(f"{'='*60}")
# Create diagram
diagram_path = create_function(iteration)
# Run checks
quality_report = run_quality_checks(
diagram_path,
output_dir=f'iteration_{iteration}_reports'
)
if quality_report['overall_status'] == 'PASS':
print(f"\n✓ Diagram approved after {iteration} iteration(s)")
return True
else:
print(f"\n⚠️ Issues found. Adjusting parameters for next iteration...")
# Here you would adjust spacing, colors, etc. based on reports
print(f"\n❌ Maximum iterations reached. Manual review required.")
return False
よくあるユースケース
ユースケース 1:CONSORT 参加者フローダイアグラム
臨床試験では、標準化された参加者フローダイアグラムが必要です。フローチャートのテンプレートを使用してください。
% Load template
\input{assets/flowchart_template.tex}
% Customize with your numbers
\begin{tikzpicture}[consort]
\node (assessed) [flowbox] {Assessed for eligibility (n=500)};
\node (excluded) [flowbox, below=of assessed] {Excluded (n=150)};
\node (reasons) [infobox, right=of excluded] {
\begin{tabular}{l}
Age $<$ 18: n=80 \\
Declined: n=50 \\
Other: n=20
\end{tabular}
};
% ... continue diagram
\end{tikzpicture}
完全なテンプレートについては、assets/flowchart_template.tex を参照してください。
ユースケース 2:電子回路図
電子工学の論文では、Schemdraw または CircuitikZ を使用してください。
# Python with Schemdraw - see scripts/circuit_generator.py
from scripts.circuit_generator import create_circuit
circuit = create_circuit(
components=['voltage_source', 'resistor', 'capacitor', 'ground'],
values=['5V', '1kΩ', '10µF', None],
layout='series'
)
circuit.save('my_circuit.pdf')
または LaTeX で CircuitikZ を使用します。assets/circuit_template.tex を参照してください。
ユースケース 3:生物学的シグナル伝達経路
分子間相互作用とシグナル伝達カスケードを可視化します。
# Python script - see scripts/pathway_diagram.py
from scripts.pathway_diagram import PathwayGenerator
pathway = PathwayGenerator()
pathway.add_protein('EGFR', position=(1, 5))
pathway.add_protein('RAS', position=(3, 5))
pathway.add_protein('RAF', position=(5, 5))
pathway.add_activation('EGFR', 'RAS')
pathway.add_activation('RAS', 'RAF')
pathway.save('mapk_pathway.pdf')
または TikZ で作成します。assets/pathway_template.tex を参照してください。
ユースケース 4:システムアーキテクチャ図
ソフトウェア/ハードウェアのコンポーネントと関係を図示します。
% Use block diagram template
\input{assets/block_diagram_template.tex}
\begin{tikzpicture}[architecture]
\node (sensor) [component] {Sensor};
\node (adc) [component, right=of sensor] {ADC};
\node (micro) [component, right=of adc] {Microcontroller};
\node (wifi) [component, above right=of micro] {WiFi Module};
\node (display) [component, below right=of micro] {Display};
\draw [dataflow] (sensor) -- node[above] {Analog} (adc);
\draw [dataflow] (adc) -- node[above] {Digital} (micro);
\draw [dataflow] (micro) -- (wifi);
\draw [dataflow] (micro) -- (display);
\end{tikzpicture}
完全なテンプレートについては、assets/block_diagram_template.tex を参照してください。
ヘルパースクリプト
script/ ディレクトリには、図の自動生成と品質検証のための Python ユーティリティが含まれています。
generate_flowchart.py
テキストによる説明を、自動品質チェック付きの TikZ フローチャートに変換します。
from scripts.generate_flowchart import text_to_flowchart, create_with_verification
description = """
1. Screen participants (n=500)
2. Exclude if age < 18 (n=150)
3. Randomize remaining (n=350)
4. Treatment group (n=175)
5. Control group (n=175)
6. Follow up at 3 months
7. Analyze data
"""
# Generate TikZ code
tikz_code = text_to_flowchart(description)
with open('methodology_flow.tex', 'w') as f:
f.write(tikz_code)
# Or create with automatic verification
success = create_with_verification(
description,
output='methodology_flow',
verify=True
)
circuit_generator.py
品質検証付きで、Schemdraw を使って回路図を生成します。
from scripts.circuit_generator import CircuitBuilder
builder = CircuitBuilder()
builder.add_voltage_source('Vs', '5V')
builder.add_resistor('R1', '1kΩ')
builder.add_capacitor('C1', '10µF')
builder.add_ground()
# Save with automatic quality checks
builder.save('circuit.pdf', verify=True)
# Access quality report
print(builder.quality_report)
pathway_diagram.py
重なり検出機能付きで、生物学的経路図を作成します。
from scripts.pathway_diagram import PathwayGenerator
gen = PathwayGenerator(
colorblind_safe=True,
auto_spacing=True # Automatically adjust spacing to prevent overlaps
)
gen.add_node('Receptor', type='protein', position=(1, 5))
gen.add_node('Kinase', type='protein', position=(3, 5))
gen.add_edge('Receptor', 'Kinase', interaction='activation')
# Save with quality verification
quality_report = gen.save('pathway.pdf', verify=True)
# Iteratively refine if needed
if quality_report['status'] != 'PASS':
gen.auto_adjust_spacing()
gen.save('pathway.pdf', verify=True)
compile_tikz.py
品質チェック機能付きの、単体で使える TikZ コンパイルユーティリティです。
# Compile TikZ to PDF with verification
python scripts/compile_tikz.py flowchart.tex -o flowchart.pdf --verify
# Generate PNG with quality report
python scripts/compile_tikz.py flowchart.tex -o flowchart.pdf --png --dpi 300 --verify
# Preview with quality overlay
python scripts/compile_tikz.py flowchart.tex --preview --show-quality
quality_checker.py
あらゆる図を対象とした、単体で使える品質検証ツールです。
# Check single diagram
python scripts/quality_checker.py diagram.png
# Check with detailed report
python scripts/quality_checker.py diagram.png --detailed --output-dir reports/
# Batch check multiple diagrams
python scripts/quality_checker.py figures/*.png --batch
# Export visual comparison report
python scripts/quality_checker.py diagram.png --visual-report
# Python API
from scripts.quality_checker import DiagramQualityChecker
checker = DiagramQualityChecker()
# Run all checks
report = checker.check_diagram('diagram.png')
# Access specific checks
overlap_report = checker.check_overlaps('diagram.png')
accessibility_report = checker.check_accessibility('diagram.png')
resolution_report = checker.check_resolution('diagram.png')
# Generate visual report
checker.create_visual_report('diagram.png', output='quality_report.png')
# Batch processing
results = checker.batch_check(['fig1.png', 'fig2.png', 'fig3.png'])
checker.save_batch_report(results, 'batch_quality_report.json')
テンプレートとアセット
assets/ ディレクトリにある組み込みテンプレートを出発点として利用できます。
flowchart_template.tex- 方法論のフローチャート(CONSORT スタイル)circuit_template.tex- 電気回路図pathway_template.tex- 生物学的経路図block_diagram_template.tex- システムアーキテクチャ図tikz_styles.tex- 再利用可能なスタイル定義(必ず読み込んでください)
すべてのテンプレートは、色覚多様性に配慮した Okabe-Ito パレットと、出版に適したスタイルを使用しています。
ベストプラクティスのまとめ
設計原則
- 複雑さより明瞭さを優先 - 簡素化し、不要な要素を取り除きます
- 一貫したスタイル - テンプレートとスタイルファイルを使用します
- 色覚多様性への配慮 - Okabe-Ito パレットと冗長な符号化を使用します
- 適切なタイポグラフィ - サンセリフフォントを使用し、最小サイズは 7~8 pt とします
- ベクター形式 - 出版には必ず PDF/SVG を使用します
技術要件
- 解像度 - ベクター形式を推奨します。ラスター形式の場合は 300 DPI 以上とします
- ファイル形式 - LaTeX には PDF、ウェブには SVG、代替形式には PNG を使用します
- 色空間 - デジタル用途には RGB、印刷には CMYK を使用します(必要に応じて変換します)
- 線幅 - 最小 0.5 pt、一般的には 1~2 pt とします
- テキストサイズ - 最終サイズで最小 7~8 pt とします
統合ガイドライン
- LaTeX に含める - TikZ には
\input{}、外部ファイルには\includegraphics{}を使用します - キャプションを詳しく記述する - すべての要素と略語を説明します
- 本文で参照する - 説明文の流れの中で図を説明します
- 一貫性を保つ - 論文内のすべての図で同じスタイルを使用します
- バージョン管理 - ソースファイル(.tex、.py)をリポジトリに保存します
よくある問題のトラブルシューティング
TikZ のコンパイルエラー
問題:! Package tikz Error: I do not know the key '/tikz/...
- 解決策:ライブラリが不足しています。プリアンブルに
\usetikzlibrary{...}を追加します
問題:テキストまたは要素が重なっている
- 解決策:品質チェッカーを実行して重なりを特定します:
python scripts/quality_checker.py diagram.png - 解決策:
node distanceを大きくし、重なりレポートを参考に位置を手動で調整します - 解決策:経路図ジェネレーターで
auto_spacing=Trueを使用し、自動調整します
問題:矢印が正しく接続されない
- 解決策:アンカーポイントを使用します:
(node.east)、(node.north)など - 解決策:重なりレポートで矢印とノードの交差を確認します
Python 生成時の問題
問題:Schemdraw の要素が整列しない
- 解決策:正確に配置するには
.at()メソッドを使用します - 解決策:重なりを防ぐには
auto_spacingを有効にします
問題:Matplotlib のテキスト描画に関する問題
- 解決策:LaTeX で描画するには
plt.rcParams['text.usetex'] = Trueを設定します - 解決策:LaTeX がインストールされていることを確認します
問題:エクスポート品質が低い
- 解決策:DPI を上げます:
plt.savefig(..., dpi=300, bbox_inches='tight') - 解決策:解像度チェッカーを実行します:
quality_checker.check_resolution(image_path, target_dpi=300)
問題:生成後に要素が重なる
- 解決策:
detect_overlaps()関数を実行して問題のある領域を特定します - 解決策:反復的な調整を行います:
iterative_diagram_refinement(create_function) - 解決策:要素間の間隔を 20~30%広げます
品質チェックの問題
問題:重なり検出で誤検出が発生する
- 解決策:しきい値を調整します:
detect_overlaps(image_path, threshold=0.98) - 解決策:ビジュアルレポートでフラグが付いた領域を手動で確認します
問題:品質チェッカーが PDF ファイルで失敗する
- 解決策:まず PDF を PNG に変換します:
from pdf2image import convert_from_path - 解決策:品質チェックには PNG 出力形式を使用します
問題:色覚シミュレーションでコントラストが低く表示される
- 解決策:コードで Okabe-Ito パレットに明示的に切り替えます
- 解決策:冗長な符号化(形状、パターン、線種)を追加します
- 解決策:色の彩度と明度の差を大きくします
問題:重大度の高い重なりが検出される
- 解決策:正確な位置を確認するには overlap_report.json を確認します
- 解決策:該当する領域の間隔を広げます
- 解決策:パラメーターを調整して再実行し、もう一度確認します
問題:ビジュアルレポートの生成に失敗する
- 解決策:Pillow と matplotlib がインストールされていることを確認します
- 解決策:画像ファイルを読み取れることを確認します:
Image.open(path).verify() - 解決策:レポート生成に十分なディスク容量があることを確認します
アクセシビリティの問題
問題:グレースケールで色を区別できない
- 解決策:アクセシビリティチェッカーを実行します:
verify_accessibility(image_path) - 解決策:冗長性を確保するため、パターン、形状、または線種を追加します
- 解決策:隣接する要素間のコントラストを高めます
問題:印刷するとテキストが小さすぎる
- 解決策:解像度バリデーターを実行します:
validate_resolution(image_path) - 解決策:最終的なサイズでデザインし、フォントサイズは 7~8 pt 以上にします
- 解決策:解像度レポートで物理的な寸法を確認します
問題:アクセシビリティチェックが繰り返し失敗する
- 解決策:具体的な失敗内容を確認するには accessibility_report.json を確認します
- 解決策:色のコントラストを少なくとも 20%高めます
- 解決策:最終決定の前に、実際にグレースケールへ変換してテストします
リソースと参考資料
詳細な参考資料
特定のトピックについて詳しく知るには、以下のファイルを読み込んでください。
references/tikz_guide.md- TikZ の構文、配置、スタイル、テクニックの完全ガイドreferences/diagram_types.md- 例を含む科学図の種類の一覧references/best_practices.md- 出版基準とアクセシビリティのガイドラインreferences/python_libraries.md- 図の作成に使用する Schemdraw、NetworkX、Matplotlib のガイド
外部リソース
TikZ と LaTeX
- TikZ & PGF マニュアル:https://pgf-tikz.github.io/pgf/pgfmanual.pdf
- TeXample.net:http://www.texample.net/tikz/(サンプルギャラリー)
- CircuitikZ マニュアル:https://ctan.org/pkg/circuitikz
Python ライブラリ
- Schemdraw ドキュメント:https://schemdraw.readthedocs.io/
- NetworkX ドキュメント:https://networkx.org/documentation/
- Matplotlib ドキュメント:https://matplotlib.org/
出版基準
- Nature の図に関するガイドライン:https://www.nature.com/nature/for-authors/final-submission
- Science の図に関するガイドライン:https://www.science.org/content/page/instructions-preparing-initial-manuscript
- CONSORT 図:https://www.consort-statement.org/consort-statement/flow-diagram
他のスキルとの連携
このスキルは、以下のスキルと相乗的に機能します。
- 科学論文の執筆 - 図は図版のベストプラクティスに従います
- 科学的可視化 - カラーパレットとスタイルを共有します
- LaTeX ポスター - ポスター図に TikZ のスタイルを再利用します
- 研究助成金 - 申請書の方法論図を作成します
- 査読 - 図の明瞭さとアクセシビリティを評価します
クイックリファレンスチェックリスト
図を提出する前に、以下を確認してください。
視覚的な品質
- ベクター形式(PDF/SVG)、または 300 DPI 以上のラスター形式である
- 要素が重なっていない(品質チェッカーで確認済み)
- すべての構成要素の間隔が十分に確保されている
- 配置がすっきりとしており、プロフェッショナルである
- すべての矢印が意図した対象に正しく接続されている
アクセシビリティ
- 色覚異常に配慮したパレット(Okabe-Ito)を使用している
- グレースケールでも機能する(アクセシビリティチェッカーでテスト済み)
- 要素間のコントラストが十分である(確認済み)
- 適切な箇所では冗長な符号化(形状+色)を使用している
- 色覚異常シミュレーションですべてのチェックに合格している
タイポグラフィと可読性
- 最終サイズでテキストが 7~8 pt 以上である
- すべての要素に明確かつ完全なラベルが付いている
- フォントファミリーとサイズが統一されている
- テキストの重なりや欠けがない
- 該当する場合は単位が含まれている
出版基準
- 原稿内の他の図とスタイルが統一されている
- すべての略語を定義した包括的なキャプションが作成されている
- 原稿本文で適切に参照されている
- ジャーナル固有の寸法要件を満たしている
- ジャーナル指定の形式(PDF/EPS/TIFF)で書き出されている
品質検証(必須)
-
run_quality_checks()を実行し、PASS ステータスを達成した - 重なり検出レポートを確認した(重大度の高い重なりがゼロ)
- アクセシビリティ検証(グレースケールと色覚異常)に合格した
- 対象 DPI で解像度を検証した(印刷では 300 以上)
- 視覚品質レポートを生成して確認した
- すべての品質レポートを図のファイルと一緒に保存した
ドキュメントとバージョン管理
- 今後の修正に備えてソースファイル(.tex、.py)を保存した
- 品質レポートを
quality_reports/ディレクトリにアーカイブした - 設定パラメーター(色、間隔、サイズ)を文書化した
- Git のコミットにソース、出力、品質レポートが含まれている
- 図の再生成方法を README またはコメントで説明している
最終的な統合チェック
- コンパイル済み原稿で図が正しく表示される
- 相互参照が機能する(
\ref{}が正しい図を参照している) - 図番号が本文中の引用と一致している
- 図に対して正しいページにキャプションが表示されている
- 図に関連するコンパイル警告やエラーがない
このスキルを使用して、複雑な科学的概念を効果的に伝える、明瞭でアクセシビリティに配慮した出版品質の図を作成してください。統合された品質検証ワークフローにより、すべての図が出版前に専門的な基準を満たしていることを確認できます。