mcpField
M
matplotlib

matplotlib

github.com/tondevrelデータ・データベース24374 回インストール39 週間前に更新
リポジトリ

matplotlib について

matplotlib は、Matplotlib ライブラリで 2D および基本的な 3D グラフを作成・調整するためのスキルガイドです。図を細かく制御したいデータ分析者や研究者向けで、探索、レポート、論文、独自の可視化ツールに使えます。

主な機能

  1. 01折れ線・散布図・棒グラフ・ヒストグラム
  2. 02ヒートマップ・等高線・ベクトル場
  3. 03複数パネルのレイアウト
  4. 04スタイルと軸の細かな調整
  5. 05印刷・Web 向け形式での出力

活用シーン

  1. 01科学論文用の図表作成
  2. 02誤差範囲付きの複数データ比較
  3. 03相関や分布の可視化
  4. 04GUI やレポートへのグラフ埋め込み

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/tondevrel/scientific-agent-skills --skill matplotlib

インストール後、Claude Code で/matplotlibを入力して読み込まれたか確認します。

詳細

Matplotlib - データ可視化

2D(および基本的な3D)プロットで最も広く使用されているライブラリです。線のスタイルから軸のスパインまで、図のあらゆる要素を完全に制御できます。

使用する場面

  • 出版品質の2Dプロット(折れ線、散布図、棒グラフ、ヒストグラム)の作成
  • 科学データ(ヒートマップ、等高線、ベクトル場)の可視化
  • 複雑な複数パネルの図の生成
  • 論文やレポート向けのプロットの微調整(LaTeX対応)
  • カスタム可視化ツールやダッシュボードの構築
  • NumPy配列やPandas DataFrameからのデータの直接プロット

リファレンスドキュメント

公式ドキュメント:https://matplotlib.org/stable/index.html
ギャラリー:https://matplotlib.org/stable/gallery/index.html(例を探すのに最適です)
検索パターン:plt.subplots、ax.set_title、ax.legend、plt.savefig、matplotlib.colors

基本原則

2つのインターフェース:適切に選択しましょう
インターフェース方法用途
オブジェクト指向(OO)fig, ax = plt.subplots()推奨。複雑で再現可能なプロットに最適です。
Pyplot(状態ベース)plt.plot(x, y)手早い対話的な確認に適しています。スクリプトやモジュールでは避けてください。
Matplotlibを使う場面
  • 図のレイアウトを高度に制御する場合。
  • 出版向けにスタイルを正確に調整する場合。
  • GUIアプリケーションにプロットを埋め込む場合。
使用しない場面
  • 対話型のWebダッシュボード(PlotlyまたはBokehを使用してください)。
  • 手早い統計的なデータ探索(Seabornを使用してください。Matplotlibをベースにしていますが、統計用途ではより簡単です)。
  • リアルタイムでの非常に大きなデータセット(100万点超)の処理(DatashaderまたはVisPyを使用してください)。

クイックリファレンス

インストール
pip install matplotlib
標準的なインポート
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib import gridspec
基本パターン - OOインターフェース(「正しい」方法)
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)

# 1. Create Figure and Axis objects
fig, ax = plt.subplots(figsize=(8, 5))

# 2. Plot data
ax.plot(x, y, label='Sine Wave', color='tab:blue', linewidth=2)

# 3. Customize
ax.set_xlabel('Time (s)')
ax.set_ylabel('Amplitude')
ax.set_title('Oscillation Example')
ax.legend()
ax.grid(True, linestyle='--')

# 4. Show or Save
plt.show()
# fig.savefig('plot.pdf', dpi=300, bbox_inches='tight')

重要なルール

✅ 推奨事項
  • OOインターフェース(ax.method())を使用してください。複数のプロットを扱うスクリプトでのエラーを防げます。
  • bbox_inches='tight'を使用してください。保存時にラベルが切れないようにできます。
  • dpiを設定してください。印刷用には300以上、Web用には72~100を使用してください。
  • 図を閉じてください。メモリーリークを避けるため、ループ内ではplt.close('all')を使用してください。
  • すべてにラベルを付けてください。各軸にはラベルと単位が必要です。
  • ベクター形式を使用してください。学術論文では.pdfまたは.svgで保存してください(拡大縮小しても劣化しません)。
  • 色覚に配慮した配色を使用してください。カラーマップにはtab10またはviridisを使用してください。
❌ 禁止事項
  • plt.とax.を混在させないでください。「隠れた状態」によるバグにつながります。
  • ループ内でplt.show()を使用しないでください。実行がブロックされるため、代わりにfig.savefig()を使用してください。
  • 凡例の位置を手動で指定しないでください。まずはax.legend(loc='best')に任せてください。
  • フォントサイズをハードコードしないでください。一貫性を保つためにplt.rcParams.update({'font.size': 12})を使用してください。
  • 「Rainbow」(Jet)を使用しないでください。誤った勾配が生じるため、magmaやinfernoなど、知覚的に均一なカラーマップを使用してください。

アンチパターン(絶対に避ける)

# ❌ BAD: Mixing interfaces (State-based + OO)
plt.figure()
ax = plt.gca()
plt.plot(x, y) # Confusing state
ax.set_title('Test')

# ✅ GOOD: Consistent OO interface
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_title('Test')

# ❌ BAD: Overlapping subplots
fig, axs = plt.subplots(2, 2)
# Plots look squashed and titles overlap

# ✅ GOOD: Use constrained_layout or tight_layout
fig, axs = plt.subplots(2, 2, constrained_layout=True)

プロットの構成

ラベル、目盛り、スタイル
fig, ax = plt.subplots()

ax.plot(x, y, 'o-', color='red', markersize=4, alpha=0.7)

# Explicitly setting limits
ax.set_xlim(0, 10)
ax.set_ylim(-1.5, 1.5)

# Controlling Ticks
ax.set_xticks([0, 2.5, 5, 7.5, 10])
ax.set_xticklabels(['Start', '1/4', 'Mid', '3/4', 'End'])

# Spines (Box around the plot)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# Adding text and arrows
ax.annotate('Local Max', xy=(1.5, 1), xytext=(3, 1.2),
             arrowprops=dict(facecolor='black', shrink=0.05))

高度なレイアウト

サブプロットとGridSpec
# Simple 2x2 grid
fig, axs = plt.subplots(2, 2, figsize=(10, 10))
axs[0, 0].plot(x, y) # Top left
axs[1, 1].scatter(x, y) # Bottom right

# Complex grid (Uneven sizes)
fig = plt.figure(figsize=(10, 6))
gs = gridspec.GridSpec(2, 2, width_ratios=[2, 1], height_ratios=[1, 2])

ax1 = fig.add_subplot(gs[0, 0]) # Top left (large width)
ax2 = fig.add_subplot(gs[0, 1]) # Top right
ax3 = fig.add_subplot(gs[1, :]) # Bottom spanning all columns

科学向けのプロット形式

ヒートマップとカラーバー
data = np.random.rand(10, 10)

fig, ax = plt.subplots()
im = ax.imshow(data, cmap='viridis', interpolation='nearest')

# Add colorbar
cbar = fig.colorbar(im, ax=ax, label='Intensity [a.u.]')

# Proper alignment of colorbar
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
fig.colorbar(im, cax=cax)
ヒストグラムとエラーバー
# Histogram
data = np.random.normal(0, 1, 1000)
ax.hist(data, bins=30, density=True, alpha=0.6, color='g', edgecolor='black')

# Error bars
x = np.arange(10)
y = x**2
yerr = np.sqrt(y)
ax.errorbar(x, y, yerr=yerr, fmt='o', capsize=5, label='Data with noise')
3Dプロット
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

surf = ax.plot_surface(X, Y, Z, cmap='coolwarm', linewidth=0, antialiased=False)
fig.colorbar(surf, shrink=0.5, aspect=5)

出版向けの書式設定

LaTeXとRcParamsの使用
# Global styling
plt.style.use('seaborn-v0_8-paper') # or 'ggplot', 'bmh'

# LaTeX for labels
plt.rcParams.update({
    "text.usetex": True,
    "font.family": "serif",
    "font.serif": ["Computer Modern Roman"],
    "axes.labelsize": 14,
})

fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_xlabel(r'$\alpha_{i} + \beta \sin(\omega t)$') # LaTeX string

実践的なワークフロー

1. 複数データセットの比較ワークフロー
def plot_comparison(datasets, labels):
    fig, ax = plt.subplots(figsize=(10, 6))
    colors = plt.cm.viridis(np.linspace(0, 1, len(datasets)))
    
    for data, label, color in zip(datasets, labels, colors):
        ax.plot(data['x'], data['y'], label=label, color=color, lw=1.5)
        ax.fill_between(data['x'], data['y']-data['std'], data['y']+data['std'], 
                        alpha=0.2, color=color)
    
    ax.set_title('Experiment Results Comparison')
    ax.legend(frameon=False)
    return fig, ax
2. リアルタイムデータの監視(対話型)
# Use this in a Jupyter environment or script
plt.ion() # Interactive mode on
fig, ax = plt.subplots()
line, = ax.plot([], [])

for i in range(100):
    new_data = np.random.rand(10)
    line.set_data(np.arange(len(new_data)), new_data)
    ax.relim()
    ax.autoscale_view()
    fig.canvas.draw()
    fig.canvas.flush_events()
    plt.pause(0.1)
3. クラスターマップ/相関行列の作成
import pandas as pd

df = pd.DataFrame(np.random.rand(10, 4), columns=['A', 'B', 'C', 'D'])
corr = df.corr()

fig, ax = plt.subplots()
im = ax.imshow(corr, cmap='RdBu_r', vmin=-1, vmax=1)
ax.set_xticks(np.arange(len(corr.columns)), labels=corr.columns)
ax.set_yticks(np.arange(len(corr.index)), labels=corr.index)

# Loop over data dimensions and create text annotations.
for i in range(len(corr.index)):
    for j in range(len(corr.columns)):
        text = ax.text(j, i, f"{corr.iloc[i, j]:.2f}",
                       ha="center", va="center", color="black")

パフォーマンスの最適化

大規模データのプロット
# 1. Use 'agg' backend for non-interactive rendering
import matplotlib
matplotlib.use('Agg')

# 2. Use PathCollection for scatter plots with many points
ax.scatter(x, y, s=1) # slow for 1M points

# 3. Use marker='' (none) and only lines for speed
ax.plot(x, y, marker=None)

# 4. Decimate data before plotting
ax.plot(x[::10], y[::10]) # Plot every 10th point

よくある問題と解決策

日付/時刻軸の問題
# ❌ Problem: Dates look like a black blob
# ✅ Solution: Use AutoDateLocator and AutoDateFormatter
import matplotlib.dates as mdates

fig, ax = plt.subplots()
ax.plot(dates, values)
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
fig.autofmt_xdate() # Rotates labels
1つのプロットに複数の凡例を表示する
# ❌ Problem: Calling ax.legend() twice replaces the first one
# ✅ Solution: Manually add the first artist back
fig, ax = plt.subplots()
line1, = ax.plot([1, 2], [1, 2], label='Line 1')
line2, = ax.plot([1, 2], [2, 1], label='Line 2')

first_legend = ax.legend(handles=[line1], loc='upper left')
ax.add_artist(first_legend) # Add back
ax.legend(handles=[line2], loc='lower right')
画像の保存品質(クリッピング)
# ❌ Problem: Legend or Axis title is cut off in the .png file
# ✅ Solution:
fig.savefig('output.png', bbox_inches='tight')

ベストプラクティス

  1. スクリプトやモジュールでは常に OO インターフェース(fig, ax = plt.subplots())を使用します
  2. 用途に適した形式で図を保存します - 論文には PDF/SVG、Web には PNG を使用します
  3. 適切な DPI を設定します - 印刷用は 300 以上、画面表示用は 72~100 にします
  4. 保存時にクリッピングを防ぐため、bbox_inches='tight' を使用します
  5. メモリーリークを防ぐため、ループ内では図を閉じます
  6. 色覚多様性に配慮したカラーマップを使用します - 'jet' は避け、'viridis'、'plasma'、'inferno' を優先します
  7. すべての軸にわかりやすい名前と単位を付けます
  8. サブプロットの重なりを防ぐため、constrained_layout=True を使用します
  9. 一貫性を保つため、plt.rcParams でグローバルスタイルを設定します
  10. 最終版を確定する前に、出力対象の解像度でプロットをテストします

コメント