使用稀疏数据在python中绘制二维等高线图

使用稀疏数据在python中绘制二维等高线图,python,matplotlib,multidimensional-array,plot,imshow,Python,Matplotlib,Multidimensional Array,Plot,Imshow,我有一些来自海洋环流模型(MITgcm)的输出数据。幸运的是,这是一个理想化的通道(笛卡尔),因此几何结构不会混淆 我想在y-z平面上绘制一些场(速度、温度等)。模拟域包括30个垂直层,其中每个层为800x400 y-x网格。我将每个字段存储在numpy数组中,其形状(30800400)分别为z、y、x 我可以很容易地绘制30个垂直水平的x-y平面切片。我可以使用matplotlib的contourf或imshow来实现这一点,并将范围更改为以km为单位的正确物理值 问题是垂直层的间距不均匀。我

我有一些来自海洋环流模型(MITgcm)的输出数据。幸运的是,这是一个理想化的通道(笛卡尔),因此几何结构不会混淆

我想在y-z平面上绘制一些场(速度、温度等)。模拟域包括30个垂直层,其中每个层为800x400 y-x网格。我将每个字段存储在numpy数组中,其形状(30800400)分别为z、y、x

我可以很容易地绘制30个垂直水平的x-y平面切片。我可以使用matplotlib的contourf或imshow来实现这一点,并将范围更改为以km为单位的正确物理值

问题是垂直层的间距不均匀。我有Z的网格数据,它告诉我每个层对应的物理深度(米)

Z是:[-5-15-25-36-49-65-84-105.5-130.5-159.5-192.5-230-273-322.5-379-443-515-596-688-792-909.5-1042.5-1192.5-1362-1553.5-1770-2015。 -2285.-2565.-2845.]

我试图通过创建一个包含2985(因为整个域深度为2985m)“垂直”层的空矩阵,并在上面Z给出的30层对应位置输入y数据(这里yz_zonal是一个(30800)数据值矩阵)来绕过这个问题:

然后,如果我尝试使用matplotlib的imshow绘制yz_矩阵,请执行以下操作:

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlabel('y (km)')
ax.set_ylabel('z (m)')
yzplot = ax.imshow(yz_matrix, aspect='auto', interpolation='gaussian', cmap='inferno', extent=[0,2000,-2985,0])
plt.colorbar(yzplot)
我刚刚得到这个数字:

在正确的物理z位置有30个数据条带,但是在它们之间有一大堆零。我只想在30条带之间插入数据,忽略所有其他点

如果有人能帮我解决这件事,那就太好了。提前谢谢

Peter

从matplotlib站点了解这一点,尤其是函数
np.meshgrid
plt.contourf
。使用不规则的
z
,类似这样的功能将起作用:

z = [1,2,5,10]
x = [1,2,3,4,5,6,7,8]

zz, xx = np.meshgrid(z, x)

# create some data
values = np.random.randn(len(x), len(z))

plt.contourf(zz, xx, values)
plt.show()

您可以直接将
yz_矩阵
绘制为
pcolormesh
,给出z和y数据的网格作为坐标。这将导致不同大小的单元延伸到z中的下一个值。见下图

也可以在新的更精细的栅格上插值数据。为此,可以使用scipy.interpolate.griddata


非常感谢。这真的很有帮助;我现在已经成功地画出了一些漂亮的情节!我以前从未使用过meshgrid或griddata,但听起来正是我所需要的。你能解释一下为什么在定义网格Y,z=np.meshgrid(Y,z[::-1])时将z切片为z[:-1]吗?为什么不仅仅是np.meshgrid(y,z)?反转
z
没有特别的原因,除了在更负的z处有更低的值。您需要自行决定数据的组织方式和输入内容。@ImportanceOfBeingErnest如果数组稀疏,是否可以使用此绘图函数。我试着使用plt.scatter(x,y,c=z),它在理论上是有效的,但我想事情可以用更好的方式来完成。
z = [1,2,5,10]
x = [1,2,3,4,5,6,7,8]

zz, xx = np.meshgrid(z, x)

# create some data
values = np.random.randn(len(x), len(z))

plt.contourf(zz, xx, values)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

z = np.array([-5.,-15.,-25.,-36.,-49.,-65.,-84.,-105.5,-130.5,-159.5,-192.5,
              -230.,-273.,-322.5,-379.,-443.,-515.,-596.,-688.,-792.,-909.5,
              -1042.5,-1192.5,-1362.,-1553.5,-1770.,-2015.,-2285.,-2565.,-2845.])
y = np.arange(0,100)
yz_matrix = np.cumsum(np.random.rand(len(z), len(y)), axis=0)

fig, (ax, ax2) = plt.subplots(ncols=2)

# plot raw data as pcolormesh
Y,Z = np.meshgrid(y,z[::-1])
ax.pcolormesh(Y,Z, yz_matrix, cmap='inferno')
ax.set_title("pcolormesh data")

# now interpolate data to new grid 
zi = np.arange(-2845,-5)
YI,ZI = np.meshgrid(y,zi)
points = np.c_[Y.flatten(),Z.flatten()]

interp = griddata(points, yz_matrix.flatten(), (YI,ZI), method='linear')

ax2.pcolormesh(YI,ZI, interp, cmap='inferno')
ax2.set_title("pcolormesh interpolated")

plt.show()