【问题标题】:lat lon alignment in basemap's pcolormesh method - feature or bug?底图的 pcolormesh 方法中的经纬度对齐 - 功能还是错误?
【发布时间】:2016-02-19 10:41:19
【问题描述】:

我正在使用 Matplotlib 和底图在地图上绘制网格数据。我正在使用此代码将 pcolormesh 方法与散点图进行比较:

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
# setup of basemap ('lcc' = lambert conformal conic).
# use major and minor sphere radii from WGS84 ellipsoid.
m = Basemap(width=12000000,height=9000000,
            rsphere=(6378137.00,6356752.3142),\
            resolution='l',area_thresh=1000.,projection='lcc',\
            lat_1=projection['standard_parallel'][0],\
            lat_2=projection['standard_parallel'][1],\
            lat_0=projection['latitude_of_projection_origin'],\
            lon_0=projection['longitude_of_central_meridian'])
x, y = m(lons, lats) # compute map proj coordinates.
# draw coastlines and political boundaries.
m.drawcoastlines()
m.drawcountries()
m.drawstates()
# draw parallels and meridians.
# label on left and bottom of map.
parallels = np.arange(0.,80,20.)
m.drawparallels(parallels,labels=[1,0,0,1])
meridians = np.arange(10.,360.,30.)
m.drawmeridians(meridians,labels=[1,0,0,1])
#cs = m.pcolormesh(x,y,data) 
cs = m.pcolormesh(x,y,data,shading='flat',cmap=plt.cm.rainbow) 
cb = m.colorbar(cs,"right", size="5%", pad='2%', ticks=V[0::5])
m.scatter(x*data,y*data, marker='.', s=100, c='g')
ax.set_title(title)
plt.show(block=False)

我得到的情节是这样的:

请注意,经纬度坐标对应于每个网格框的左下角。这是设计使然还是错误?我会按设计思考,但我看到的所有示例 (http://matplotlib.org/basemap/users/examples.html) 都没有提及它。我想要以 lon lat 坐标点为中心的网格单元,它们本身位于不规则网格上(lons、lats 变量是二维数组)。我如何做到这一点?

注意。这里的 data 变量只是一个掩码,对应于 one 或 nans。

谢谢。

已编辑:根据 Tom 的建议,如果我尝试使用 contourf,我会得到以下图像(放大到与第一张图像大致相同)。

它仍然不能很好地处理边缘,因为它无法在有限值和 nan 之间绘制曲面,因此有很多缺失点。我希望渲染每个网格单元。似乎 imshow 可以做我想做的事,但这似乎只适用于常规(线性)网格。

【问题讨论】:

    标签: dictionary matplotlib matplotlib-basemap


    【解决方案1】:

    pcolormesh 将节点坐标作为XY 参数。从docs(到pcolor,但它与pcolormesh 相同):

    XY,如果给定,指定颜色的 (x, y) 坐标 四边形; C[i,j] 的四边形在以下位置有角:

    (X[i,   j],   Y[i,   j]), 
    (X[i,   j+1], Y[i,   j+1]), 
    (X[i+1, j],   Y[i+1, j]), 
    (X[i+1, j+1], Y[i+1, j+1]).
    

    理想情况下,X 和 Y 的尺寸应该比 C 大一;如果维度相同,则 C 的最后一行和最后一列将被忽略。

    我建议对 xy 中每个四边形点的 x 和 y 坐标进行平均,然后将这些坐标用于 scatter,以使您的点居中。

    【讨论】:

    • 谢谢,这肯定澄清了事情。但是,我的散点已经在正确的位置。相反,它是我想要轻推的 pcolormesh,以便每个网格单元都以点为中心。此外,鉴于我有不规则的纬度网格,我不确定如何手动计算每个四边形的质心。
    • contourf 使用细胞中心。这对你有用而不是 pcolormesh 吗?
    【解决方案2】:

    您可以手动调整 lon 和 lat 数据,将它们向下和向左移动 1/2 网格间距。然后当你绘制它时,原始的 lons 和 lats 将位于每个像素的中心。此代码还为 lons 和 lats 数组的每个维度添加一个,以便它们比数据本身的维度大一,documentation 状态是理想的。

    # Subtract 1/2 the grid size from both lon and lat arrays
    lons = lons - dlon/2
    lats = lats - dlat/2
    # Add 1 grid spacing to the right column of lon array and concatenate it as an additional column to the right
    lons = np.c_[ lons, lons[:,-1]+dlon ]
    # Duplicate the bottom row of the lon array and concatenate it to the bottom
    lons = np.r_[ lons, [lons[-1,:]] ]
    # Duplicate the right-most column of lats array and concatenate it on the right
    lats = np.c_[ lats, lats[:,-1] ]
    # Add 1 grid spacing to the bottom row of lat array and concatenate it as an additional row below
    lats = np.r_[ lats, [lats[-1,:]+dlat] ]
    
    # Then plot as before
    m.pcolormesh(lons, lats, data)
    

    【讨论】:

      【解决方案3】:

      要从二维中心网格点数组计算左下角,请使用以下平均例程:

      # adjust xlon,xlat values so they represent corners of grid cells for mapping using pcolor
      # calculate average between two points and reassign lat/lon pairs
      # skip first row and column of data since there are no points outside of domain to average with
      
      # define empty arrays for storing new lats, lons, and values
      corner_lats=np.empty([len(xlat[:,0])-1, len(xlat[0,:])-1],float)
      corner_lons=np.empty([len(xlat[:,0])-1, len(xlat[0,:])-1],float)
      corner_values=np.zeros([len(xlat[:,0])-1, len(xlat[0,:])-1],float)
      
      # go through each xlat and xlon array and calculate LL corners
      for lat in range(1,len(xlat[:,0])-1):
          for lon in range(1,len(xlat[0,:])-1):
              corner_lats[lat,lon]=(xlat[lat,lon]+xlat[lat+1,lon])/2
              corner_lons[lat,lon]=(xlon[lat,lon]+xlon[lat,lon+1])/2
              corner_values[lat-1,lon-1]=data[lat,lon]
      

      然后在映射时,使用新的角纬度、经度和值:

      m.pcolor(corner_lons,corner_lats,corner_values,latlon=True)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-20
        • 1970-01-01
        • 2017-08-19
        • 1970-01-01
        • 1970-01-01
        • 2017-11-12
        • 2021-02-08
        • 1970-01-01
        相关资源
        最近更新 更多