matplotlibcartopyorthographic

Plotting data in orthographic projection using matplotlib & cartopy


I don't know how to get a map like the attached example but without coastlines, borders and gridlines outside plotted data. The second question is, instead of a square frame with lon and lats labels, is it possible to set the x and y axis along the plotted data outline, so that the labels are next to this outline, and not next to the frame?

import xarray as xr
from matplotlib import pyplot as plt
import cartopy.crs as ccrs
import cartopy

ds = xr.open_dataset(r'D:\Python\qq_z1000.nc')
ds2 = ds['qq'].mean(dim='time')
minn = ds2.min()
maxx = ds2.max()

fig = plt.figure(figsize=(8, 8), dpi=300, num="False")
central_lon, central_lat = 12.5, 47.5
extent = [-22.5, 45, 25, 65]
ax = plt.axes(projection=ccrs.Orthographic(central_lon, central_lat))
ax.set_extent(extent)

gl = ax.gridlines(draw_labels=True, linestyle='--', color='grey', dms=True, 
                  x_inline=False, y_inline=False, linewidth=0.3)
gl.top_labels = False
gl.right_labels = False
gl.xlabel_style = {'size': 10, 'color': 'black'}
gl.ylabel_style = {'size': 10, 'color': 'black'}
gl.xlocator = plt.FixedLocator(range(-180, 181, 10))

ax.coastlines(resolution='50m')
ax.add_feature(cartopy.feature.BORDERS, edgecolor='black')
im = ax.pcolormesh(ds2.longitude, ds2.latitude, ds2, transform=ccrs.PlateCarree(), 
                   cmap='jet', vmin=minn, vmax=maxx)

cbar = fig.colorbar(im, orientation='horizontal', pad=0.05, shrink=0.8)

#plt.savefig('my_map2.jpg', dpi=300, bbox_inches='tight')
plt.show()

my_map2

I've tried changing this line in the code in different ways, but to no avail.

im = ax.pcolormesh(ds2.longitude, ds2.latitude, ds2, transform=ccrs.PlateCarree(), cmap='jet', vmin=minn, vmax=maxx)


Solution

  • I managed to correct the code to get the map I wanted.

    import matplotlib.pyplot as plt
    import cartopy
    import cartopy.crs as ccrs
    import numpy as np
    import xarray as xr
    import matplotlib.path as mpath
    
    ds = xr.open_dataset(r'R:\Python\qnew_1000.nc')
    ds2 = ds['qq'].mean(dim='time')
    minn = ds2.min()
    maxx = ds2.max()
    
    noProj = ccrs.PlateCarree()
    myProj = ccrs.LambertConformal(central_longitude=0, central_latitude=55)
    myProj._threshold = myProj._threshold/20.
    
    plt.figure(figsize=(8,8))
    axs = plt.axes(projection=myProj)
    
    [axs_hdl] = axs.plot([60, -60, -60, 60, 60], [20, 20, 85, 85, 20],
             color='black', linewidth=0.5, marker='none',
             transform=noProj)
    
    tx_path = axs_hdl._get_transformed_path()
    path_in_data_coords, _ = tx_path.get_transformed_path_and_affine()
    
    polygon = mpath.Path(path_in_data_coords.vertices)
    axs.set_boundary(polygon) #This masks-out unwanted part of the plot
    axs.set_xmargin(0)
    axs.set_ymargin(0)
    axs.set_global()
    axs.add_feature(cartopy.feature.OCEAN, linewidth=.3, color='lightblue')
    axs.add_feature(cartopy.feature.LAND, zorder=1, edgecolor='black')
    axs.add_feature(cartopy.feature.COASTLINE, linewidth=0.5)
    axs.add_feature(cartopy.feature.BORDERS, linewidth=0.5)
    axs.set_extent([-60, 60, 20, 85], crs=noProj)
    axs.tick_params(axis='both', which='major', labelsize=10)
    axs.set_title("")
    gl=axs.gridlines(draw_labels=True, x_inline=False, y_inline=False, color='k', linestyle='dashed', linewidth=0.5)
    gl.top_labels = False
    
    pcm = axs.pcolormesh(ds2.longitude, ds2.latitude, ds2, transform=ccrs.PlateCarree(), 
                         vmin=minn, vmax=maxx, cmap='jet',
                         shading='nearest')
    
    cbar = plt.colorbar(pcm, ax=axs, orientation='horizontal', pad=0.08, shrink=0.8)
    cbar.set_label('(g kg$^{-1}$)')
    
    plt.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95, wspace=0.2, hspace=0.2)
    plt.savefig("figure.jpg", dpi=300, bbox_inches='tight', pad_inches=0.1, format='jpg', facecolor="w", transparent=False)
    plt.show()
    

    enter image description here