mcpField
M
matplotlib-visualization

matplotlib-visualization

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

matplotlib-visualization について

エンジニアや CFD 利用者向けの、Matplotlib による工学プロット作成のリファレンススキルです。ポンプ曲線、流れ場の可視化、図のスタイル設定、高解像度出力を扱います。

主な機能

  1. 01ポンプ・システム性能曲線の作成
  2. 02CFD 等高線図とベクトル場の描画
  3. 033D 曲面図と複数パネル図の作成
  4. 04出版向けスタイルと LaTeX ラベル設定
  5. 05高解像度画像の出力

活用シーン

  1. 01ポンプの揚程・動力・効率の作図
  2. 02CFD の速度場や圧力場の可視化
  3. 03出版向け工学図表の準備

インストール

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

$npx skills add https://github.com/soljourner/claude-engineering-skills --skill matplotlib-visualization

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

同梱ファイルexamples.pyreference.md

詳細

エンジニアリング向け Matplotlib ビジュアライゼーション

ポンプ性能曲線、CFD 結果の可視化、速度コンター、出版品質の図など、プロフェッショナルなエンジニアリング用プロットを作成できます。

インストールとセットアップ

pip install matplotlib numpy scipy

基本的なインポート方法:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D

# Set style for professional figures
plt.style.use('seaborn-v0_8-darkgrid')  # or 'classic', 'bmh', 'ggplot'

エンジニアリングでよく使われるプロットの種類

ポンプ性能曲線(H-Q、P-Q、η-Q)

流量に対する揚程、動力、効率を示す標準的なポンプ特性曲線:

import matplotlib.pyplot as plt
import numpy as np

# Sample pump data
Q = np.linspace(0, 120, 50)  # Flow rate [m³/h]
H = 80 - 0.005 * Q**2  # Head [m]
P = 5 + 0.08 * Q + 0.0005 * Q**2  # Power [kW]
eta = (Q * H) / (367 * P) * 100  # Efficiency [%]

# Create figure with three subplots
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(10, 10), sharex=True)

# Head-Flow curve
ax1.plot(Q, H, 'b-', linewidth=2, label='Head curve')
ax1.set_ylabel('Head [m]', fontsize=12)
ax1.set_title('Pump Performance Curves', fontsize=14, fontweight='bold')
ax1.grid(True, alpha=0.3)
ax1.legend()

# Power-Flow curve
ax2.plot(Q, P, 'r-', linewidth=2, label='Power curve')
ax2.set_ylabel('Power [kW]', fontsize=12)
ax2.grid(True, alpha=0.3)
ax2.legend()

# Efficiency-Flow curve
ax3.plot(Q, eta, 'g-', linewidth=2, label='Efficiency curve')
ax3.set_xlabel('Flow Rate [m³/h]', fontsize=12)
ax3.set_ylabel('Efficiency [%]', fontsize=12)
ax3.grid(True, alpha=0.3)
ax3.legend()

plt.tight_layout()
plt.savefig('pump_curves.png', dpi=300, bbox_inches='tight')
plt.show()
系統曲線

ポンプ曲線に系統曲線を重ねて、運転点を特定します:

# Pump curve
Q = np.linspace(0, 120, 50)
H_pump = 80 - 0.005 * Q**2

# System curve: H = H_static + k*Q²
H_static = 20  # Static head [m]
k = 0.003  # System resistance coefficient
H_system = H_static + k * Q**2

fig, ax = plt.subplots(figsize=(10, 6))

ax.plot(Q, H_pump, 'b-', linewidth=2, label='Pump curve')
ax.plot(Q, H_system, 'r--', linewidth=2, label='System curve')

# Find and mark operating point
idx = np.argmin(np.abs(H_pump - H_system))
ax.plot(Q[idx], H_pump[idx], 'ko', markersize=10, label=f'Operating point\n({Q[idx]:.1f} m³/h, {H_pump[idx]:.1f} m)')

ax.set_xlabel('Flow Rate [m³/h]', fontsize=12)
ax.set_ylabel('Head [m]', fontsize=12)
ax.set_title('Pump and System Curves', fontsize=14, fontweight='bold')
ax.grid(True, alpha=0.3)
ax.legend(fontsize=10)

plt.tight_layout()
plt.savefig('system_curve.png', dpi=300, bbox_inches='tight')
plt.show()
速度/圧力コンター

コンタープロットで CFD 結果を可視化します:

import matplotlib.pyplot as plt
import numpy as np

# Create mesh grid
x = np.linspace(0, 10, 100)
y = np.linspace(0, 5, 50)
X, Y = np.meshgrid(x, y)

# Example velocity field (flow around obstacle)
U = 2.0 - 1.5 * np.exp(-((X-3)**2 + (Y-2.5)**2) / 2)
V = 0.5 * np.sin(np.pi * X / 5) * np.exp(-((X-3)**2 + (Y-2.5)**2) / 4)
velocity = np.sqrt(U**2 + V**2)

fig, ax = plt.subplots(figsize=(12, 6))

# Filled contours
levels = np.linspace(velocity.min(), velocity.max(), 20)
contourf = ax.contourf(X, Y, velocity, levels=levels, cmap='jet')
cbar = plt.colorbar(contourf, ax=ax, label='Velocity [m/s]')

# Optional: Add contour lines
contour = ax.contour(X, Y, velocity, levels=10, colors='k', linewidths=0.5, alpha=0.4)
ax.clabel(contour, inline=True, fontsize=8, fmt='%.2f')

ax.set_xlabel('x [m]', fontsize=12)
ax.set_ylabel('y [m]', fontsize=12)
ax.set_title('Velocity Contour Plot', fontsize=14, fontweight='bold')
ax.set_aspect('equal')

plt.tight_layout()
plt.savefig('velocity_contour.png', dpi=300, bbox_inches='tight')
plt.show()
ベクトル場

流れの方向と大きさを表示します:

import matplotlib.pyplot as plt
import numpy as np

# Create coarser grid for vectors
x = np.linspace(0, 10, 20)
y = np.linspace(0, 5, 10)
X, Y = np.meshgrid(x, y)

# Velocity components
U = 2.0 - 1.5 * np.exp(-((X-3)**2 + (Y-2.5)**2) / 2)
V = 0.5 * np.sin(np.pi * X / 5) * np.exp(-((X-3)**2 + (Y-2.5)**2) / 4)
velocity = np.sqrt(U**2 + V**2)

fig, ax = plt.subplots(figsize=(12, 6))

# Quiver plot with color by magnitude
quiver = ax.quiver(X, Y, U, V, velocity, cmap='viridis', scale=30, width=0.003)
cbar = plt.colorbar(quiver, ax=ax, label='Velocity magnitude [m/s]')

ax.set_xlabel('x [m]', fontsize=12)
ax.set_ylabel('y [m]', fontsize=12)
ax.set_title('Velocity Vector Field', fontsize=14, fontweight='bold')
ax.set_aspect('equal')

plt.tight_layout()
plt.savefig('velocity_vectors.png', dpi=300, bbox_inches='tight')
plt.show()
3D サーフェスプロット

圧力または温度分布を可視化します:

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

# Create mesh
x = np.linspace(-5, 5, 50)
y = np.linspace(-5, 5, 50)
X, Y = np.meshgrid(x, y)

# Example: Pressure distribution
Z = 100 + 10 * np.exp(-0.1 * (X**2 + Y**2)) * np.cos(0.5 * np.sqrt(X**2 + Y**2))

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

# Surface plot
surf = ax.plot_surface(X, Y, Z, cmap='coolwarm', linewidth=0, antialiased=True, alpha=0.9)

# Customize
ax.set_xlabel('x [m]', fontsize=11)
ax.set_ylabel('y [m]', fontsize=11)
ax.set_zlabel('Pressure [kPa]', fontsize=11)
ax.set_title('Pressure Distribution', fontsize=14, fontweight='bold', pad=20)

# Add colorbar
cbar = fig.colorbar(surf, ax=ax, shrink=0.5, aspect=5, label='Pressure [kPa]')

# Set viewing angle
ax.view_init(elev=25, azim=45)

plt.tight_layout()
plt.savefig('pressure_3d.png', dpi=300, bbox_inches='tight')
plt.show()
サブプロットとマルチパネル図

詳細な分析に向けた複雑なレイアウト:

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(figsize=(14, 10))

# Create 2x2 grid
gs = fig.add_gridspec(2, 2, hspace=0.3, wspace=0.3)

# Subplot 1: Line plot
ax1 = fig.add_subplot(gs[0, 0])
x = np.linspace(0, 100, 100)
y1 = 80 - 0.005 * x**2
ax1.plot(x, y1, 'b-', linewidth=2)
ax1.set_xlabel('Flow Rate [m³/h]')
ax1.set_ylabel('Head [m]')
ax1.set_title('(a) Pump Curve')
ax1.grid(True, alpha=0.3)

# Subplot 2: Contour
ax2 = fig.add_subplot(gs[0, 1])
x = np.linspace(0, 10, 50)
y = np.linspace(0, 5, 25)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
contourf = ax2.contourf(X, Y, Z, levels=15, cmap='RdBu_r')
plt.colorbar(contourf, ax=ax2, label='Value')
ax2.set_xlabel('x [m]')
ax2.set_ylabel('y [m]')
ax2.set_title('(b) Contour Plot')

# Subplot 3: Bar chart
ax3 = fig.add_subplot(gs[1, 0])
categories = ['Case 1', 'Case 2', 'Case 3', 'Case 4']
values = [75, 82, 68, 91]
bars = ax3.bar(categories, values, color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'])
ax3.set_ylabel('Efficiency [%]')
ax3.set_title('(c) Performance Comparison')
ax3.grid(True, axis='y', alpha=0.3)

# Subplot 4: Scatter with trend
ax4 = fig.add_subplot(gs[1, 1])
x_data = np.random.rand(50) * 100
y_data = 30 + 0.5 * x_data + np.random.randn(50) * 5
ax4.scatter(x_data, y_data, alpha=0.6, s=50)
# Add trend line
z = np.polyfit(x_data, y_data, 1)
p = np.poly1d(z)
ax4.plot(x_data, p(x_data), 'r--', linewidth=2, label=f'y={z[0]:.2f}x+{z[1]:.2f}')
ax4.set_xlabel('Parameter X')
ax4.set_ylabel('Parameter Y')
ax4.set_title('(d) Correlation Analysis')
ax4.legend()
ax4.grid(True, alpha=0.3)

plt.suptitle('Multi-Panel Engineering Analysis', fontsize=16, fontweight='bold', y=0.995)

plt.savefig('multipanel.png', dpi=300, bbox_inches='tight')
plt.show()

プロフェッショナルな図のスタイリング

スタイルシートの使用
# Available styles
import matplotlib.pyplot as plt
print(plt.style.available)

# Apply a style
plt.style.use('seaborn-v0_8-whitegrid')

# Or create custom style
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.size'] = 11
plt.rcParams['axes.linewidth'] = 1.5
plt.rcParams['lines.linewidth'] = 2
plt.rcParams['grid.alpha'] = 0.3
カスタムカラーとスタイリング
# Professional color schemes
colors_engineering = {
    'blue': '#0072BD',
    'red': '#D95319',
    'yellow': '#EDB120',
    'purple': '#7E2F8E',
    'green': '#77AC30',
    'cyan': '#4DBEEE',
    'maroon': '#A2142F'
}

# Apply to plots
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, y1, color=colors_engineering['blue'], linewidth=2.5, label='Series 1')
ax.plot(x, y2, color=colors_engineering['red'], linewidth=2.5, label='Series 2')
ラベルでの LaTeX の使用

数式をレンダリングするために LaTeX を有効にします:

import matplotlib.pyplot as plt
import numpy as np

# Enable LaTeX
plt.rcParams['text.usetex'] = False  # Set True if LaTeX installed
plt.rcParams['mathtext.fontset'] = 'cm'  # Computer Modern font

fig, ax = plt.subplots(figsize=(10, 6))

x = np.linspace(0, 100, 100)
y = 80 - 0.005 * x**2

ax.plot(x, y, 'b-', linewidth=2)

# Use raw strings with LaTeX syntax
ax.set_xlabel(r'Flow Rate $Q$ [m$^3$/h]', fontsize=13)
ax.set_ylabel(r'Head $H$ [m]', fontsize=13)
ax.set_title(r'Pump Curve: $H = H_0 - k Q^2$', fontsize=14, fontweight='bold')

# Greek letters and equations
ax.text(50, 60, r'$\eta = \frac{Q \cdot H \cdot \rho \cdot g}{P_{shaft}}$',
        fontsize=16, bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))

ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
よく使われるエンジニアリング記号
# Flow rate: Q, $\dot{m}$, $\dot{V}$
# Pressure: p, P, $\Delta p$
# Temperature: T, $\theta$
# Velocity: v, u, V, $\vec{v}$
# Density: $\rho$
# Viscosity: $\mu$, $\nu$
# Efficiency: $\eta$
# Power: P, $\dot{W}$
# Energy: E, $\dot{E}$
# Reynolds number: $Re = \frac{\rho v D}{\mu}$

高解像度プロットの保存

各種フォーマット
# PNG - raster, good for web
plt.savefig('figure.png', dpi=300, bbox_inches='tight', facecolor='white')

# PDF - vector, good for publications
plt.savefig('figure.pdf', bbox_inches='tight', facecolor='white')

# SVG - vector, editable in Inkscape/Illustrator
plt.savefig('figure.svg', bbox_inches='tight', facecolor='white')

# EPS - vector, required by some journals
plt.savefig('figure.eps', format='eps', bbox_inches='tight')

# TIFF - raster, required by some journals
plt.savefig('figure.tiff', dpi=600, bbox_inches='tight', facecolor='white')
DPI の推奨値
  • 画面表示:72-96 DPI
  • プレゼンテーション:150 DPI
  • 印刷/出版:300-600 DPI
  • ポスター:150-300 DPI(閲覧距離によって異なります)
図のサイズの目安
# Single column (journal): 3.5 inches width
fig, ax = plt.subplots(figsize=(3.5, 2.5))

# Double column (journal): 7 inches width
fig, ax = plt.subplots(figsize=(7, 5))

# Presentation (16:9):
fig, ax = plt.subplots(figsize=(12, 6.75))

# Presentation (4:3):
fig, ax = plt.subplots(figsize=(10, 7.5))

# Poster:
fig, ax = plt.subplots(figsize=(14, 10))

ベストプラクティス

  1. 軸には必ずラベルを付け、単位を角括弧で示します:[m/s]、[kPa]、[°C]
  2. 関連する図では一貫した色を使用します
  3. 複数の系列をプロットする場合は凡例を追加します
  4. 見やすさを高めるため、alpha を低く(0.3)してグリッド線を使用します
  5. 適切な線幅(メインプロットでは 2-2.5)に設定します
  6. 適切なカラーマップを選択します:
    • 逐次型:viridis、plasma、inferno(一般的なデータ)
    • 発散型:RdBu_r、coolwarm(重要な中間値を持つデータ)
    • 質的:tab10、Set1(カテゴリーデータ)
  7. ラベルが切り取られないよう、tight_layout() または bbox_inches='tight' を使用します
  8. show() の前に保存します。表示すると図がクリアされる場合があります
  9. メモリを解放するため、保存後に図を閉じます:plt.close()
  10. CFD 結果では、桁違いの値を扱う量に対して対数スケールの使用を検討します

クイックリファレンス

# Figure and axes
fig, ax = plt.subplots(figsize=(width, height))

# Line plot
ax.plot(x, y, 'b-', linewidth=2, label='Label', marker='o', markersize=5)

# Scatter plot
ax.scatter(x, y, c=colors, s=sizes, alpha=0.6, cmap='viridis')

# Contour plot
contourf = ax.contourf(X, Y, Z, levels=20, cmap='jet')
plt.colorbar(contourf, ax=ax, label='Label')

# Quiver plot
quiver = ax.quiver(X, Y, U, V, scale=50)

# Labels and title
ax.set_xlabel('Label [unit]', fontsize=12)
ax.set_ylabel('Label [unit]', fontsize=12)
ax.set_title('Title', fontsize=14, fontweight='bold')

# Grid and legend
ax.grid(True, alpha=0.3)
ax.legend(loc='best', fontsize=10)

# Limits
ax.set_xlim([xmin, xmax])
ax.set_ylim([ymin, ymax])

# Log scale
ax.set_xscale('log')
ax.set_yscale('log')

# Save
plt.tight_layout()
plt.savefig('figure.png', dpi=300, bbox_inches='tight')
plt.show()

関連項目

コメント