关于 atmospheric-science-research
面向大气科学研究者的技能,用于指导本地大气数据的可复现分析和论文级图表制作。它规定了从元数据检查、计算和绘图,到视觉复核、导出与文档记录的分阶段流程。
主要功能
- 01先检查元数据再处理数据
- 02可复现的分析工作流
- 03大气诊断计算与绘图规范
- 04渲染图表的复核与修订
- 05导出 600 dpi PNG 和 PDF
适用场景
- 01基于本地大气数据开展分析
- 02将诊断结果制作成期刊图表
- 03复核图表并记录未解决风险
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ zsy1207/ atmospheric-science-research --skill atmospheric-science-research安装后在 Claude Code 中输入/atmospheric-science-research确认已加载。
详细介绍
大气科学研究
在可复现的项目中,对本地大气数据计算诊断指标,并绘制符合期刊标准的图表。
工作流
新分析按步骤 1–7 运行。仅修复图表时使用 Patch Mode。
- 探查 — 仅检查元数据:
ncdump -h、cdo sinfon、h5dump -H,或用于 Zarr 的仅读取元数据的 Python 单行命令。 - 规划 — 只询问会影响结果的科学问题,并为每个问题推荐答案。在计划和 README 中记录所有采纳的假设。
- 构建 — 使用
figN/compute_*.py、figN/plot_*.py、data_output/figN/...。除非收到要求,否则不要重组现有项目。 - 计算 — 脚本无需必填 CLI 参数即可运行,且具备幂等性;绘图读取输出前,先写入可复用的输出。
- 绘图 — 遵循绘图标准。
- 审查 — 运行 RR,直到每幅图表都为
PASS或BLOCKED。 - 导出并记录 — 导出最终文件(绘图标准 › 导出),然后根据 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 重新开始。