You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib绘图中屏蔽特定值、色条适配及相关报错问题求助

解决Matplotlib tricontourf绘制xarray气象数据的常见问题

1. 解决掩码后z与x/y长度不一致的报错

tricontourf要求x、y、z为长度相同的一维数组,直接对z使用掩码数组会导致内部三角化时长度不匹配。正确做法是同步过滤x、y、z中不符合阈值的元素:

import xarray as xr
import matplotlib.pyplot as plt
import numpy as np

# 加载xarray数据
ds = xr.open_dataset('your_tqc_data.nc')
tqc = ds['TQC']

# 将数据展平为一维
x = tqc.lon.values.flatten()
y = tqc.lat.values.flatten()
z = tqc.values.flatten()

# 过滤阈值(如0.2)以上的数据
threshold = 0.2
valid_idx = z >= threshold
x_valid = x[valid_idx]
y_valid = y[valid_idx]
z_valid = z[valid_idx]

2. 让vmin/vmax生效

确保在调用tricontourf时明确指定vmin/vmax参数,且使用过滤后的有效数据(或正确的掩码数组):

fig, ax = plt.subplots(figsize=(10, 6))
# 使用过滤后的数据,指定vmin为阈值,vmax为数据最大值
contour_plot = ax.tricontourf(
    x_valid, y_valid, z_valid,
    vmin=threshold,
    vmax=np.nanmax(z_valid),
    cmap='viridis'
)

如果使用掩码数组,需确保z是numpy.ma.MaskedArray,同时指定vmin:

z_masked = np.ma.masked_less(z, threshold)
contour_plot = ax.tricontourf(
    x, y, z_masked,
    vmin=threshold,
    cmap='viridis',
    extend='min'  # 必须设置,否则set_under不生效
)

3. 正确使用cmap.set_under屏蔽低值

若需保留所有数据点但屏蔽阈值以下的值,需配合extend='min'和vmin参数:

cmap = plt.get_cmap('viridis')
# 设置阈值以下的值为白色(或透明:'none')
cmap.set_under('white')

fig, ax = plt.subplots(figsize=(10, 6))
contour_plot = ax.tricontourf(
    x, y, z_masked,
    vmin=threshold,
    cmap=cmap,
    extend='min'
)
  • 必须设置extend='min',否则色条不会显示低值的标记,且set_under的颜色不会应用到数据点
  • vmin需与屏蔽阈值一致,确保小于该值的点被识别为"under"

4. 精确匹配colorbar与图高度

使用mpl_toolkits.axes_grid1的make_axes_locatable,无需手动调整shrink参数:

from mpl_toolkits.axes_grid1 import make_axes_locatable

fig, ax = plt.subplots(figsize=(10, 6))
contour_plot = ax.tricontourf(x_valid, y_valid, z_valid, vmin=threshold, cmap='viridis')

# 分割主轴,创建与主图高度一致的色条轴
divider = make_axes_locatable(ax)
# size设置色条宽度,pad设置色条与主图的间距
cax = divider.append_axes("right", size="5%", pad=0.1)

# 添加色条到新建的轴
fig.colorbar(contour_plot, cax=cax)

plt.show()

完整示例代码

方式1:过滤无效数据(推荐,性能更优)

import xarray as xr
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1 import make_axes_locatable

# 加载数据
ds = xr.open_dataset('tqc_data.nc')
tqc = ds['TQC']
threshold = 0.2

# 展平并过滤数据
x = tqc.lon.values.flatten()
y = tqc.lat.values.flatten()
z = tqc.values.flatten()
valid_idx = z >= threshold
x_valid, y_valid, z_valid = x[valid_idx], y[valid_idx], z[valid_idx]

# 绘图
fig, ax = plt.subplots(figsize=(10, 6))
contour = ax.tricontourf(
    x_valid, y_valid, z_valid,
    vmin=threshold,
    vmax=np.nanmax(z_valid),
    cmap='viridis'
)

# 创建匹配高度的色条
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.1)
fig.colorbar(contour, cax=cax, label='Total Column Cloud Water (TQC)')

ax.set_xlabel('Longitude')
ax.set_ylabel('Latitude')
ax.set_title('TQC Distribution (≥0.2)')

plt.show()

方式2:使用掩码数组保留所有点

import xarray as xr
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1 import make_axes_locatable

# 加载数据
ds = xr.open_dataset('tqc_data.nc')
tqc = ds['TQC']
threshold = 0.2

# 展平并创建掩码数组
x = tqc.lon.values.flatten()
y = tqc.lat.values.flatten()
z = tqc.values.flatten()
z_masked = np.ma.masked_less(z, threshold)

# 设置颜色映射
cmap = plt.get_cmap('viridis')
cmap.set_under('white')

# 绘图
fig, ax = plt.subplots(figsize=(10, 6))
contour = ax.tricontourf(
    x, y, z_masked,
    vmin=threshold,
    cmap=cmap,
    extend='min'
)

# 创建匹配高度的色条
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.1)
fig.colorbar(contour, cax=cax, label='Total Column Cloud Water (TQC)')

ax.set_xlabel('Longitude')
ax.set_ylabel('Latitude')
ax.set_title('TQC Distribution (Values <0.2 masked)')

plt.show()

内容的提问来源于stack exchange,提问作者Louschmuh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 09:53:29