简体   繁体   English

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

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

I have some output data from an ocean circulation model (MITgcm). 我有一些来自海洋环流模型(MITgcm)的输出数据。 It is an idealised channel (Cartesian) so the geometry is not confusing, luckily. 幸运的是,这是一个理想化的通道(笛卡尔),因此几何形状不会引起混淆。

I'd like to plot some of the fields (velocity, temperature etc.) in the yz plane. 我想在yz平面上绘制一些场(速度,温度等)。 The simulation domain involves 30 vertical layers where each layer is an 800x400 yx grid. 仿真域涉及30个垂直层,其中每个层都是800x400 yx网格。 I have each of the fields stored in numpy arrays with shape (30, 800, 400) going z,y,x respectively. 我将每个字段存储在形状为(30,800,400)的numpy数组中,分别为z,y,x。

I can easily plot xy plane slices for the 30 vertical levels. 我可以轻松绘制30个垂直水平的xy平面切片。 I can do this using matplotlib's contourf or imshow and changing the extent to the correct physical values in km. 我可以使用matplotlib的contourf或imshow并将范围更改为正确的物理值(以km为单位)来执行此操作。

The problem is that the vertical layers are unevenly spaced. 问题是垂直层的间距不均匀。 I have the grid data for Z which tells me what physical depth (in metres) each of the layers corresponds to. 我有Z的网格数据,该数据告诉我每个图层对应的物理深度(以米为单位)。

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

I tried to get round this by creating an empty matrix with 2985 (as the full domain depth is 2985m) 'vertical' layers, and inputting the y-data at the corresponding positions for the 30 layers as given by Z above (here yz_zonal is a (30,800) matrix of data values): 我试图通过创建一个带有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

Then if I try to plot yz_matrix using matplotlib's imshow, by doing: 然后,如果我尝试使用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)

I just get this figure: BAD yz plot of velocity data 我刚得到这个图: 速度数据的BAD yz图

There are 30 strips of data values at the correct physical z positions, but there's a whole load of zeros in between them. 在正确的物理z位置上有30条数据值,但它们之间全部为零。 I only want to interpolate the data in between the 30 strips and ignore all of the other points. 我只想在30条之间插入数据,而忽略所有其他点。

It would be brilliant if anyone could sort this out for me. 如果有人可以帮我解决这个问题,那将是很棒的。 Thanks in advance! 提前致谢!

Peter 彼得

Take a look at this example from the matplotlib site, and especially the functions np.meshgrid and plt.contourf . 在matplotlib网站上看一下这个示例 ,尤其是np.meshgridplt.contourf函数。 Something like this with irregular z 's will work: 像这样的带有不规则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()

You may directly plot the yz_matrix as a pcolormesh , giving a meshgrid of the z and y data as coordinates. 您可以将yz_matrix直接绘制为pcolormesh ,将z和y数据的网格作为坐标。 This would lead to different sized cells which extent up to next value in z. 这将导致大小不同的像元,这些像元的范围扩展到z中的下一个值。 See left picture below. 请参见下面的左图。

You may also interpolate your data on a new finer grid. 您也可以将数据插值到新的更精细的网格上。 To this end, scipy.interpolate.griddata may be used. 为此,可以使用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