如何在Matplotlib中绘制4D数组?附三维数组数据详情
4D深度-经纬度-数值可视化实现方案
你需要的是展示不同深度层(z轴)下,经度(x)、纬度(y)对应数值(A)的分布,类似分层的pcolormesh/pcolor效果,以下提供两种实用实现方式:
一、数据准备
先运行以下代码生成基础数据和网格坐标(pcolormesh需要二维网格匹配维度):
import numpy as np import matplotlib.pyplot as plt # 生成经纬度、深度数组及随机数值数组 x = np.arange(-7.03125,27.28125,0.0622) y = np.arange(-44.89006,-15.7057495,0.0529) z = np.linspace(-0.511953294, -5902.05762,75) A = np.random.rand(75,552,552) # 生成二维网格坐标(匹配pcolormesh输入要求) X, Y = np.meshgrid(x, y)
二、静态分层展示(选关键深度层)
如果只需查看部分重点深度层的分布,可生成子图网格批量展示:
# 选择要展示的深度索引(可根据需求调整) depth_indices = [0, 25, 50, 74] fig, axes = plt.subplots(2, 2, figsize=(12, 10)) axes = axes.flatten() for idx, ax in zip(depth_indices, axes): # 绘制当前深度层的pcolormesh(转置A[idx]匹配网格维度) pc = ax.pcolormesh(X, Y, A[idx].T, cmap='viridis') ax.set_title(f"深度: {z[idx]:.2f}") ax.set_xlabel("经度") ax.set_ylabel("纬度") # 添加统一颜色条 fig.colorbar(pc, ax=axes, orientation='vertical', fraction=0.02, pad=0.05) plt.tight_layout() plt.show()
三、交互式动态切换深度层
针对75层的大量数据,用滑块控件实时切换深度层更高效:
from matplotlib.widgets import Slider # 创建主绘图区 fig, ax = plt.subplots(figsize=(10, 8)) plt.subplots_adjust(bottom=0.2) # 初始展示第0层数据 initial_depth = 0 pc = ax.pcolormesh(X, Y, A[initial_depth].T, cmap='viridis') ax.set_xlabel("经度") ax.set_ylabel("纬度") title = ax.set_title(f"深度: {z[initial_depth]:.2f}") # 添加颜色条 fig.colorbar(pc, ax=ax) # 创建滑块控件区域 ax_slider = plt.axes([0.2, 0.05, 0.6, 0.03]) depth_slider = Slider( ax=ax_slider, label='深度索引', valmin=0, valmax=74, valinit=initial_depth, valstep=1 ) # 滑块更新逻辑 def update_depth(val): depth_idx = int(val) pc.set_array(A[depth_idx].T.ravel()) # 更新数值数组 title.set_text(f"深度: {z[depth_idx]:.2f}") # 更新标题 fig.canvas.draw_idle() # 绑定滑块事件 depth_slider.on_changed(update_depth) plt.show()
四、网页级交互式展示(可选)
如果需要更流畅的交互体验,可使用Plotly生成网页版可视化:
import plotly.graph_objects as go # 初始化热力图 fig = go.Figure(data=go.Heatmap( x=x, y=y, z=A[0].T, colorscale='Viridis', colorbar=dict(title='数值') )) # 添加深度切换滑块 fig.update_layout( title=f"深度: {z[0]:.2f}", xaxis_title='经度', yaxis_title='纬度', sliders=[dict( active=0, currentvalue={"prefix": "深度索引: "}, pad={"t": 50}, steps=[dict( method="update", args=[{"z": [A[idx].T]}, {"title": f"深度: {z[idx]:.2f}"}], label=str(idx) ) for idx in range(75)] )] ) fig.show()
注意:
A[idx].T转置操作是必须的——因为A的维度为(z, x, y),而网格坐标X/Y的维度为(len(y), len(x)),转置后才能匹配pcolormesh/热力图的输入要求。
内容的提问来源于stack exchange,提问作者Amr Talaat
相关产品推荐
相关产品推荐

