如何将4D数据绘制成分层等高线图?已有代码需后续指导
4D分层等高线/热图绘制方案
你的需求是基于包含lat(x)、lon(y)、levels(z)、dust_mixing_ratio(第四维度,颜色/强度)的CSV数据,绘制分层可视化图。先修正你现有grids_maker函数的问题(原函数错误地混合了所有层级数据插值),再提供三种可行的绘制方案:
第一步:修正网格生成函数
原函数将所有层级的坐标混在一起插值,导致结果无法对应单个层级。修改后按层级分组处理,保证每个层级的网格独立对应其沙尘混合比分布:
import pandas as pd import numpy as np from scipy.interpolate import griddata as si def grids_maker(filepath): df = pd.read_csv(filepath, sep=' ') level_grids = {} reso_x = reso_y = 50 interp = 'cubic' # 可选'nearest'/'linear' # 全局统一经纬度范围,确保所有层级网格尺寸一致 x_min, x_max = df['lat'].min(), df['lat'].max() y_min, y_max = df['lon'].min(), df['lon'].max() grid_x, grid_y = np.mgrid[x_min:x_max:1j*reso_x, y_min:y_max:1j*reso_y] # 按层级分组插值 for level, group in df.groupby('levels'): xy = group[['lat', 'lon']] g = group['dust_mixing_ratio'] grid_g = si(xy, g.values, (grid_x, grid_y), method=interp) level_grids[level] = { 'x': grid_x, 'y': grid_y, 'g': grid_g } return level_grids
方案一:分层平铺2D热图
将每个层级的热图按顺序排列成子图,直观对比不同层级的沙尘分布:
import matplotlib.pyplot as plt # 获取各层级网格数据 level_grids = grids_maker("D:\DATA\2015\MIXING_RATIOe.csv") sorted_levels = sorted(level_grids.keys()) # 按层级值排序 # 布局设置:每行3个图,自动计算行数 n_cols = 3 n_rows = (len(sorted_levels) + n_cols - 1) // n_cols fig, axes = plt.subplots(n_rows, n_cols, figsize=(15, 5*n_rows)) axes = axes.flatten() # 统一颜色标尺,保证所有层级颜色范围一致 all_g_values = np.concatenate([level_grids[lev]['g'].ravel() for lev in sorted_levels]) vmin, vmax = np.nanmin(all_g_values), np.nanmax(all_g_values) # 绘制每个层级的热图 for idx, level in enumerate(sorted_levels): ax = axes[idx] grid_data = level_grids[level] im = ax.pcolormesh(grid_data['x'], grid_data['y'], grid_data['g'], vmin=vmin, vmax=vmax, cmap='viridis') ax.set_title(f'层级 {level}') ax.set_xlabel('纬度(lat)') ax.set_ylabel('经度(lon)') # 隐藏多余子图 for idx in range(len(sorted_levels), len(axes)): axes[idx].axis('off') # 添加全局颜色条 fig.colorbar(im, ax=axes, label='沙尘混合比(dust_mixing_ratio)') plt.tight_layout() plt.show()
方案二:3D空间分层叠加热图
在3D坐标系中,将每个层级作为一个平面叠加,Z轴对应levels值,颜色表示沙尘混合比:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D level_grids = grids_maker("D:\DATA\2015\MIXING_RATIOe.csv") sorted_levels = sorted(level_grids.keys()) fig = plt.figure(figsize=(12, 8)) ax = fig.add_subplot(111, projection='3d') # 统一颜色范围 all_g_values = np.concatenate([level_grids[lev]['g'].ravel() for lev in sorted_levels]) vmin, vmax = np.nanmin(all_g_values), np.nanmax(all_g_values) # 绘制每个层级的3D平面 for level in sorted_levels: grid_data = level_grids[level] X, Y = grid_data['x'], grid_data['y'] Z = np.full_like(X, level) # 当前层级的Z轴值固定 # 将沙尘混合比转换为颜色值 face_colors = plt.cm.viridis((grid_data['g'] - vmin)/(vmax - vmin)) ax.plot_surface(X, Y, Z, facecolors=face_colors, rstride=1, cstride=1, shade=False) # 设置坐标轴与标题 ax.set_xlabel('纬度(lat)') ax.set_ylabel('经度(lon)') ax.set_zlabel('层级(levels)') ax.set_title('3D分层沙尘混合比分布图') # 添加颜色条 sm = plt.cm.ScalarMappable(cmap='viridis', norm=plt.Normalize(vmin=vmin, vmax=vmax)) sm.set_array([]) fig.colorbar(sm, ax=ax, label='沙尘混合比(dust_mixing_ratio)') plt.show()
方案三:交互式层级切换热图
用Plotly实现可交互的热图,通过下拉菜单切换不同层级,适合探索数据:
import plotly.graph_objects as go level_grids = grids_maker("D:\DATA\2015\MIXING_RATIOe.csv") sorted_levels = sorted(level_grids.keys()) fig = go.Figure() # 统一颜色范围 all_g_values = np.concatenate([level_grids[lev]['g'].ravel() for lev in sorted_levels]) vmin, vmax = np.nanmin(all_g_values), np.nanmax(all_g_values) # 添加所有层级的热图轨迹 for level in sorted_levels: grid_data = level_grids[level] fig.add_trace(go.Heatmap( x=grid_data['x'][0,:], y=grid_data['y'][:,0], z=grid_data['g'], zmin=vmin, zmax=vmax, colorscale='Viridis', name=f'层级 {level}', visible=(level == sorted_levels[0]) # 默认显示第一个层级 )) # 添加下拉切换按钮 buttons = [] for i, level in enumerate(sorted_levels): button = dict( label=f'层级 {level}', method='update', args=[{'visible': [j == i for j in range(len(sorted_levels))]}] ) buttons.append(button) fig.update_layout( updatemenus=[dict( type="dropdown", buttons=buttons, x=0.1, y=1.1 )], title='交互式层级沙尘混合比热图', xaxis_title='纬度(lat)', yaxis_title='经度(lon)', coloraxis_colorbar=dict(title='沙尘混合比') ) fig.show()
内容的提问来源于stack exchange,提问作者shravani banerjee
相关产品推荐
相关产品推荐

