【问题标题】:Can't plot the scatter plot using Cartopy which well shown in basemap无法使用 Cartopy 绘制散点图,这在底图中很好地显示
【发布时间】:2020-02-07 15:34:15
【问题描述】:

HDF-EOS 网站提供了一些有用的代码示例来处理卫星数据。我尝试使用基于 OMI 的 level2 检索数据集(类似交换)。但是,当我想使用 Cartopy 可视化数据时,我认为它比 Python 中的底图更好,问题就出现了。

这是示例代码。我已经上传了案例资料here,有兴趣的可以下载。

## related libraries
from netCDF4 import Dataset
import cartopy
from cartopy.io.img_tiles import StamenTerrain
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from mpl_toolkits.basemap import Basemap


## read the data
dset = f[DATAFIELD_NAME]
data = dset[:]
lat = f[LAT_NAME][:]
lon = f[LON_NAME][:]
title = dset.attrs['Title'].decode()
units = dset.attrs['Units'].decode()
_FillValue = dset.attrs['_FillValue']
add_offset = dset.attrs['Offset']
scale_factor = dset.attrs['ScaleFactor']
data[data == _FillValue] = np.nan
data = data * scale_factor + add_offset
data = np.ma.masked_where(np.isnan(data), data)
# Subset data at nCandidate = 0
data = data[0,:,:]
lon = lon[0,:,:]
lat = lat[0,:,:]
fig  = plt.figure(figsize=(12,5))
ax1 = plt.subplot(121)
m = Basemap(projection='cyl', resolution='l',
                llcrnrlat=-90, urcrnrlat = 90,
                llcrnrlon=-180, urcrnrlon = 180)
m.drawcoastlines(linewidth=0.5)
m.drawparallels(np.arange(-90., 120., 30.), labels=[1, 0, 0, 0])
m.drawmeridians(np.arange(-180, 180., 45.), labels=[0, 0, 0, 1])
m.scatter(lon, lat, c=data, s=0.1, cmap=plt.cm.jet,
          edgecolors=None, linewidth=0)
cb = m.colorbar()
cb.set_label(units)
plt.title("BASEMAP")

ax2 = plt.subplot(122,projection=ccrs.PlateCarree())
ax2.scatter(lon,lat,c=data,s=0.1,zorder =4,\
            transform=ccrs.PlateCarree(), cmap = plt.cm.jet)
ax2.set_global()
plt.title("CARTOPY")

我不知道如何解决这个问题?

【问题讨论】:

  • 你能在不需要下载任何东西的情况下让它重现吗?
  • 好的,我试着把数据复制到这里。
  • transform=ccrs.Geodetic() 有什么改变吗?您的经度和纬度数据的界限是什么?

标签: python matplotlib gis matplotlib-basemap cartopy


【解决方案1】:

我不确定您的示例为什么不起作用,我可以使用与您的基本相同的以下代码得到一个数字:

from matplotlib.colors import LogNorm

FILE_NAME = 'OMI-Aura_L2G-OMNO2G_2016m0526_v003-2016m0527t184011.he5'
path = '/HDFEOS/GRIDS/ColumnAmountNO2/Data Fields/'
DATAFIELD_NAME = path + 'ColumnAmountNO2'


f=h5py.File(FILE_NAME, mode='r')
dset = f[DATAFIELD_NAME]
data =dset[:].astype(np.float64)

# Retrieve any attributes that may be needed later.
# String attributes actually come in as the bytes type and should
# be decoded to UTF-8 (python3).
scale = f[DATAFIELD_NAME].attrs['ScaleFactor']
offset = f[DATAFIELD_NAME].attrs['Offset']
missing_value = f[DATAFIELD_NAME].attrs['MissingValue']
fill_value = f[DATAFIELD_NAME].attrs['_FillValue']
title = f[DATAFIELD_NAME].attrs['Title'].decode()
units = f[DATAFIELD_NAME].attrs['Units'].decode()

# Retrieve the geolocation data.
latitude = f[path + 'Latitude'][:]
longitude = f[path + 'Longitude'][:]

latitude=latitude[0,:,:]
longitude=longitude[0,:,:]
data=data[0,:,:]

data[data == missing_value] = np.nan
data[data == fill_value] = np.nan
data = scale * (data - offset)
datam = np.ma.masked_where(np.isnan(data), data)

#Figure
fig=plt.figure()
axs=plt.subplot(111,projection=ccrs.PlateCarree())
pcm=axs.scatter(longitude,latitude,c=datam,s=0.1,cmap='viridis',norm=LogNorm(vmin=1e14,vmax=1e17))
axs.add_feature(cfeature.COASTLINE)
#colorbar
fig.subplots_adjust(right=0.87)
cbar_ax = fig.add_axes([0.89, 0.3, 0.04, 0.4])
cbar=fig.colorbar(pcm,cax=cbar_ax, extend='both', orientation='vertical')

这是结果:

我使用了对数色标,并为您的色标设置了一些合理的值,以使绘图具有可读性。另外我使用了 viridis 颜色图,因为jet is not a perceptually uniform colormap不应该使用

附言 我花了一段时间才加载您的数据集,因为您的示例根本不清楚。例如,您没有指定要绘制的数据字段或如何在数据集中读取。尝试编辑您的问题以使其更清晰!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多