繁体   English   中英

使用稀疏数据在python中绘制2d等高线图

[英]Plotting a 2d contour plot in python with sparse data

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

我想在yz平面上绘制一些场(速度,温度等)。 仿真域涉及30个垂直层,其中每个层都是800x400 yx网格。 我将每个字段存储在形状为(30,800,400)的numpy数组中,分别为z,y,x。

我可以轻松绘制30个垂直水平的xy平面切片。 我可以使用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为(30,800)个数据值矩阵):

yz_matrix = np.empty((2985, 800)) #empty matrix for yz-plane data, vertical extent is 2985 (m)

for i in range(len(Z)):
     yz_matrix[round(-Z[i])] = yz_zonal[i] #set matrix values to correct depths

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

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)

我刚得到这个图: 速度数据的BAD yz图

在正确的物理z位置上有30条数据值,但它们之间全部为零。 我只想在30条之间插入数据,而忽略所有其他点。

如果有人可以帮我解决这个问题,那将是很棒的。 提前致谢!

彼得

在matplotlib网站上看一下这个示例 ,尤其是np.meshgridplt.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_matrix直接绘制为pcolormesh ,将z和y数据的网格作为坐标。 这将导致大小不同的像元,这些像元的范围扩展到z中的下一个值。 请参见下面的左图。

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

在此处输入图片说明

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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM