" Created on by Haolishen on 2021.6.2, in TianJin"
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.gridliner import LATITUDE_FORMATTER, LONGITUDE_FORMATTER
import warnings; warnings.filterwarnings('ignore')
plt.rcParams['font.family'] ='Times New Roman'
plt.rcParams['font.size'] = 12
def get_lambert_ticks(ax, ticks0, tick_location):
import shapely.geometry as sgeom
xmin,xmax,ymin,ymax = ax.get_extent()
lonmin,lonmax,latmin,latmax = ax.get_extent(ccrs.PlateCarree())
axises = {'left': [(xmin, ymin), (xmin, ymax)],'right': [(xmax, ymin), (xmax, ymax)],
'bottom': [(xmin, ymin), (xmax, ymin)], 'top': [(xmin, ymax), (xmax, ymax)],}
line_axis = sgeom.LineString(axises[tick_location])
ticks = []
N = 50
for tick1 in ticks0:
if( (tick_location.upper()=='TOP') | (tick_location.upper()=='BOTTOM')):
xy = np.vstack((np.zeros(N)+tick1, np.linspace(latmin-5, latmax+5, N, endpoint=True))).T
elif( (tick_location.upper()=='LEFT') | (tick_location.upper()=='RIGHT')):
xy = np.vstack((np.linspace(lonmin-5, lonmax+5, N, endpoint=True), np.zeros(N)+tick1)).T
proj_xy = (ax.projection.transform_points(ccrs.Geodetic(), xy[:,0], xy[:,1]))[:,:2]
line_lonlat = sgeom.LineString(proj_xy)
locs = line_axis.intersection(line_lonlat)
if not locs:
tick = [None]
else:
if( (tick_location.upper()=='TOP') | (tick_location.upper()=='BOTTOM')):
tick = locs.xy[0]
elif( (tick_location.upper()=='LEFT') | (tick_location.upper()=='RIGHT')):
tick = locs.xy[1]
ticks.append(tick[0])
ticklabels = ticks0
while True:
try:
index = ticks.index(None)
except ValueError:
break
ticks.pop(index)
ticklabels.pop(index)
return ticks, ticklabels
def lambert_yticks_left(ax, ticks, length, width, pad, fontdict=None):
" Draw ticks on the left y-axis of a Lamber Conformal projection. "
yticks, yticklabels = get_lambert_ticks(ax, ticks, 'left')
ax.yaxis.tick_left()
ax.set_yticks(yticks)
ax.set_yticklabels([ax.yaxis.get_major_formatter()(ytick) for ytick in yticklabels],fontdict)
ax.tick_params(axis='y',which='major',direction='out',length=length, width=width, pad=pad)
return
def lambert_yticks_right(ax, ticks,length, width, pad, fontdict=None):
" Draw ticks on the right y-axis of a Lamber Conformal projection. "
yticks, yticklabels = get_lambert_ticks(ax, ticks, 'right')
ax2 = ax.secondary_yaxis('right')
ax2.yaxis.tick_right()
ax2.set_yticks(yticks)
ax2.set_yticklabels([ax.yaxis.get_major_formatter()(ytick) for ytick in yticklabels],fontdict)
ax2.tick_params(axis='y',which='major',direction='out',length=length, width=width, pad=pad)
return
def lambert_xticks_bottom(ax, ticks, length, width, pad, fontdict=None):
" Draw ticks on the bottom x-axis of a Lambert Conformal projection. "
xticks, xticklabels = get_lambert_ticks(ax, ticks, 'bottom')
ax.xaxis.tick_bottom()
ax.set_xticks(xticks)
ax.set_xticklabels([ax.xaxis.get_major_formatter()(xtick) for xtick in xticklabels],fontdict)
ax.tick_params(axis='x',which='major',direction='out',length=length, width=width, pad=pad)
return
def lambert_xticks_top(ax, ticks, length, width, pad, fontdict=None):
" Draw ticks on the top x-axis of a Lambert Conformal projection. "
xticks, xticklabels = get_lambert_ticks(ax, ticks, 'top')
ax2 = ax.secondary_xaxis('top')
ax2.xaxis.tick_top()
ax2.set_xticks(xticks)
ax2.set_xticklabels([ax.xaxis.get_major_formatter()(xtick) for xtick in xticklabels],fontdict)
ax2.tick_params(axis='x',which='major',direction='out',length=length, width=width, pad=pad)
return
proj = ccrs.LambertConformal(central_longitude=110,central_latitude=30.0,standard_parallels=(25,47))
extent = [80, 135, 17, 53]
fig = plt.figure(figsize=(8,6))
ax = plt.axes(projection=proj)
ax.set_extent(extent, crs=ccrs.PlateCarree())
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.LAND)
ax.gridlines(draw_labels=None, xlocs=range(0
,180,10), ylocs=range(0,90,10), linestyle='--', linewidth=0.25, color='k')
xticks = [lon for lon in np.arange(70,160,10)]
yticks = [lat for lat in np.arange(0,60,10)]
ax.xaxis.set_major_formatter(LONGITUDE_FORMATTER)
ax.yaxis.set_major_formatter(LATITUDE_FORMATTER)
fig.canvas.draw()
lambert_xticks_top(ax, xticks, length=4, width=1.0, pad=0, fontdict={'family':'Times New Roman','size':12,'color':'k','rotation':0} )
lambert_yticks_right(ax, yticks, length=4, width=1.0, pad=2, fontdict={'family':'Times New Roman','size':12,'color':'k','rotation':0} )
lambert_xticks_bottom(ax, xticks, length=4, width=1.0, pad=2, fontdict={'family':'Times New Roman','size':12,'color':'k','rotation':0} )
lambert_yticks_left(ax, yticks, length=4, width=1.0, pad=1, fontdict={'family':'Times New Roman','size':12,'color':'k','rotation':0} )
plt.savefig(r'cartopy-lambert-loblat.png',dpi=600,bbox_inches='tight')