使用底图进行3D海流绘图

时间:2019-03-30 11:28:58

标签: python-3.x netcdf4

我正在尝试使用3d要素和底图绘制洋流,但是每当我尝试包括底图时,它仅绘制表面数据,而不绘制子表面数据。正常的箭头操纵matplotlib quiver选项在这里似乎无法正常工作,因此即将到来的绘图质量不佳或信息量丰富

我已经创建了3d底图,并使用模型输出从netcdf文件读取数据

import os
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
from mpl_toolkits.mplot3d import Axes3D
from netCDF4 import Dataset



#Reading the netcdf histoty file
in_file = Dataset('../../roms_z_his_w_t8_010.nc','r')
#temp = in_file.variables['temp'][:,:,:,:]
#salt = in_file.variables['salt'][:,:,:,:]
u = in_file.variables['u'][0,:10,:,:]
v = in_file.variables['v'][0,:10,:,:]
w = in_file.variables['w'][0,:10,:,:]
d = -(in_file.variables['depth'][:10])
lat = in_file.variables['lat'][:]
lon = in_file.variables['lon'][:]

x,y,z =  np.meshgrid(lat,d,lon)

#Create a 3d normal figure
fig = plt.figure(figsize=(16,14))
ax = fig.gca(projection='3d')

#Draw the earth map using Basemap
# Define lower left, uperright lontitude and lattitude respectively
extent = [75, 100, 5, 25]
# Create a basemap instance that draws the Earth layer
bm = Basemap(llcrnrlon=extent[0], llcrnrlat=extent[2],
             urcrnrlon=extent[1], urcrnrlat=extent[3],
             projection='cyl', resolution='l', fix_aspect=False, ax=ax)
# Add Basemap to the figure
ax.add_collection3d(bm.drawcoastlines(linewidth=0.25))
ax.add_collection3d(bm.drawcountries(linewidth=0.35))
ax.view_init(azim=300, elev=50)
ax.set_xlabel('Longitude (°E)', labelpad=20)
ax.set_ylabel('Latitude (°N)', labelpad=20)
ax.set_zlabel('Depth (m)', labelpad=20)
# Add meridian and parallel gridlines
lon_step = 5
lat_step = 5
meridians = np.arange(extent[0], extent[1] + lon_step, lon_step)
parallels = np.arange(extent[2], extent[3] + lat_step, lat_step)
ax.set_yticks(parallels)
ax.set_yticklabels(parallels)
ax.set_xticks(meridians)
ax.set_xticklabels(meridians)
#ax.set_zticks(d)
#ax.set_zticklabels(d)

skip=(slice(None,None,1),slice(None,None,1))
ax.quiver(z[skip],x[skip],y[skip],u[skip],v[skip],w[skip], length=0.1, normalize=False)
plt.savefig('3dplot.png')
in_file.close()

我想要一个3d洋流,其底图功能和箭头大小会随大小或色标而变化。现在看起来像这样:

enter image description here

1 个答案:

答案 0 :(得分:1)

尝试一下-我添加了set_zlim(0.,150)来强制z轴展开:

import os
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
from mpl_toolkits.mplot3d import Axes3D
from netCDF4 import Dataset



#Reading the netcdf history file
in_file = Dataset(r'roms.nc','r')
#temp = in_file.variables['temp'][:,:,:,:]
#salt = in_file.variables['salt'][:,:,:,:]
u = in_file.variables['u'][0,:10,:,:]
v = in_file.variables['v'][0,:10,:,:]
w = in_file.variables['w'][0,:10,:,:]
d = (in_file.variables['depth'][:10])
lat = in_file.variables['lat'][:]
lon = in_file.variables['lon'][:]

in_file.close()


x,y,z =  np.meshgrid(lat,d,lon)

#Create a 3d normal figure
fig = plt.figure(figsize=(16,14))
ax = fig.gca(projection='3d')

#Draw the earth map using Basemap
# Define lower left, uperright lontitude and lattitude respectively
extent = [75, 100, 5, 25]
# Create a basemap instance that draws the Earth layer
bm = Basemap(llcrnrlon=extent[0], llcrnrlat=extent[2],
             urcrnrlon=extent[1], urcrnrlat=extent[3],
             projection='cyl', resolution='l', fix_aspect=False, ax=ax)

# Add Basemap to the figure
ax.add_collection3d(bm.drawcoastlines(linewidth=0.25))
ax.add_collection3d(bm.drawcountries(linewidth=0.35))
ax.view_init(azim=300, elev=50)
ax.set_xlabel('Longitude (°E)', labelpad=20)
ax.set_ylabel('Latitude (°N)', labelpad=20)
ax.set_zlabel('Depth (m)', labelpad=20)

# Add meridian and parallel gridlines
lon_step = 5
lat_step = 5
meridians = np.arange(extent[0], extent[1] + lon_step, lon_step)
parallels = np.arange(extent[2], extent[3] + lat_step, lat_step)
ax.set_yticks(parallels)
ax.set_yticklabels(parallels)
ax.set_xticks(meridians)
ax.set_xticklabels(meridians)
#ax.set_zticks(d)
#ax.set_zticklabels(d)

skip=(slice(None,None,1),slice(None,None,1))
ax.quiver(z[skip],x[skip],y[skip],u[skip],v[skip],w[skip], length=0.1, normalize=False)
ax.set_zlim(0., 150)
plt.savefig('3dplot.png')

输出: 3D Currents