Pcolormesh绘制分箱PSD异常:云粒子粒径与垂直速度对比图问题
我正在尝试绘制气象科学飞行中云样本的分箱垂直速度与分箱粒径对比图。现有DataFrame包含多列代表粒子粒径分箱端点(单位:mm),最后一列为垂直速度(单位:m/s),粒径分箱列的Z值为#/cm⁴,代表对应粒径范围的云粒子数浓度。
我尝试将垂直速度列(w_ms-1)设为索引(存在重复值),转置DataFrame后使用pcolormesh绘图,预期得到类似手绘的分箱浓度分布,但实际生成的图形异常:
- 四边形未按对数间距排列
- 存在本该有数据却缺失的区域
相关代码如下:
CONCvWdf = pd.DataFrame() #this is the dataframe where all CONC and W data will be concatenated. for filename in CommonDates: #concatenate W and CONCENTRATION for all files(that represent different dates) into one giant dataframe df = pd.merge(MergedHDict[filename]['CONCENTRATION'], TAMMSDict[filename]['w_ms-1'], right_index=True, left_index=True) #merging w onto CONC with common indicies CONCvWdf = pd.concat([CONCvWdf, df], ignore_index=True) #concatenating vertically, the axis of concatenation defaults to 0 (stacks the rows) CONCvWdf = CONCvWdf[CONCvWdf['w_ms-1'].notnull()] #removes rows where W has null values CONCvWdf.reset_index(drop=True, inplace=True) CONCvWdf
#attempting to plot data by setting w as the index CONCvWdf.set_index('w_ms-1', inplace=True, drop=True) # replacing index that is currently displaying time with the w_ms-1 values for each corresponding time CONCvWdf.index.name=None CONCvWdf
CONCvWdf = CONCvWdf.T # transposing dataframe for plotting purposes. this sets the index to the size-bin endpoints and sets the column values to the values of W. plt.style.use('tableau-colorblind10') # figure style fig, ax = plt.subplots(figsize=(12.5, 9)) # assign subplots to fig and ax fig.tight_layout(pad = 8.5) # pad edges of figure cmap = cmr.get_sub_cmap(cm.gnuplot2.copy(), 0, 0.9) # make copy of colormap to alter it. use cmr.get_sub_cmap to reduce the color range of the cmap cmap.set_bad(color='white') # set 0 to white shading #dropped last row/column of data to fit shading scheme. CONCplot = ax.pcolormesh(CONCvWdf.columns, CONCvWdf.index.astype(float), CONCvWdf.iloc[:-1,: -1].astype(float), shading='flat', norm = mpl.colors.LogNorm(), cmap = cmap, edgecolors = 'black') cb = plt.colorbar(CONCplot, shrink=1, aspect=25, location='right', ax=ax) cb.ax.set_title('#/cm⁴', pad=15, fontsize=10.5) ax.set_title('Number Concentration', pad=13.5, fontsize=15, fontweight="bold") ax.set_xlabel("W m/s", rotation=0, labelpad=8) ax.set_ylabel("D (mm)", labelpad=12.5) ax.set_xscale('symlog') ax.set_yscale('log') plt.show()
1. 垂直速度列作为索引导致列顺序无序
把w_ms-1设为索引后转置,DataFrame的列会变成原始w_ms-1的无序值(因为原始数据中该列有重复值且未排序)。pcolormesh会严格按照列的原始顺序绘制,不会自动按数值大小排序,这直接导致x轴(垂直速度)的刻度排列混乱,四边形自然无法匹配对数间距的要求。
2. 重复垂直速度值引发的数据覆盖/缺失
转置时,pandas不允许存在重复列名,相同的w_ms-1值会被合并为同一列,但只会保留最后一次出现的对应粒径浓度数据,前面的同速度数据会被丢弃。这就造成了本该有数据的区域出现空白,形成缺失块。
3. 对数轴与无序输入数据不兼容
虽然你设置了ax.set_xscale('symlog'),但传入pcolormesh的x轴数据是未排序的CONCvWdf.columns,matplotlib无法基于无序数据正确计算对数刻度的间距,最终导致图形单元格排列混乱。
4. 粒径分箱的边界数据处理错误
粒径分箱是连续的区间(如0.1-0.2mm、0.2-0.4mm),但你直接将分箱端点作为y轴输入给pcolormesh。pcolormesh要求的是分箱边界数组(维度比数据矩阵多1),而非单纯的端点值,这也会导致y轴的对数间距无法正确映射到图形单元格。
内容的提问来源于stack exchange,提问作者Christian Hall

