paper-figures について
paper-figuresは、表形式のデータと自然言語の指定から、論文向けの図を作成するスキルです。再現可能なmatplotlibスクリプトを生成・実行し、出力されたPNGを指定内容と照合します。
主な機能
- 01CSV、JSON、表形式データに対応
- 02自然言語による図の指定
- 03matplotlibを使うPythonスクリプト
- 04300 DPIでPNGを出力
- 05描画後の監査とステータス報告
活用シーン
- 01CSVの実験結果をグラフ化
- 02自然言語の説明から図を作成
- 03データと仕様に基づいて論文図を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ evoscientist/ evoskills --skill paper-figuresインストール後、Claude Code で/paper-figuresを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
requirements.txtreferences/chart-types.mdpublication-style.mdscripts/validate_figure.py詳細
論文用図表
matplotlib を使用して、表形式のデータと自然言語による説明から、出版可能な品質のグラフ図(PNG)を作成するための体系的なアプローチです。
このスキルを使う場面
- ユーザーが CSV/データフレーム/インラインデータを提供し、グラフを求めている
- ユーザーが作成したい図を文章で説明し、描画を求めている
- 論文や実験向けの「figure」「plot」「chart」「visualize」「render」に言及している
入力と出力
エージェントが受け取る入力:
- データソース:CSV ファイルのパス、JSON、またはインラインの表。
- 説明:グラフの種類、軸、タイトル、色、注釈、凡例、シナリオなどを指定する自然言語のテキストです。簡潔な場合もあれば、段落全体にわたる場合もあります。この説明が仕様のすべてです。参照画像は提供されません。
出力(常に):
- 次の処理を行う、単独で実行可能な Python スクリプト
plot.py:- 提供されたソースからデータを読み込む
matplotlibで図を描画するplt.savefig(..., dpi=300, bbox_inches="tight")を使って PNG を保存する
- その隣に描画済みの
plot.pngを出力します(スクリプトを実行して PNG を生成してください。スクリプトを書くだけで終わらせないでください)。
検証用成果物(ファイルシステムにアクセスできる場合に作成):
figure-spec.md— コーディング前に抽出した簡潔な図の仕様。audit.md— 描画後の監査チェックリストと、実施した修正。final-status.md—PASSED、PASSED_WITH_WARNINGS、REPAIRED、FAILED_NEEDS_HANDOFFのいずれか1つのステータスラベル。
出力ディレクトリ:
- ユーザーが出力ディレクトリ(例:「
path/to/dir/に保存」)を指定した場合は、そのディレクトリ内にplot.pyとplot.pngを書き込みます。ディレクトリが存在しない場合は作成してください。 - ディレクトリが指定されていない場合は、現在の作業ディレクトリに書き込みます。
- ファイル名は常に
plot.pyとplot.pngです。異なる入力で繰り返し実行する場合は、ファイル名を変えるのではなく、異なるディレクトリに出力してください。これにより、PNG の近くにあるスクリプトへの参照が安定し、バッチ比較も容易になります。
セットアップ
依存関係:pip install matplotlib pandas numpy scipy(スキルのルートにある requirements.txt にも記載されています)。ユーザーが作業している環境にインストールしてください。
基本ワークフロー
Step 1: Plan Figure -> verify: description/data ambiguity handled
Step 2: Inspect the data
Step 3: Write figure-spec.md -> verify: figure-spec.md has all required fields
Step 4: Pick the matplotlib idiom
Step 5: Apply publication-style defaults
Step 6: Write the script and run it -> verify: plot.py runs and plot.png exists
Step 7: Audit the result -> verify: chart matches spec, data, and description;
repair and re-audit until it does; final-status.md is honest
ワークフローは一度きりの描画タスクではなく、小規模な検証プロトコルとして扱ってください。監査に合格するか、残っている問題を明示するまで、グラフは完成ではありません。
ステータスラベル
最終ステータスは、次のうち1つだけを使用してください。
| ステータス | 意味 |
|---|---|
PASSED | 図が、要求されたグラフの種類、データ項目、尺度、ラベル、系列、凡例、注釈、および出力要件に一致しています。 |
PASSED_WITH_WARNINGS | 図は使用可能で、依頼内容にも忠実ですが、軽微なスタイルまたはレイアウトの不一致が残っており、その内容が audit.md に記載されています。 |
REPAIRED | 最初の描画で少なくとも1つの監査項目に不合格となり、スクリプトを修正した結果、修正版の描画が合格しています。 |
FAILED_NEEDS_HANDOFF | 必須項目、グラフの意味、パッケージ依存関係、または視覚的要件を検証または修正できませんでした。具体的な阻害要因を記載してください。 |
スクリプトが実行できたという理由で PASSED にしないでください。実行によって証明できるのは PNG が存在することだけであり、図が依頼内容に一致していることではありません。
ステップ 1:図を計画する
コードを書く前に、説明から以下を特定します。
- グラフの種類(折れ線、棒、散布図、円、KDE、バイオリン、バブル、トルネード、リング、ヒートマップなど)。種類が曖昧な場合は、明示されている種類を優先し、そうでなければ軸やデータの形状から判断します。
- 軸:x 軸ラベル、y 軸ラベル、単位、スケール(線形/対数)、目盛りの書式。サブプロット間での軸の共有、2 系列で x を共有しながら y の単位が異なる場合の二重軸(
ax.twinx()/ax.twiny())、値の範囲が大きく異なる場合の二重軸/分断軸に注意します。 - タイトル:説明文で引用符付きのタイトルが指定されている場合は、そのまま使います。
- 系列/カテゴリ:数、名前、順序。
- 色:特定の色が指定されている場合はそれを使い、それ以外はデフォルトの配色を使います。
- 注釈:凡例、グリッド線、基準線、データラベル。
「約 200」「0 をわずかに上回る」などの数量が説明に含まれている場合は、それらを CSV と照らし合わせて妥当性を確認します。説明は言い換えられていることがあり、CSV が正確な情報源です。
よく見られるパターンをいくつか紹介します。
- 断面データのタイトルに背景情報を含める:データが単一の年や単一の実験などのスナップショットである場合は、タイトル自体にその背景情報を含めます。括弧書き、カンマ区切りの接尾辞、引用符付きの接頭辞などを使います。
fig.textなどで独立した「サブタイトル」を追加しないでください。matplotlib にはすっきりしたサブタイトル用 API がなく、場当たり的なサブタイトルは配置やスタイルがずれがちです。 - 複数系列を区別する。ただし、同じ情報を重ねて表現しない:複数の系列がある場合、直接の終点ラベル、凡例、または凡例と組み合わせた異なる線種などで、読者が系列を見分けられるようにします。同じ系列に対して凡例と終点ラベルを併用したり、同じ点や領域に凡例項目とプロット上のテキスト注釈を併用したりしないでください。一方で、情報をすべて省くのも避けてください。複数の曲線を識別する手掛かりなしに表示することは許容されません。
- データを黙って省かない:入力のすべての系列とデータ点は、プロットに表示するか、表示されないことを明示します。スケール範囲外の値は端に注釈を付けます。系列全体を省略する場合は、説明でその理由を示します。黙って省略すると、プロットだけを見た読者には何が欠けているのかわからず、不備となります。
- 求められていない要素は追加しない。説明で求められた計算は行う:説明で求められているものだけをプロットします。依頼にない凡例項目、注釈、視覚要素を追加しないでください。データに存在しない行を作り出したり、説明にない推定値や集計値を計算したりしないでください。ただし、説明で求められている派生統計量(四分位数、平均、平滑化曲線、回帰フィット、密度推定など)は必須であり、禁止されているわけではありません。忠実に計算してください。
グラフの意味を左右する重大な曖昧さがある場合(たとえば、y 変数の候補が 2 つある場合や、単位の変換方法が不明な場合)は、具体的な質問を 1 つしてください。スタイル上の曖昧さにとどまる場合は、よりシンプルな案を選び、その判断を figure-spec.md に記録します。
ステップ 2:データを確認する
プロットのコードを書く前に、最初の約 10 行と列名を確認します。説明には意味上の意図が示され、CSV には構造上の正確な情報が示されています。列名について説明と CSV の内容が異なる場合は、CSV を優先します。
複数系列のデータでは、ロング形式(系列、x、y の各組につき 1 行)かワイド形式(系列ごとに 1 列)かを確認します。必要に応じてピボットまたはメルトします。
Step 3: figure-spec.md を作成する
コーディングを始める前に、簡潔な Markdown 仕様書を作成します。これは監査で確認する契約です。次の形式を使用してください。
# Figure Spec
- chart_type:
- data_sources:
- rows_in_scope:
- data_columns:
- x_axis:
- field:
- label:
- unit:
- scale:
- range:
- y_axis:
- field:
- label:
- unit:
- scale:
- range:
- additional_axes:
- series_or_categories:
- category_order:
- color_mapping:
- size_mapping:
- legend:
- required_annotations:
- forbidden_elements:
- layout_constraints:
- source_note:
- assumptions:
ルール:
- 数値軸ごとに、
scaleを明示する必要があります(linear、log、symlogなど)。 forbidden_elementsには、回帰直線、対角の基準線、すべての点へのラベル、追加のサイズ凡例、集計など、魅力的に見えても依頼されていない視覚要素を含める必要があります。category_orderは、説明で指定されている場合、その順序を維持する必要があります。指定されていない場合は、明示的に並べ替えが依頼されていない限り、データの順序を維持してください。- 統計量、集計、近似直線、平滑化曲線を導出する場合は、その計算方法を
assumptionsに記載してください。
Step 4: matplotlib の慣用的な書き方を選ぶ
チャートの種類ごとのレシピ(サポート対象のチャートごとに、matplotlib の短いコード例を 1 つずつ)については、references/chart-types.md を参照してください。慣れていない種類で適切な書き方を確認する場合や、トルネード、リング、KDE など、扱いが難しい種類を再確認する場合に読んでください。
Step 5: 出版物向けのデフォルト設定を適用する
サイズ、フォント、パレット、DPI、savefig の規約については、references/publication-style.md を参照してください。説明で明示的に異なる指定がない限り、毎回これらを適用してください。
Step 6: スクリプトを作成して実行する
- スクリプトを作成します。
python plot.pyで実行します。- PNG が生成されたことを確認します。
- スクリプトでエラーが発生した場合は、完了を報告する前に修正して再実行します。
scripts/validate_figure.py が利用可能な場合は、描画後に実行してください(スクリプトのパスは、このスキルのディレクトリからの相対パスです)。
python scripts/validate_figure.py --output-dir <output-dir> --spec <output-dir>/figure-spec.md
Step 7: 結果を監査する
説明をコードおよびデータと照らし合わせて再確認します。エージェントによる PNG の目視確認は信頼性が低いため、代わりに構造を検証してください。
- 説明で求められたタイトル、両方の軸ラベル、凡例を設定しましたか?
- 系列名、順序、色は、説明の指定と一致していますか?
- データ内のピーク/最小値/傾向の位置は、説明と一致していますか(例:「ピークは 0 をわずかに上回る位置」とある場合、データも実際にそこでピークになっていますか)?
- 説明にある個別の要素(グリッド線、基準線、注釈)をすべて含めましたか?
- 説明で削除を求められていない目盛りが消えていませんか?
ax.tick_params(length=0)、set_xticks([])を呼び出したり、軸のスパインを非表示にしたりした場合、説明に照らして正当化できますか?デフォルトでは「目盛りを表示」です。理由なく非表示にするのは不備です。 - 特にヒストグラムでは、x 軸の目盛りはビンの境界です。決して非表示にしないでください。x 軸の目盛りがないヒストグラムは読み取れません。
- 意図的に目盛りを削除した場合(説明でそのように指定されているため)、読みやすさを保つ代替手段(線の端点に直接ラベルを付ける、カラーバーを付ける、値を注釈で示すなど)はありますか?
- 軸の範囲には、説明で指定されたすべての要素が収まっている必要があります。 ブリーフで特定の領域、ラベル付きの点、または値が明示されている場合、
ax.set_xlim/ax.set_ylimにそれらを含める必要があります。指定された要素をチャートから切り落とすような範囲の絞り込みは不備であり、データを黙って除外するのと同じです。
欠落している項目はすべて不備として扱い、スクリプトを修正してください。
監査結果を audit.md に記録します。
# Figure Audit
- script_ran: yes/no
- png_exists: yes/no
- chart_type_matches_spec: pass/fail
- data_columns_match_spec: pass/fail
- axis_scales_match_spec: pass/fail
- labels_units_match_spec: pass/fail
- series_category_order_match_spec: pass/fail
- legend_complete_and_uncropped: pass/fail
- annotations_match_spec: pass/fail
- forbidden_elements_absent: pass/fail
- obvious_text_overlap_or_clipping: pass/fail
- repairs_made:
- remaining_warnings:
- final_status:
必須項目に不合格がある場合は、plot.py を修正して再実行し、監査も再実行してください。必須項目に不合格が残ったままタスクを完了としてはいけません。入力の矛盾や依存関係が利用できないために必須項目を満たせない場合は、final_status: FAILED_NEEDS_HANDOFF に設定し、正確な理由を記載してください。
コア設計ルール
0. スタイリングより忠実性を優先する
優先順位:
- 指定されたデータの意味を一致させます。
- チャートの種類、軸のフィールド、スケール、単位、ラベル、凡例、注釈、カテゴリの順序、視覚的なエンコーディングを一致させます。
- 図を読みやすくします。
- 出版物向けのスタイルを適用します。
出版物向けのスタイルによって、チャートの意味を変えてはいけません。説明で求められている場合、または figure-spec.md で正当化されている場合を除き、見栄えを良くするための視覚要素を追加しないでください。
1. スクリプトは自己完結し、再現可能である必要があります
ユーザーが指定していないものをハードコードしないでください。指定されたパスからデータを読み込み、CSV が存在する場合は数値を作り出さないでください。同じ plot.py であれば、matplotlib がインストールされたどのマシンでも同じ PNG を再生成できるようにします。
2. 説明は意図、CSV は事実です
説明では言い換えや丸めが行われることがあります。説明と CSV の内容が食い違う場合は CSV の内容をプロットしつつ、説明が示す傾向の形(ピークの位置、傾向、順序)は再現してください。食い違いは、データの解析を誤った可能性が高いことを示すサインです。
3. 図は 1 つ、ファイルは 1 つ、保存は 1 回
最後に plt.savefig(...) を 1 回だけ呼び出してください。中間で plt.show() を何度も呼ばないでください(ヘッドレス環境では処理が停止します)。明示的な指示がない限り、複数の図を生成するスクリプトは作成しないでください。
4. シンプルなケースでは matplotlib pyplot を、複雑なレイアウトでは OO インターフェースを使います
単一の Axes なら plt.plot / plt.bar で問題ありません。サブプロット、複数の Y 軸、または Axes ごとのスタイル設定が必要になったら、fig, ax = plt.subplots(...) に切り替え、ax のメソッドを呼び出してください。1 つの図で両方を混在させると、コードが壊れやすくなります。
5. 色には意味があります
説明で色が指定されている場合(「低い値は青、高い値はオレンジ」など)は、それを使用してください。色は読み手に意味を伝えます。指定がない場合は、知覚的に均一なカラーパレットをデフォルトで使います(カテゴリカルデータには tab10、連続データには viridis が適しています)。
6. 装飾ではなく、情報を伝えます
グリッド、目盛り、枠線、注釈は、読み取りやすさに役立つものにしてください。デフォルトではチャートの不要な装飾を取り除きます。多くのプロットでは上と右のスパインを非表示にし(ax.spines[['top','right']].set_visible(False))、値の大きさを比較する場合にのみ、薄い Y 軸グリッドを有効にします。
7. タイトル用の余白を確保します
tight_layout() は、タイトルを Axes の上端で切り取ることがあります。rcParams ブロック(publication-style.md を参照)で "axes.titlepad": 10 を設定するか、ax.set_title(...) に pad=10 を渡してください。タイトルが軸に接していることは、生成された図が「未完成」に見える最も一般的な兆候です。
8. 複数パネルのレイアウトには gridspec を使い、savefig を重ねて使わないでください
成果物は PNG 1 つです。説明で複数のサブプロット(サイドパネル付きのメインチャート、2×2 の比較グリッド、インセット付きのチャートなど)が求められている場合は、fig.add_gridspec(...) を使って 1 つの図にまとめ、savefig を 1 回だけ呼び出します。PNG を複数出力しないでください。評価ハーネスが受け取るのは 1 つだけです。chart-types.md → マルチパネル構成を参照してください。
9. matplotlib の高水準 API を使い、座標計算を独自に実装しないでください
レイアウト、注釈、書式設定のためのヘルパーが matplotlib に用意されている場合は、位置、座標変換、テキストの配置を手作業で計算するのではなく、それらを使ってください。たとえば、データに固定されたサブ Axes には inset_axes、パネル構成には gridspec、棒ごとの値の注釈には bar_label、余白の調整には tight_layout / constrained_layout、軸ラベルの書式設定には ticker.FuncFormatter を使います。高水準のヘルパーは、図のサイズ変更、DPI の変更、その後の subplots_adjust 呼び出しにも対応できますが、座標変換を手作業で行うとレイアウトが少し変わるだけで崩れます。ピクセル単位の計算を書いたり、ax.transData / ax.transAxes を手作業で連結したりしていることに気づいたら、いったん止めて、まず組み込みの機能を探してください。
直感に反する注意点
チャートの種類を示すラベルだけを信じないでください
説明にある「トルネードチャート」は、技術的には横向きのグループ化棒グラフ(カテゴリごとに正負の棒がある形式)かもしれません。作成方法を決める前に、説明が示す形状を読み取り、データの構成と照らし合わせて確認してください。
説明中の数値は概算です
説明では、値が 187.4 のときに「約 200」と書かれていることがあります。187.4 をプロットしてください。明らかに誤っている場合(説明で補正される単位の不一致など)を除き、CSV の値から変更しないでください。
その場しのぎのスタイル設定より、スタイルのデフォルトを優先します
プロットごとに rcParams を調整するたび、図同士を比較しにくい、独自の見た目になってしまいます。publication-style.md の公開用デフォルトを一貫して適用し、説明で求められる場合にのみ、図ごとに上書きしてください。
リファレンスの使い方
| トピック | リファレンスファイル | 使用する場面 |
|---|---|---|
| グラフの種類別レシピ | chart-types.md | 特定のグラフの種類に適した matplotlib の書き方が必要な場合 |
| 論文向けのスタイル | publication-style.md | 図のサイズ、フォント、パレット、DPI、savefig を設定する場合 |