2017-07-06 64 views
1

我有一些來自海洋循環模型(MITgcm)的輸出數據。這是一個理想化的通道(笛卡兒),所以幾何不會令人困惑,幸運的是。使用稀疏數據在python中繪製2D輪廓圖

我想繪製一些在y-z平面上的場(速度,溫度等)。仿真域涉及30個垂直層,其中每個層是800×400的y-x網格。我有每個字段存儲在numpy數組形狀(30,800,400)分別去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(作爲完整的域深度爲2985米)'垂直'層,並輸入30層的相應位置的y數據爲由Z上面給出的(這裏yz_zonal是數據值(30800)矩陣):

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 

然後,如果我嘗試繪圖yz_matrix使用matplotlib的imshow,這樣做:

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 y-z plot of velocity data

在正確的物理z位置有30個數據值條帶,但它們之間存在整個零負載。我只想插入30條之間的數據並忽略所有其他點。

如果有人能爲我解決這個問題,這將是非常光明的。提前致謝!

彼得

回答

1

您可以直接繪製yz_matrixpcolormesh,給z和y數據作爲座標的meshgrid。這將導致不同大小的單元格擴展到z中的下一個值。請參閱下面的左圖。

您也可以將數據內插到新的更細的網格上。爲此,可以使用scipy.interpolate.griddata

enter image description here

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

謝謝!這真的很有幫助;我已經設法做出一些不錯的情節!我從來沒有使用過meshgrid或griddata,但聽起來正是我需要的。 當您定義網格Y,Z = np.meshgrid(y,z [ - - 1])時,您能澄清爲什麼將z切成z [::-1]嗎?爲什麼不只是np.meshgrid(y,z)? –

+0

除了在更負的z處具有較低的值以外,沒有什麼特別的理由反轉'z'。你需要自己決定你的數據是如何組織的,並決定輸入什麼內容。 – ImportanceOfBeingErnest

0

看看這個example從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()