【问题标题】:Plotting oceans in maps using basemap and python使用底图和 python 在地图中绘制海洋
【发布时间】:2015-08-20 22:26:35
【问题描述】:

我正在绘制此处可用的 netCDF 文件: https://goo.gl/QyUI4J

使用下面的代码,地图如下所示:

但是,我希望海洋是白色的。更好的是,我希望能够指定海洋的颜色。如何更改下面的代码来做到这一点?现在,问题是海洋正在被绘制在数据尺度上。 (请注意,netCDF 文件很大,大约 3.5 GB)。

import pdb, os, glob, netCDF4, numpy
from matplotlib import pyplot as plt
from mpl_toolkits.basemap import Basemap

def plot_map(path_nc, var_name):
    """
    Plot var_name variable from netCDF file
    :param path_nc: Name of netCDF file
    :param var_name: Name of variable in netCDF file to plot on map
    :return: Nothing, side-effect: plot an image
    """

    nc = netCDF4.Dataset(path_nc, 'r', format='NETCDF4')
    tmax  = nc.variables['time'][:]

    m = Basemap(projection='robin',resolution='c',lat_0=0,lon_0=0)

    m.drawcoastlines()
    m.drawcountries()

    # find x,y of map projection grid.
    lons, lats = get_latlon_data(path_nc)
    lons, lats = numpy.meshgrid(lons, lats)
    x, y = m(lons, lats)
    nc_vars = numpy.array(nc.variables[var_name])

    # Plot!
    m.drawlsmask(land_color='white',ocean_color='white')
    cs = m.contourf(x,y,nc_vars[len(tmax)-1,:,:],numpy.arange(0.0,1.0,0.1),cmap=plt.cm.RdBu)

    # add colorbar
    cb = m.colorbar(cs,"bottom", size="5%", pad='2%')
    cb.set_label('Land cover percentage '+var_name+' in '+os.path.basename(path_nc))

    plt.show()


plot_map('perc_crops.nc','LU_Corn.nc')

【问题讨论】:

  • get_latlon_data 是什么?

标签: python plot matplotlib-basemap


【解决方案1】:

您需要在 nc_vars 数据集上使用 maskoceans

contourf之前,插入这个

nc_new = maskoceans(lons,lats,nc_vars[len(tmax)-1,:,:])

然后使用新屏蔽的数据集调用contourf,即

cs = m.contourf(x,y,nc_new,numpy.arange(0.0,1.0,0.1),cmap=plt.cm.RdBu)

要指定海洋颜色,如果您想要白色海洋,您可以拨打drawslmask 或在该呼叫中指定海洋颜色 - 例如插入m.drawlsmask(land_color='white',ocean_color='cyan')

我在下面给出了对您的代码进行尽可能少改动的工作代码。取消对drawslmask 的调用以查看青色海洋。

输出

代码的完整工作版本

import pdb, os, glob, netCDF4, numpy
from matplotlib import pyplot as plt
from mpl_toolkits.basemap import Basemap, maskoceans

def plot_map(path_nc, var_name):
    """
    Plot var_name variable from netCDF file
    :param path_nc: Name of netCDF file
    :param var_name: Name of variable in netCDF file to plot on map
    :return: Nothing, side-effect: plot an image
    """

    nc = netCDF4.Dataset(path_nc, 'r', format='NETCDF4')
    tmax  = nc.variables['time'][:]

    m = Basemap(projection='robin',resolution='c',lat_0=0,lon_0=0)

    m.drawcoastlines()
    m.drawcountries()    

    # find x,y of map projection grid.
    lons, lats = nc.variables['lon'][:],nc.variables['lat'][:]
    # N.B. I had to substitute the above for unknown function get_latlon_data(path_nc)
    # I guess it does the same job

    lons, lats = numpy.meshgrid(lons, lats)
    x, y = m(lons, lats)
    nc_vars = numpy.array(nc.variables[var_name])
    
    #mask the oceans in your dataset
    nc_new = maskoceans(lons,lats,nc_vars[len(tmax)-1,:,:])
    
    #plot!
    #optionally give the oceans a colour with the line below
    #Note - if land_color is omitted it will default to grey
    #m.drawlsmask(land_color='white',ocean_color='cyan')
    cs = m.contourf(x,y,nc_new,numpy.arange(0.0,1.0,0.1),cmap=plt.cm.RdBu)

    # add colorbar
    cb = m.colorbar(cs,"bottom", size="5%", pad='2%')
    cb.set_label('Land cover percentage '+var_name+' in '+os.path.basename(path_nc))

    plt.show()


plot_map('perc_crops.nc','LU_Corn.nc')

P.S.这是一个要测试的大文件!

【讨论】:

    【解决方案2】:

    合法的好解决方案是使用效用函数maskoceans,它接受一个数据数组并掩盖海洋和湖泊中的所有点。

    相反,您可以采取简单的方法。先画出等高线图,然后使用drawlsmask,它允许透明色:

    # Colors can be RGBA tuples
    m.drawlsmask(land_color=(0, 0, 0, 0), ocean_color='deeppink', lakes=True)
    

    土地是透明的,可以让等高线图显示出来。

    【讨论】:

      【解决方案3】:

      您在地图中看到的颜色与传递给 contourcf 函数的颜色图 cm.plt.RdBu 有关。您需要更改此颜色图以达到您想要的结果。 Here你可以找到底图颜色图的教程。

      【讨论】:

      • 感谢@rflkortekaas,这与颜色图无关。问题是海洋在这个 netCDF 中的值是 0.0 或更低。当我绘制数据时,它们的颜色与具有 0.0 值的土地像素相同。我希望单独绘制海洋(白色或我选择的其他颜色)
      • 它与颜色图有关,但您上面的信息不清楚。底图上有一个选项可以遮盖阵列中的海洋,也许您可​​以通过它实现您的要求。
      • 我在 drawlsmask 中将 ocean_color 设置为白色,但它似乎不起作用
      • 这不起作用,因为contourf覆盖了drawlsmask。因此,您的 contourf 函数从颜色图中用红色绘制海洋,并从 drawlsmask 将其绘制在白色海洋上。
      • 是的,但是将 drawslmask 移动到 contourf 下面也无济于事。
      猜你喜欢
      • 1970-01-01
      • 2016-04-02
      • 2020-05-08
      • 2018-07-15
      • 1970-01-01
      • 2013-07-05
      • 2022-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多