mcpField
M
matplotlib

matplotlib

github.com/tondevrel数据与数据库24374 次安装39 周前更新
代码仓库

关于 matplotlib

matplotlib 是使用 Matplotlib 创建和调整二维及基础三维图表的技能指南,面向需要精细控制图表的数据分析者和研究人员,可用于探索、报告、论文及自定义可视化工具。

主要功能

  1. 01折线、散点、条形图和直方图
  2. 02热图、等高线和矢量场
  3. 03多面板图表布局
  4. 04精细调整样式与坐标轴
  5. 05导出印刷和网页格式

适用场景

  1. 01制作科学论文图表
  2. 02带误差范围地比较多组数据
  3. 03绘制相关性或分布图
  4. 04在 GUI 或报告中嵌入图表

安装

复制下面的命令,在终端中运行。

$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

核心原则

两种接口:谨慎选择
接口方法用例
面向对象(OO)fig, ax = plt.subplots()推荐。最适合创建复杂、可复现的图表。
Pyplot(基于状态)plt.plot(x, y)快速交互式检查。避免在脚本/模块中使用。
适合使用 Matplotlib 的场景
  • 高层次控制图形布局。
  • 为出版物精确设置样式。
  • 在 GUI 应用程序中嵌入图表。
不要用于
  • 交互式 Web 仪表板(使用 Plotly 或 Bokeh)。
  • 快速统计探索(使用 Seaborn——它基于 Matplotlib 构建,但更适合统计分析)。
  • 实时绘制超大型数据集(>1M 个点)(使用 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}) 保持一致。
  • 使用“彩虹”(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
单个图表中的多个图例
# ❌ 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. 脚本和模块始终使用面向对象接口(fig, ax = plt.subplots())
  2. 使用合适的格式保存图表——出版物使用 PDF/SVG,网页使用 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. 在目标分辨率下测试图表,再定稿

评论

支持 Markdown