Plotting data in orthographic projection using matplotlib & cartopy

372 Views Asked by At

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)

1

There are 1 best solutions below

0
krzyba On BEST ANSWER

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