如何在Flopy中使用pcolormesh创建对称色条?
污染物羽流浓度图symlog刻度色条优化方案
问题说明
要绘制0-5000mg/L的污染物羽流2D浓度图,要求最低浓度0显示为白色,选用binary色卡。由于数据量庞大,使用symlog刻度能更好地呈现浓度分布,但色条无法像线性刻度那样显示明确的0和5000极值;尝试自定义刻度时,又出现标签拥挤的问题。同时也不确定是否有更适合的色卡可选。
复现代码
plt.figure(figsize=(10,10)) ucnobj = bf.UcnFile('init_plume_ED.UCN') times = ucnobj.get_times() conc = ucnobj.get_data(totim=times[-1]) modelmap = flopy.plot.PlotMapView(model=mf, layer=13, extent=(725,925,100,220)) norm = Normalize(vmin=0, vmax=5000) cs = modelmap.plot_array(conc, cmap='binary', norm='symlog') cbar = plt.colorbar(cs,shrink=0.2) plt.title('Initial phenol plume concentration (symlog scale)')
注:plot_array()会将关键字参数传递给pcolormesh()
问题根源与解决方法
排查后发现核心问题:
- MT3D会将干单元的浓度值设为
-1e30,这些负数值干扰了色条的范围计算 - 数据中0-1区间存在大量小值,
symlog刻度会优先展示该区间的数值,导致色条偏离目标范围
解决步骤:
使用ma.masked_equal()屏蔽干单元的负浓度值,再进行绘图:
import numpy.ma as ma # 屏蔽值为-1e30的干单元数据 conc_masked = ma.masked_equal(conc, -1e30) # 绘制屏蔽后的浓度图 plt.figure(figsize=(10,10)) modelmap = flopy.plot.PlotMapView(model=mf, layer=13, extent=(725,925,100,220)) cs = modelmap.plot_array(conc_masked, cmap='binary', norm='symlog', vmin=0, vmax=5000) cbar = plt.colorbar(cs, shrink=0.2) plt.title('Initial phenol plume concentration (symlog scale)')
屏蔽负数值后,色条将只展示0-5000的目标浓度范围,同时保留symlog刻度对数据分布的良好展示效果。
色卡替代建议
如果需要0值显示为白色,除了binary色卡,还可以尝试:
viridis_r:反转的viridis色卡,最小值为浅白色调,色彩过渡更柔和,适合浓度分布可视化- 自定义渐变色卡:比如
plt.cm.get_cmap('Blues_r'),从白色过渡到深蓝色,能清晰区分低浓度和高浓度区域
内容的提问来源于stack exchange,提问作者Viridis
相关产品推荐
相关产品推荐

