【问题标题】:How to plot Ocean Currents with Cartopy如何用 Cartopy 绘制洋流
【发布时间】:2019-10-20 15:46:19
【问题描述】:

我正在尝试为一个项目绘制一个包含来自 NASA 数据库的洋流的 netCDF4 文件,但我不断收到诸如“x 和 y 坐标与矢量分量的形状不兼容”之类的错误。

我尝试将流图更改为轮廓图(当我这样做时,它说它需要是一个 2d 数组),我试图更改它但我无法让它工作。

import os
import matplotlib.pyplot as plt
from netCDF4 import Dataset as netcdf_dataset
import numpy as np
import cartopy.crs as ccrs

fname = "oscar_vel2019.nc.gz.nc"

data=netcdf_dataset(fname)
v = data.variables['v'][0, :, :, :]
vf = data.variables['vm'][0, :, :, :]
u = data.variables['u'][0, :, :, :]
uf = data.variables['um'][0, :, :, :]
lats = data.variables['latitude'][:]
lons = data.variables['longitude'][:]
ax = plt.axes(projection=ccrs.PlateCarree())

mymap=plt.streamplot(lons, lats, u, v, 60, transform=ccrs.PlateCarree())

ax.coastlines()

plt.show()

我希望它能够在绘图上显示洋流,并通过动画显示粒子在洋流中的运动。我真的没有太多的知识,这就是我问的原因。这是我从中获取文件的链接:https://podaac-opendap.jpl.nasa.gov/opendap/hyrax/allData/oscar/preview/L4/oscar_third_deg/oscar_vel2019.nc.gz.html

【问题讨论】:

  • 如果 lat 和 Lon 是一维变量,您需要使用网格来制作与 u 和 v 相同的大小
  • 如果我问了一个愚蠢的问题,我很抱歉,但我以前没有做过这样的事情,所以我不确定网格网格是如何工作的。那么,您介意举个例子说明我将如何做到这一点吗?我之前尝试过这样做; x, y = np.meshgrid(u, v) mymap=plt.streamplot(lons, lats, x, y, 60, transform=ccrs.PlateCarree()) 但这只是给了我一个内存错误: MemoryError: Unable to allocate具有形状 (577681, 577681) 和数据类型 float64 的数组
  • 如果 lat 和 Lon 是一维变量,你应该网格化 lat 和 Lon 而不是 u 和 v。如果他们已经是两个 d 那么那当然没有帮助。
  • 我尝试使用缩减的数据集,但是虽然不再出现内存错误,但现在我得到了这个错误; ValueError:x 和 y 坐标与矢量分量的形状不兼容。有人可以帮我解决这表明什么以及我需要改变什么吗?

标签: python-3.x matplotlib cartopy netcdf4


【解决方案1】:

好的,我下载了数据。问题是 u 和 v 是 4 维的,所以你需要挤出“深度”维度。 Cartopy 也不接受大于 180 的经度,而且您可能无法使用流图绘制整个事情。此外, density=60 将永远需要......

这很丑,但给了你想法。

import xarray as xr
import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

with xr.open_dataset('/Users/jklymak/downloads/oscar_vel2019.nc.gz.nc') as ds:
    print(ds)

    ax = plt.axes(projection=ccrs.PlateCarree())

    dec = 10
    lon = ds.longitude.values[::dec]
    lon[lon>180] = lon[lon>180] - 360
    mymap=plt.streamplot(lon, ds.latitude.values[::dec], ds.u.values[0, 0, ::dec, ::dec], ds.v.values[0, 0, ::dec, ::dec], 6, transform=ccrs.PlateCarree())
    ax.coastlines()
    plt.show()

【讨论】:

    猜你喜欢
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 2019-02-07
    相关资源
    最近更新 更多