【问题标题】:Axis labels for LambertConformal in cartopy at wrong location错误位置的 cartopy 中 LambertConformal 的轴标签
【发布时间】:2021-06-04 14:38:03
【问题描述】:

我想在 LambertConformal 投影中绘制一些数据并向坐标轴添加标签。请参阅下面的示例代码。但是,现在 x-labels 出现了两次,而且两次都出现在图的中间,而不是在图的底部。相反,当我设置 gl.xlabels_bottom = Falsegl.xlabels_top = True 时,根本不会绘制任何 x 标签。使用 y 标签,我没有遇到这个问题;它们只是沿着绘图的左边界或右边界很好地绘制。 如何在正确的位置(图的底部)获取 x 标签?

import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
 
bounds_lon = [-45,-25]
bounds_lat = [55,65]
lon = np.arange(bounds_lon[0],bounds_lon[1]+0.1,0.1)
lat = np.arange(bounds_lat[0],bounds_lat[1]+0.1,0.1)
Lon, Lat = np.meshgrid(lon,lat)
data = np.ones(np.shape(Lon))

data_crs = ccrs.PlateCarree()
projection = ccrs.LambertConformal(central_longitude=np.mean(bounds_lon),central_latitude=np.mean(bounds_lat),cutoff=bounds_lat[0])

plt.figure(figsize=(4,4))
ax = plt.axes(projection=projection)
ax.coastlines()
ax.contourf(Lon, Lat, data, transform=data_crs)

gl = ax.gridlines(crs=ccrs.PlateCarree(), linewidth=2, color='gray', alpha=0.5, linestyle='--')
gl.xlabels_bottom = True

【问题讨论】:

    标签: python matplotlib axis-labels cartopy


    【解决方案1】:

    需要手动重新定位刻度标签。要成功地做到这一点,需要对绘图设置进行一些其他调整。这是您可以尝试的代码。

    import numpy as np
    import matplotlib.pyplot as plt
    import cartopy.crs as ccrs
    
    bounds_lon = [-45,-25]
    bounds_lat = [55,65]
    
    # make-up data to plot on the map
    inc = 0.5
    lon = np.arange(bounds_lon[0],bounds_lon[1]+inc, inc)
    lat = np.arange(bounds_lat[0],bounds_lat[1]+inc, inc)
    Lon, Lat = np.meshgrid(lon,lat)
    
    #data = np.ones(np.shape(Lon))  # original `boring` data
    data = np.sin(Lon)+np.cos(Lat)  # better data to use instead
    
    data_crs = ccrs.PlateCarree()
    projection = ccrs.LambertConformal(central_longitude=np.mean(bounds_lon), \
                                       central_latitude=np.mean(bounds_lat), \
                                       #cutoff=bounds_lat[0]
                                      )
    
    # Note: `cutoff` causes horizontal cut at lower edge
    
    # init plot figure
    plt.figure(figsize=(15,9))
    ax = plt.axes(projection=projection)
    ax.coastlines(lw=0.2)
    ax.contourf(Lon, Lat, data, transform=data_crs, alpha=0.5)
    
    # set gridlines specs
    gl = ax.gridlines(crs=ccrs.PlateCarree(), linewidth=2, color='gray', alpha=0.5, linestyle='--')
    
    gl.top_labels=True
    gl.bottom_labels=True
    gl.left_labels=True
    gl.right_labels=True
    
    plt.draw()  #enable access to lables' positions
    xs_ys = ax.get_extent()  #(x0,x1, y0,y1)
    #dx = xs_ys[1]-xs_ys[0]
    dy = xs_ys[3]-xs_ys[2]
    
    # The extent of `ax` must be adjusted
    # Extents' below and above are increased
    new_ext = [xs_ys[0], xs_ys[1], xs_ys[2]-dy/15., xs_ys[3]+dy/12.] 
    ax.set_extent(new_ext, crs=projection)
    
    # find locations of the labels and reposition them as needed
    xs, ys = [], []
    for ix,ea in enumerate(gl.label_artists):
        xy = ea[2].get_position()
        xs.append(xy[0])
        ys.append(xy[1])
    
        # Targeted labels to manipulate has "W" in them
        if "W" in ea[2].get_text():
            x_y = ea[2].get_position()
    
            # to check which are above/below mid latitude of the plot
            # use 60 (valid only this special case)
            if x_y[1]<60:
                # labels at lower latitudes
                curpos = ea[2].get_position()
                newpos = (curpos[0], 54.7)        # <- from inspection: 54.7
                ea[2].set_position(newpos)
            else:
                curpos = ea[2].get_position()
                newpos = (curpos[0], 65.3)        # <- from inspection: 65.3
                ea[2].set_position(newpos)
    
    plt.show()
    

    编辑1

    如果您想将所有纬度/经度标签移到外部边缘,请尝试此代码。比上面的要简洁很多。

    import numpy as np
    import matplotlib.pyplot as plt
    import cartopy.crs as ccrs
    
    bounds_lon = [-45,-25]
    bounds_lat = [55,65]
    
    inc = 0.5
    lon = np.arange(bounds_lon[0],bounds_lon[1]+inc, inc)
    lat = np.arange(bounds_lat[0],bounds_lat[1]+inc, inc)
    Lon, Lat = np.meshgrid(lon,lat)
    #data = np.ones(np.shape(Lon))  # boring data
    data = np.sin(Lon)+np.cos(Lat)  # more interesting
    
    data_crs = ccrs.PlateCarree()
    projection = ccrs.LambertConformal(central_longitude=np.mean(bounds_lon), \
                                       central_latitude=np.mean(bounds_lat), \
                                       cutoff=bounds_lat[0]
                                      )
    
    # init plot
    plt.figure(figsize=(15,9))
    ax = plt.axes(projection=projection)
    ax.coastlines(lw=0.2)
    ax.contourf(Lon, Lat, data, transform=data_crs, alpha=0.3)
    
    gl = ax.gridlines(draw_labels=True, x_inline=False, y_inline=False,
                  color='k', linestyle='dashed', linewidth=0.5)
    
    gl.top_labels=True
    gl.bottom_labels=True
    gl.left_labels=True
    gl.right_labels=True
    
    plt.show()
    

    如果你想得到一条直线的底边,你可以通过从这行代码中删除选项cutoff=bounds_lat[0]来实现:-

    projection = ccrs.LambertConformal(central_longitude=np.mean(bounds_lon), \
                                   central_latitude=np.mean(bounds_lat), \
                                   cutoff=bounds_lat[0]
                                  )
    

    这样就变成了

    projection = ccrs.LambertConformal(central_longitude=np.mean(bounds_lon),
                   central_latitude=np.mean(bounds_lat))
    

    你会得到这样的情节:-

    【讨论】:

    • 谢谢! x_inline=False 对我有用。
    猜你喜欢
    • 2015-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    相关资源
    最近更新 更多