mcpField
M
matplotlib-visualization

matplotlib-visualization

github.com/soljourner数据与数据库9543 次安装51 周前更新
代码仓库

关于 matplotlib-visualization

面向工程师和 CFD 使用者的 Matplotlib 绘图参考技能,涵盖泵曲线、流场可视化、图表样式与高分辨率导出。

主要功能

  1. 01绘制泵与系统性能曲线
  2. 02绘制 CFD 等值图和矢量场
  3. 03制作 3D 曲面与多面板图
  4. 04设置出版样式和 LaTeX 标签
  5. 05导出高分辨率图像

适用场景

  1. 01绘制泵的扬程、功率和效率曲线
  2. 02可视化 CFD 速度或压力场
  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()

另请参阅

评论

支持 Markdown