mcpField
A
atmospheric-science-research

atmospheric-science-research

github.com/zsy1207数据与数据库247 次安装1 周前更新
代码仓库

关于 atmospheric-science-research

面向大气科学研究者的技能,用于指导本地大气数据的可复现分析和论文级图表制作。它规定了从元数据检查、计算和绘图,到视觉复核、导出与文档记录的分阶段流程。

主要功能

  1. 01先检查元数据再处理数据
  2. 02可复现的分析工作流
  3. 03大气诊断计算与绘图规范
  4. 04渲染图表的复核与修订
  5. 05导出 600 dpi PNG 和 PDF

适用场景

  1. 01基于本地大气数据开展分析
  2. 02将诊断结果制作成期刊图表
  3. 03复核图表并记录未解决风险

安装

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

$npx skills add https://github.com/zsy1207/atmospheric-science-research --skill atmospheric-science-research

安装后在 Claude Code 中输入/atmospheric-science-research确认已加载。

详细介绍

大气科学研究

在可复现的项目中,对本地大气数据计算诊断指标,并绘制符合期刊标准的图表。

工作流

新分析按步骤 1–7 运行。仅修复图表时使用 Patch Mode。

  1. 探查 — 仅检查元数据:ncdump -h、cdo sinfon、h5dump -H,或用于 Zarr 的仅读取元数据的 Python 单行命令。
  2. 规划 — 只询问会影响结果的科学问题,并为每个问题推荐答案。在计划和 README 中记录所有采纳的假设。
  3. 构建 — 使用 figN/compute_*.py、figN/plot_*.py、data_output/figN/...。除非收到要求,否则不要重组现有项目。
  4. 计算 — 脚本无需必填 CLI 参数即可运行,且具备幂等性;绘图读取输出前,先写入可复用的输出。
  5. 绘图 — 遵循绘图标准。
  6. 审查 — 运行 RR,直到每幅图表都为 PASS 或 BLOCKED。
  7. 导出并记录 — 导出最终文件(绘图标准 › 导出),然后根据 README 模板编写或更新一份中文 README.md。将 BLOCKED 图表和未解决的风险写入风险部分。

计算规则

  • 速度与效率 — 优先使用能提高计算效率的软件包和算法,例如 dask。
  • 重网格 — 对降水和通量使用 cdo remapcon / xesmf "conservative";对平滑状态变量(T、Z、u、v、q)使用 remapbil / "bilinear"。
  • 区域填充 — 子区域边界在目标范围外至少多包含 1 个网格点,以避免地图边缘出现空白。

绘图标准

最终标准以渲染后的 PNG 为准,而非代码参数。根据实际项目和 RR 的检查结果设置以下每个参数;目标是生成可用于顶级大气科学期刊发表的高质量科学图表。

尺寸与字体

图宽为最终印刷宽度:单栏 50–85 mm,双栏 105–170 mm;高度低于 228 mm。因此,字体大小均为印刷字号:面板字母为 12 pt 粗体,面板描述为 10 pt,其他所有内容(刻度、标签、图例、色标、矢量标尺)为 8–9 pt,不得低于 8 pt。

使用 Arial,Helvetica 为备选;修补时保留项目现有字体。Mathtext 使用相同字体,以确保单位直立显示:

plt.rcParams.update({
    "font.family": "sans-serif",
    "font.sans-serif": ["Arial", "Helvetica"],
    "mathtext.default": "regular",
    "mathtext.fontset": "custom",
    "mathtext.rm": "sans",
    "mathtext.it": "sans:italic",
    "mathtext.bf": "sans:bold",
})

Mathtext 上标中的单位:r"W m$^{-2}$"、r"m s$^{-1}$"。绝不使用斜杠表示法。

色图与级别

所有填色字段都使用显式离散 levels。色图只能选自以下白名单(允许使用反转的 _r 版本,例如 RdBu_r,使负值显示为蓝色)。在白名单范围内,选择颜色符合变量惯例的色图:

  • 对于 0 有意义的有符号字段(异常、差异、趋势、回归、相关性,以及原始 ω、涡度、散度、u、v、水汽通量散度、净辐射)→ 发散色图:RdBu、BrBG、bwr、PuOr、PRGn、cmaps.BlueWhiteOrangeRed、cmaps.hotcold_18lev。使用关于 0 对称的 levels,且不包含 0 级别,使中间色带跨越 0 并显示为白色(例如 ±0.5、±1,……);保持色标默认的等宽分级,并将刻度设在级别边界上,这样就不会标注 0。
  • 非异常热浪、降水、湿度和风速字段 → 顺序色图:plasma、YlGnBu、viridis、YlOrRd、cmaps.precip3_16lev。
  • 当数值可能超出 levels 时,使用 extend="both";当一端在物理上有界时,使用 "max" / "min"。
  • 可比较的面板共用 levels、cmap、extend(对于 pcolormesh,使用一个 BoundaryNorm(levels, cmap.N, extend="both"),并令 cmap = plt.get_cmap(name))。绝不按面板自动缩放。根据领域知识设置级别;如果信号显示得过淡或已饱和,检查取值范围并重新设置。
  • 色标:地图下方使用水平色标;独立地图或右侧共用色标使用垂直色标;色标应较窄(aspect 为 25–40),长度不得超过面板组,刻度应少,标签应简短并带单位。每个变量和尺度使用一个共用色标。
布局和面板
  • 始终使用 dpi=600, layout="constrained" 创建图形,以便矢量图例按导出分辨率测量;对于 3 个或更多面板或共用色标的情况,在其中使用 GridSpec / subplot_mosaic。在 GeoAxes 上添加色标后,重新检查间距。
  • 面板字母:在每个面板边框上方的左上角使用小写粗体 a、b、c:ax.text(0, 1.02, "a", transform=ax.transAxes, ha="left", va="bottom", fontweight="bold")。
  • 面板描述:使用不超过 6 个词的名词短语(850 hPa wind、El Niño composite),居中显示:ax.text(0.5, 1.02, "850 hPa wind", transform=ax.transAxes, ha="center", va="bottom")。每行的字母、描述和矢量图例共用同一 y 坐标。
  • 图中不得有 suptitle、图注、默认坐标轴标题、数据标记或说明性文字;解读内容应放在图注或 README 中。
地图
区域投影
全球或以太平洋为中心PlateCarree(central_longitude=180) 或 Robinson
热带和中纬度区域PlateCarree(默认);有充分理由时,中纬度区域可使用 LambertConformal
极地NorthPolarStereo / SouthPolarStereo
  • 数据绘图调用(contourf、contour、pcolormesh、curly_vector、scatter)需指定 transform=ccrs.PlateCarree();如果不指定,坐标会被解读为投影自身的单位,导致场的位置悄然错置。add_geometries 使用 crs=ccrs.PlateCarree();面板文字使用 transform=ax.transAxes。
  • 全球场需要循环点:
    from cartopy.util import add_cyclic
    cyc, cyc_lon = add_cyclic(da.values, x=da["lon"].values, axis=-1)
    
  • 跨越 0° 或 180° 的区域:子集筛选前,使用 assign_coords 将经度转换为 −180–180((da.lon + 180) % 360 - 180)或 0–360(da.lon % 360),然后执行 sortby("lon");仅靠填充无法封闭接缝。
  • ax.coastlines(linewidth=0.8, color="0.2");除非科学上确有需要,否则不绘制国界。
  • gl = ax.gridlines(draw_labels=True, linestyle="--", linewidth=0.6, color="0.5", alpha=0.6);gl.top_labels = gl.right_labels = False。多面板地图仅在左侧列和底部行显示标签:gl.left_labels = col == 0; gl.bottom_labels = row == nrows - 1。
  • 研究区域框:使用红色或蓝色虚线,linewidth 为 1.2–2.0,zorder 较高。
青藏高原掩膜

对于包含青藏高原的地图,在 700 hPa 及以下(700 / 850 / 925 / 1000 hPa),使用 regionmask 掩盖高原上的矢量、等值线和显著性点,保留填色场完整,并在其上绘制灰色多边形。多边形默认的 zorder(1.5)已高于填色层,因此不会出现白色边缘。

from pathlib import Path
import geopandas as gpd, regionmask

tibet = gpd.read_file(Path(__file__).resolve().parents[1] / "data/map/Tibet/Tibet.shp")
on_tp = regionmask.mask_geopandas(tibet, u).notnull()   # True on plateau grid points
u, v = u.where(~on_tp), v.where(~on_tp)                 # same for contour fields and p-values
ax.add_geometries(tibet.geometry, crs=ccrs.PlateCarree(),
                  facecolor="lightgrey", edgecolor="grey", linewidth=0.5)

如果文件缺失,且有地表位势数据,则使用 3000 m 地形等高线;否则将图标记为 BLOCKED。

矢量和等值线

使用 Skyborn 的 curly_vector 绘制风矢量和通量矢量。它会自行对场进行采样,因此不要使用 [::n] 进行子采样。以下数值仅为起始值:在 RR 期间调整密度、箭头长度、线宽和图例,使流场在印刷尺寸下清晰可读。

from skyborn.plot import curly_vector, curly_vector_key

cv = curly_vector(ax, lon, lat, u, v, transform=ccrs.PlateCarree(),
                  density=0.5, ref_magnitude=10, ref_length=0.06,
                  color="#555555", linewidth=0.8, zorder=3)
key = curly_vector_key(ax, cv, U=10, units=r"m s$^{-1}$", labelpos="W",
                       frameon=False, show_description=False,
                       width=0, height=0, padding=0, x=1.0, y=1.02,
                       arrow_props={"color": "#555555", "linewidth": 0.8},
                       text_props={"fontsize": 8})
fig.canvas.draw()                    # after the final layout change
key.x = 1.0 - key.patch.get_width()  # key arrow tip on the map's right edge
  • 传入 ref_magnitude(易于理解的速度值,也是图例中的 U);若不传入,各面板将按各自的最大值缩放。共用一个图例的面板必须等宽,并使用相同的 ref_magnitude 和 ref_length;否则应为每个面板单独设置图例。图例应根据最大速度至少达到 U 的面板生成,因为 Skyborn 会将箭头长度限制在该最大值。对于非 PlateCarree 投影,regrid_shape 可使箭头间距更均匀。
  • 使用 mathtext 传入 units;默认值 "m/s" 不符合单位规则。
  • 在地图外侧右上方放置一个图例,与字母/描述基线对齐,样式与场中的箭头一致。
  • 仅在等值线有助于解读时绘制(零线、阈值)。零等值线使用深色,线宽为 0.8–1.0 pt;其他等值线线宽为 0.4–0.6 pt,并使用适中的 alpha;仅标注选定的等值线。
显著性

应清晰可见,但不能喧宾夺主。默认使用点;根据面板调整点的间距、大小和透明度,并在 RR 期间进行调试。点绝不能合并成深色块,也不能遮挡场。只有在必须区分响应的正负时,才使用低饱和度的红色/蓝色。稀疏的 "." 或 ".." 点状填充(通过 contourf(..., levels=[0, 0.05, 1], hatches=[".", None], colors="none") 实现)也是一种选择。

其他图表类型
  • 时间序列:使用细线;异常值配零线或参考线;用阴影带表示不确定性。
  • 垂直剖面/廓线:压力轴倒置(1000 hPa 在底部);地形填充为灰色。
  • 相关矩阵:使用以 0 为中心的发散色图,范围为 [-1, 1];显著性用点或轮廓表示,不要在每个单元格中都写数值。
  • EOF:使用以 0 为中心的发散地图;PC 归一化并显示零线;在面板说明中注明解释方差;说明符号约定。
  • 散点图/回归图:仅在相关系数 r、斜率或 p 值对结果至关重要时标注。
导出

所有内容均以 600 dpi 渲染。每个绘图脚本都接受可选的 --final 标志:不加该标志时,输出用于 RR 的 PNG;加上该标志时,输出 PNG 和 PDF。

exts = ("png", "pdf") if final else ("png",)
for ext in exts:
    fig.savefig(f"{stem}.{ext}", dpi=600)
plt.close(fig)

如果 PDF 文件过大或渲染缓慢,请对密集图层传入 rasterized=True。

RR 规则

复审(RR)用于检查每张渲染图中的视觉缺陷和明显的数据错误。

  • 每次迭代都要打开渲染后的 PNG;仅检查代码不算完成复审。
  • 对照绘图标准和下方清单检查,然后分类:PASS(没有待处理项)、REVISE(修复所有无需新信息即可解决的可见问题,重新渲染一次,再重复检查)或 BLOCKED(需要用户决定或缺少输入,或者输出无法辨读)。
  • 至少迭代一次才能标记为 PASS,最多迭代 5 次。如果仍未达到 PASS,则标记为 BLOCKED,并在 README 中列出剩余问题。
  • 在此处根据 PNG 调整矢量密度和图例,以及点状显著性标记的间距和大小;绘图代码只设置初始值。
  • 即使没有违反任何规则,只要有不符合顶级大气科学期刊风格之处,都应修改。
检查项通过标准
文本使用 Arial 或项目字体;单位使用 mathtext;没有裁切内容或小于 8 pt 的文字;没有总标题、图注或解释性文字
面板面板字母为粗体,说明简短且居中,矢量图例与其位于同一基线上
色图使用白名单中的色图并显式指定 levels;具有明确零值的有符号场使用以 0 为中心的发散色图,否则使用顺序色图;设置 extend;可比较的面板共用同一色标范围
地图显示海岸线和经纬度标签;没有日期变更线接缝或空白边框
西藏在 700 hPa 及以下,不得在高原上显示箭头、等值线或点;绘制灰色多边形
矢量密度清晰易读;右上角设置一个图例,箭头端点位于右边缘
显著性清晰可见,但不能喧宾夺主
布局面板平衡;色标窄;没有重叠
物理合理性数值、单位和正负号合理;压力轴倒置
整体符合顶级大气科学期刊发表标准的高质量科学图表

README 模板

每张图均为 PASS 或 BLOCKED 后,编写一份中文 README.md。按项目实际布局编写;不要为了套用模板而重组项目。

# 项目说明

简要说明科学目标和主要工作内容。

## 1. 数据简述

- 输入数据路径:
- 数据来源与类型:
- 时间范围:
- 空间范围与分辨率:

## 2. 路径结构和实现功能

- `data_output/fig1/xxx.nc`:实现功能
- `fig1/compute_xxx.py`:实现功能
- `fig1/plot_xxx.py`:实现功能
- `fig1/fig1_xxx.png`、`fig1/fig1_xxx.pdf`:实现功能

## 3. 实现算法与细节

- 采用的假设与默认选择:逐条列出用户确认的选择和可逆的默认设置,算法简单时也要写。
- 算法如无需展开,可写:`本任务算法直接,省略。`
- 若有复杂处理,写清关键公式、统计方法、重网格方案和加速策略。

## 4. 可能存在的问题与风险

- 列出 `BLOCKED` 的图、原因和剩余问题,以及其他未解决的风险。
- 无则写:`目前无明显问题。`

## 5. 图片简述

- 以大气科学论文写作口径,专业、简洁地说明每张图的内容与意义。

## 6. 版本更新

- (更新时填写日期、变更内容、影响文件)

后续修改(包括 Patch Mode)时,在「版本更新」中追加记录,并仅更新受影响的路径和图表部分。

Patch Mode

阅读现有代码,进行最小且安全的修改,仅重新渲染受影响的图表,执行 RR、导出,并在 README 中追加一条「版本更新」记录。

如果 RR 发现计算错误(变量错误、单位错误或气候基准错误),请停止修补并从步骤 2 重新开始。

评论

支持 Markdown