绘图Skill:二维伪彩色云图绘制
概述
基于 Matplotlib 的高质量二维伪彩色图(contourf / pcolormesh)绘制工具,专用于科研论文中的空间分布、浓度场、温度场等数据可视化。
支持特性:
- 线性或对数色标(LogNorm)、自定义分段 colormap
- 陆地/无效值掩膜处理
- 经纬度格式化输出(°E / °N)
- 一键生成符合期刊要求的图片(含 colorbar、边框、刻度修饰)
参数说明
| 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | x | np.ndarray (1D) | 是 | X 轴坐标(例如经度、距离) | | y | np.ndarray (1D) | 是 | Y 轴坐标(例如纬度、深度) | | z | np.ndarray (2D) | 是 | 形状为 (len(y), len(x)) 的二维数据 | | levels | list or str | 否 | 等值线层级:"log10"(对数)、"linear"(线性)或自定义列表,默认 "log10" | | norm | str | 否 | 归一化方式:"log" / "linear",默认 "log" | | cmap | str or list | 否 | 颜色映射,可传 "jet"、"viridis" 或自定义分段颜色列表,默认自定义 rainbow | | mask_value | float | 否 | 需要掩膜的特定值(例如 -1 代表陆地),默认 None | | mask_color | tuple | 否 | 掩膜区域颜色,默认 (0.2, 0.2, 0.2) | | xlabel | str | 否 | X 轴标签,默认 "Longitude" | | ylabel | str | 否 | Y 轴标签,默认 "Latitude" | | title | str | 否 | 图标题,默认空 | | colorbar_label | str | 否 | 色标条标签,默认 "Concentration" | | colorbar_ticks | list | 否 | 色标刻度值,默认 [1e-12, 1e-9, 1e-6, 1e-3, 1](对数时) | | figsize | tuple | 否 | 图片尺寸 (宽, 高) 英寸,默认 (8, 6) | | dpi | int | 否 | 输出分辨率,默认 300 | | save_path | str | 否 | 保存路径,若为 None 则只显示不保存 | | show | bool | 否 | 是否弹出显示窗口,默认 True | | format_coords | bool | 否 | 是否格式化为经纬度样式(添加 °E/°N),默认 False |
工作流
Step 1:数据校验与预处理
- 检查 z.shape == (len(y), len(x)),若不满足则尝试转置或报错
- 若 mask_value 非空,将 z == mask_value 的区域设为 NaN,后续用 set_bad 绘制掩膜颜色
- 若 norm 为 "log",将所有非正数裁剪为极小正值(1e-30)或加掩膜
Step 2:色标与层级自动生成
- 若 levels 为 "log10":生成对数间隔层级
- 若为 "linear":生成 np.linspace(z_min, z_max, 20)
- 若为自定义列表:直接使用
Step 3:自定义 colormap 构建
- 若 cmap 为字符串:调用 matplotlib.cm.get_cmap
- 若为列表形式:使用 LinearSegmentedColormap.from_list 生成自定义分段色标
- 示例:
nodes = [0.0, 0.5, 0.7, 0.8, 1.0],colors = ['white', 'royalblue', 'lightpink', 'red', 'yellow']
- 示例:
Step 4:图形绘制
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import numpy as np
fig, ax = plt.subplots(figsize=figsize, dpi=dpi)
# 若需要掩膜背景:先绘制一个仅含掩膜值的深色背景
if mask_value is not None:
z_masked = np.where(z == mask_value, 1.0, np.nan)
ax.contourf(x, y, z_masked, levels=[0.5, 1.5], colors=[mask_color])
# 主云图
norm_obj = colors.LogNorm() if norm == "log" else None
cf = ax.contourf(x, y, z, levels=levels, norm=norm_obj, cmap=cmap)
# 可选:等值线
ax.contour(x, y, z, levels=levels, colors='black', linewidths=0.5)
Step 5:坐标轴美化
- 若 format_coords 为 True,编写 format_longitude 和 format_latitude 函数
- 设置 xlabel / ylabel / title(字体大小按期刊常规,例如 fontsize=12)
Step 6:色标条
cbar = fig.colorbar(cf, ax=ax, orientation='horizontal', pad=0.05, shrink=0.8)
cbar.set_label(colorbar_label, fontsize=12)
cbar.set_ticks(colorbar_ticks)
Step 7:输出
if save_path:
plt.savefig(save_path, dpi=dpi, bbox_inches='tight')
if show:
plt.show()
plt.close()
示例
import numpy as np
x = np.linspace(100, 280, 100)
y = np.linspace(-50, 70, 80)
z = np.random.rand(80, 100) * 1e-6 # 模拟浓度场
plot_2d_contour(
x=x, y=y, z=z,
norm="log",
levels="log10",
cmap="jet",
xlabel="Longitude (°E)",
ylabel="Latitude (°N)",
title="Surface concentration",
colorbar_label="Bq/m³",
save_path="test_contour.png"
)
期望输出:对数间隔色标、底部水平色标条(刻度 1e-12 ~ 1)、尺寸 8×6 英寸、dpi=300。
约束条件
- 输入 x、y 必须单调递增(网格规则)
- z 中若存在 NaN 或 inf,自动掩膜处理
- 对数模式下,z 中 ≤0 的值会被设为极小正值(1e-30)或掩膜
- 数据动态范围过大(>1e10)时,建议用户手动指定层级以避免内存溢出
- 输出格式推荐 PNG(位图)或 PDF(矢量),默认 PNG
- 不处理投影转换(如墨卡托),仅支持笛卡尔坐标
微信扫一扫