【问题标题】:PYTHON: overlaying netCDF data on a basemap (contourf)PYTHON:在底图(轮廓)上覆盖 netCDF 数据
【发布时间】:2015-11-04 13:50:49
【问题描述】:

我是 python 和 netCDF 的新手,但几天来一直在处理以下问题,但没有任何进展。我的代码是基于我读过的各种教程和示例,我不知道出了什么问题!

基本上,我希望能够将一些 netCDF 数据的图叠加到底图上。我的代码(完整)如下:

import numpy as np
from netCDF4 import Dataset
# from scipy.io import netcdf
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

when = 0 # improve this variable later so that user input can be date/ time

filename = '/net/glusterfs_surft/surft/data/LakeData/JRA55/raw/jra55_tmp.1964010100_1964123121.nc' # input the complete filepath here
# open the file at the address 'filename' for reading:
fopen = Dataset(filename, 'r') # <-- turn on if using netCDF4
# fopen = netcdf.netcdf_file(filename, 'r') <-- turn on if using scipy.io

# variables in JRA-55 are:
# TMP_GDS0_HTGL
# initial_time0_hours
# initial_time0_encoded
# initial_time0
# g0_lon_2 (runs from 0 to 360E in 1.25 deg steps)
# g0_lat_1 (runs from 90 to -90 in 1.25 deg steps)

# now set variables x, y and 'data':
x = fopen.variables['g0_lon_2'][:] # this is a 1D longitude array
y = fopen.variables['g0_lat_1'][:] # this is a 1D latitude array 
data = fopen.variables['TMP_GDS0_HTGL'][:] 
# this is a 3D array with temperature saved at each point in 2D space and time
# reduce data to a 2D array for a specific time:
data_when = data[when,:,:]

#close the file at the address
fopen.close()

# create a basemap to plot onto:
m = Basemap(width=5000000, height=3500000,\
        resolution='l', projection='stere',\
        lat_ts=40, lat_0=50, lon_0=0)
m.drawcoastlines()
m.drawparallels(np.arange(-80.,81,20))
m.drawmeridians(np.arange(-180.,181,20))
# 
#   add other basemap drawing options here 
#

# convert 1D matrices into 2D fill matrices for processing:
xx, yy = np.meshgrid(x, y)

plt.contourf(xx, yy, data_when, latlon=True)

plt.show()

如果我注释掉底图部分,那么我的数据如下所示:

world map, no borders, temperature contours

如果我包含它们(无需注释掉plt.contourf(xx, yy, data_when, latlon=True)),我得到的图像是:

stereographic projection at lat = 50, lon = 0, with borders, no contours

我希望能够在一个图中显示这些图像的相应部分,但不知道如何。使用的地图投影不重要,但图像应与数据和底图相对应。

谢谢!希望能帮到你!

【问题讨论】:

  • 显然用户无法访问与我相同的文件路径。如果您想对我有帮助,我使用的数据来自 JRA-55(准确地说是 1964 年 2m 温度),但正如我预计的那样,大多数人不会有这个,任何基于 netCDF 的建议都会很棒!
  • 你在做什么似乎基本上是正确的。没有原始数据确实很难调试。我遇到过类似的情况,我建议遵循控制程序:在更大的地图上进行全覆盖,查看是否有任何数据可见;检查 xx 和 yy 的实际值并与地图坐标进行比较(您会看到它们将鼠标悬停在地图上);检查坐标变量是否正确;在网格网格之前/之后翻转坐标等...
  • 您可以尝试不使用latlon=True。而是使用xx, yy = m(xx, yy) 创建地图索引。我过去曾得到过这样的帮助。

标签: python netcdf matplotlib-basemap


【解决方案1】:

我的代码的以下版本功能齐全。感谢 sea_hydro 在 cmets 中提供的帮助。我希望代码的工作版本对其他希望解决这个问题的新手有用!

import numpy as np
from netCDF4 import Dataset
# from scipy.io import netcdf
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap

when = 0 # improve this variable later so that user input can be date/ time

filename = 'some_filepath' # input the complete filepath here
# open the file at the address 'filename' for reading:
fopen = Dataset(filename, 'r') # <-- turn on if using netCDF4
# fopen = netcdf.netcdf_file(filename, 'r') <-- turn on if using scipy.io

# now set variables x, y and 'data':
x = fopen.variables['lon_var'][:] # this is a 1D longitude array
y = fopen.variables['lat_var'][:] # this is a 1D latitude array 
data = fopen.variables['data_var'][:] 
# this is a 3D array with a value saved at each point in 2D space and time
# reduce data to a 2D array for a specific time:
data_when = data[when,:,:]

#close the file at the address
fopen.close()

# create a basemap to plot onto:
m = Basemap(width=10000000, height=7000000,\
        resolution='l', projection='stere',\
        lat_ts=40, lat_0=50, lon_0=0)
m.drawcoastlines()
m.drawparallels(np.arange(-80.,81,20))
m.drawmeridians(np.arange(-180.,181,20))
# 
#   add other basemap drawing options here 
#

此代码使用立体地图投影。其他底图选项可以找到in the matlpotlib basemap toolkit documentation

# convert 1D matrices into 2D fill matrices for processing:
xx, yy = np.meshgrid(x, y)
xx, yy = m(xx, yy)
plt.contourf(xx, yy, data_when)

plt.show()

也可以叠加其他图。

【讨论】:

  • 为了让上述代码充分发挥作用,我发现在经度 360 度处的数据也需要一个额外的值,尽管这与 0 度的值相同。用户可能还会注意到,此代码不会为立体投影产生正确的结果(尽管它可能看起来像一目了然)。其他一些底图也可以使用 - 我在 Albers 上取得了最大的成功。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 2020-12-01
  • 1970-01-01
相关资源
最近更新 更多