123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- import sys
- import numpy as nmp
- import matplotlib as mpl
- import matplotlib.pyplot as plt
- import matplotlib.colors as colors
- from math import trunc
- # Mine:
- import barakuda_orca as brkdo
- # Old savefig option:
- # savefig(cfignm+'.'+cfig_type, dpi=100, facecolor='w', edgecolor='w', orientation='portrait'
- # Time-series:
- WDTH_TS = 13.2
- FIG_SIZE_TS = (WDTH_TS,4.2)
- DPI_TS = 120
- AXES_TS = [0.08, 0.05, 0.89, 0.89]
- # For projections :
- # =================
- # lcc = Lambert conformal conic
- #
- # ['natarct', 'lcc', -60., 40., 80., 72., 55., -32., 10., 'l' ], # NATL + Arctic
- # my zone PROJ llcrnrlon llcrnrlat urcrnrlon urcrnrlat lat1 lon0 mer/par continent-res
- projection_def = [
- ['nseas', 'lcc', -55., 40., 55., 75., 60., -20., 10., 'l' ], # Nordic seas
- ['natarct', 'lcc', -52., 38., 110., 75., 60., -15., 10., 'l' ], # NATL + Arctic
- ['labir', 'lcc', -62., 48., -10., 75., 50., -30., 5., 'l' ],
- ['labsp', 'lcc', -60., 48., 50., 75.5, 50., -30., 10., 'l' ],
- ['npol', 'stere', -75., 45., 100., 60., 80., -30., 10., 'l' ],
- ['npol2', 'stere', -55., 40., 145., 40., 80., -5., 10., 'l' ], # North Pole
- ['spstere', 'stere', 0., 0., 0., 0., -48., 90., 10., 'l' ], # South Pole Default matplotlib!
- ['matl' , 'cyl', -82.,-21., 12., 79., 30., -30., 15., 'l' ], # Nordic seas
- ['atmed', 'lcc', -18., 33., -2., 42., 30., -10., 5., 'h' ],
- ['kav7' , 'kav', 0., 0., 0., 0., 0., 0., 0., 'l' ] ] # global map-monde
-
- #
- # ['spol2', 'stere', -45.,-35., 130., -35., -88., 5., 10., 'l' ], # South Pole
- # ['spol2','stere', -45.,-38., 130.,-35., -90., -5., 10., 'l' ], # South Pole
- #=================================================================================
- # ['natarct','lcc', -65., 35., 88., 70., 50., -30., 10., 'h' ], # NATL + Arctic
- def plot_nproj_extra(czone, rmin, rmax, dc, xlon, xlat, XF, XI,
- cfignm='fig', lkcont=False, cpal='jet', cbunit=' ',
- cfig_type='pdf', ctitle=' ', lforce_lim=False,
- cb_orient='vertical', i_cb_subsamp=1, dpi_fig=140,
- xlon_o=[ 0. ], xlat_o=[ 0. ], XI_o=[ 0. ], rice_crit=0.15):
- # Plot projection with basemap...
- #===================================================================================
- # INPUT:
- # xlon and xlat can be 1D or 2D !!!
- #
- #===================================================================================
-
- from mpl_toolkits.basemap import Basemap
- from mpl_toolkits.basemap import shiftgrid
- import barakuda_colmap
- font_ttl, font_ylb, font_clb = __font_unity__()
- # For projections :
- vp = __give_proj__(czone) ; # projection information
- l_ice_obs = False
- if len(nmp.shape(XI_o)) > 1: l_ice_obs = True
- # must work with XFtmp rather than XF, because sometimes XF is overwrited...
- [ny, nx] = nmp.shape(XF)
- XFtmp = nmp.zeros(ny*nx) ; XFtmp.shape = [ny, nx]
- XFtmp[:,:] = XF[:,:]
- XItmp = nmp.zeros(ny*nx) ; XItmp.shape = [ny, nx]
- XItmp[:,:] = XI[:,:]
-
- if l_ice_obs:
- [ny2, nx2] = nmp.shape(XI_o)
- XIotmp = nmp.zeros(ny2*nx2) ; XIotmp.shape = [ny2, nx2]
- XIotmp[:,:] = XI_o[:,:]
- if len(nmp.shape(xlat)) == 1 and len(nmp.shape(xlon)) == 1:
- #if czone == 'kav7' and xlon[0] >= 0.:
- # # Shifting data and longitude to be consistent with map projection
- # XItmp, xlon = shiftgrid(180.+xlon[0], XItmp, xlon, start=False, cyclic=360.0)
- # XFtmp, xlon = shiftgrid(180.+xlon[0], XFtmp, xlon, start=False, cyclic=360.0)
- LON_2D, LAT_2D = nmp.meshgrid(xlon,xlat)
- else:
- LAT_2D = nmp.zeros(ny*nx) ; LAT_2D.shape = [ny, nx] ; LAT_2D[:,:] = xlat[:,:]
- LON_2D = nmp.zeros(ny*nx) ; LON_2D.shape = [ny, nx] ; LON_2D[:,:] = xlon[:,:]
- if lforce_lim: __force_min_and_max__(rmin, rmax, XFtmp)
- vc = __vcontour__(rmin, rmax, dc)
- vci = __vcontour__(0., 1., 0.1)
- # Colorbar position/size if horizontal
- vcbar = [0.1, 0.08, 0.86, 0.03]
- # Figure/canvas size:
- if cb_orient == 'horizontal':
- if czone == 'natarct':
- vfig_size = [ 5.8, 5.6 ]; vsporg = [0.08, 0.1, 0.9, 0.92]
- vcbar = [0.05, 0.08, 0.9, 0.03]
- if czone == 'npol2':
- vfig_size = [ 4.4, 5.6 ]; vsporg = [0.01, 0.15, 1., 0.8]
- vcbar = [0.05, 0.065, 0.92, 0.03]
- if czone == 'kav7':
- vfig_size = [ 8.1, 5.6 ]; vsporg = [0.001, 0.15, 1., 0.8]
- vcbar = [0.04, 0.08, 0.92, 0.03]
-
- else:
- # Vertical color bar on the rhs
- vfig_size = [ 7., 7. ]; vsporg = [0.1, 0.1, 0.85, 0.85]
- if czone == 'nseas': vfig_size = [ 7., 5.4 ]; vsporg = [0.085, 0.03, 0.9, 0.94]
- if czone == 'natarct': vfig_size = [ 7.7, 7. ]; vsporg = [0.07, 0.033, 0.92, 0.93]
- if czone == 'spstere': vfig_size = [ 7., 5.8 ]; vsporg = [0.075, 0.035, 0.93, 0.93]
- if czone == 'npol2': vfig_size = [ 7., 7.1 ]; vsporg = [0.085, 0.03, 0.91, 0.94]
- #if czone == 'kav7': vfig_size = [ 7., 5. ]; vsporg = [0.085, 0.03, 0.91, 0.94]
-
-
- fig = plt.figure(num = 1, figsize=(vfig_size), dpi=None, facecolor='w', edgecolor='k')
- ax = plt.axes(vsporg, facecolor = 'w')
- ## Colmap:
- colmap = barakuda_colmap.chose_colmap(cpal)
- pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
- mpl.rcParams['contour.negative_linestyle'] = 'solid'; plt.contour.negative_linestyle='solid'
- colmapi = barakuda_colmap.chose_colmap('blanc')
- #pal_normi = colors.Normalize(vmin = 0., vmax = 1., clip = True)
-
- if vp[1] == 'lcc' or vp[1] == 'cyl' :
- carte = Basemap(llcrnrlon=vp[2],llcrnrlat=vp[3],urcrnrlon=vp[4],urcrnrlat=vp[5],\
- resolution=vp[9],area_thresh=1000.,projection=vp[1],\
- lat_1=vp[6],lon_0=vp[7])
- elif vp[1] == 'stere' :
- if vp[0] == 'spstere' or vp[0] == 'npstere':
- carte = Basemap(projection=vp[0], boundinglat=vp[6], lon_0=vp[7], resolution=vp[9])
- else:
- carte = Basemap(llcrnrlon=vp[2],llcrnrlat=vp[3],urcrnrlon=vp[4],urcrnrlat=vp[5],\
- resolution=vp[9],area_thresh=1000.,projection='stere',\
- lat_0=vp[6],lon_0=vp[7])
- elif vp[1] == 'kav' :
- print ' *** plot_nproj.barakuda_plot => Projection '+vp[0]+' / '+str(vp[7])+' / '+vp[9]
- carte = Basemap(projection=vp[0],lon_0=vp[7],resolution=vp[9])
-
- else:
- print 'ERROR: barakuda_plot.py => proj type '+vp[1]+' unknown!!!'; sys.exit(0)
- x0,y0 = carte(LON_2D,LAT_2D)
- if l_ice_obs:
- x2,y2 = carte(xlon_o,xlat_o)
-
- cf = carte.contourf(x0, y0, XFtmp, vc, cmap = colmap, norm = pal_norm)
- # Black contours if needed :
- if lkcont:
- ckf = carte.contour(x0, y0, XFtmp, vc, colors='k', linewidths=0.5)
- if cpal != 'ice':
- for c in cf.collections: c.set_zorder(0.5) # Changing zorder so black cont. on top
- for c in ckf.collections: c.set_zorder(0.5) # of filled cont. and under continents (zorder 1)
- # Adding Sea-ice:
- cfi = carte.contourf(x0, y0, XItmp, [rice_crit, 1.], cmap = colmapi)
- cf2 = carte.contour( x0, y0, XItmp, [rice_crit], colors='k', linewidths=0.5)
- for c in cfi.collections: c.set_zorder(0.75)
- for c in cf2.collections: c.set_zorder(1)
- if l_ice_obs:
- cf3 = carte.contour( x2, y2, XIotmp, [rice_crit], colors='r', linewidths=2.)
- for c in cf3.collections: c.set_zorder(1)
- carte.drawcoastlines() ; carte.fillcontinents(color='grey') ; carte.drawmapboundary()
-
- if vp[1] == 'lcc' or vp[1] == 'cyl':
- carte.drawmeridians(nmp.arange(-360,360,vp[8]), labels=[0,0,0,1])
- carte.drawparallels(nmp.arange( -90, 90,vp[8]), labels=[1,0,1,0])
- if vp[1] == 'stere':
- carte.drawmeridians(nmp.arange(-180,180,20), labels=[0,0,0,1])
- carte.drawparallels(nmp.arange( -90, 90,10), labels=[1,0,0,0])
- #plt.title(ctitle, **font_ttl)
- # ADDING COLORBAR
- # ===============
- if cb_orient == 'horizontal':
- clbax = fig.add_axes(vcbar) # axes for colorbar
- clb = plt.colorbar(cf, cax=clbax, ticks=vc, drawedges=lkcont, orientation='horizontal')
- for t in clb.ax.get_xticklabels(): t.set_font.size(10)
- else:
- clb = plt.colorbar(cf, ticks=vc, drawedges=lkcont)
- for t in clb.ax.get_yticklabels(): t.set_fontsize(16)
- if i_cb_subsamp > 1:
- cn_clb = [] ; jcpt = 0
- for rtck in vc:
- if jcpt % i_cb_subsamp == 0:
- if float(int(rtck)) == round(rtck,0):
- cn_clb.append(str(int(rtck))) ; # we can drop the ".0"
- else:
- cn_clb.append(str(rtck)) ; # keeping the decimals...
- else:
- cn_clb.append(' ')
- jcpt = jcpt + 1
- clb.ax.set_xticklabels(cn_clb)
- clb.set_label('('+cbunit+')', **font_clb)
- font_lab = { 'fontname':'Arial', 'fontweight':'normal', 'fontsize':24 }
- ax.annotate(ctitle, xy=(0.4, 0.95), xycoords='axes fraction', **font_lab)
- plt.savefig(cfignm+'.'+cfig_type, dpi=dpi_fig, orientation='portrait', transparent=True) ; #, transparent=True, acecolor='w', edgecolor='w',
- plt.close(1)
- del LON_2D, LAT_2D, XFtmp
- return
- # LOCAL functions
- # ===============
- def __message__(ccr):
- # Find the CONF from CONF-EXP and exit if CONF does not exist!
- i = 0 ; conf = ''
- while i < len(ccr) and ccr[i] != '-' : conf = conf+ccr[i]; i=i+1
- print 'conf =', conf, '\n'
- return conf
- def __get_mat__(cf):
- f1 = open(cf, 'r') # for reading
- lines1=f1.readlines()
- f1.close()
- zm = []
- jy = 0
- for l in lines1:
- if l[0] != '#':
- jy = jy + 1
- ls = l.split()
- zm.append([])
- for c in ls:
- zm[jy-1].append(float(c))
- zxm = array(zm)
- print 'Shape zxm = ',nmp.shape(zxm), '\n'
- return zxm
- def __vcontour__(zmin, zmax, zdc):
- #
- #
- lngt = zmax - zmin
- #
- ncont = lngt/zdc
- #
- vcont = nmp.arange(zmin, zmax + zdc, zdc)
- #
- #lat_min
- return vcont
- def __name_coor_ticks__(lon_min=0., lon_max=360., dlon=30., lat_min=-90., lat_max=90., dlat=15., lon_ext=0):
- #
- # Builds nice ticks for X and Y (lon, lat) axes!
- #
- # Arrange longitude axis !
- VX = nmp.arange(lon_min, lon_max+lon_ext+dlon, dlon); VX0 = nmp.arange(lon_min, lon_max+lon_ext+dlon, dlon);
- ivf = nmp.where(VX>180); VX0[ivf] = VX[ivf] - 360
- cn_lon = []
- for rlon in VX0:
- jlon = int(rlon)
- if jlon < 0:
- cn_lon.append(str(-jlon)+r'$^{\circ}$W')
- else:
- if jlon == 0:
- cn_lon.append(str(jlon)+r'$^{\circ}$')
- else:
- cn_lon.append(str(jlon)+r'$^{\circ}$E')
- #
- # Arrange latitude axis !
- VY = nmp.arange(lat_min, lat_max+dlat, dlat)
- cn_lat = []
- for rlat in VY:
- jlat = int(rlat)
- if jlat < 0:
- cn_lat.append(str(-jlat)+r'$^{\circ}$S')
- else:
- if jlat == 0:
- cn_lat.append(str(jlat)+r'$^{\circ}$')
- else:
- cn_lat.append(str(jlat)+r'$^{\circ}$N')
- #
- return VX, VY, cn_lon, cn_lat
- def __give_proj__(cname):
- #
- #
- nb =nmp.shape(projection_def)[0] ; #print 'nb =', nb
- #
- # Initializing :
- vproj = [ 'NC', 'NC', 0., 0., 0., 0., 0., 0., 'NC' ]
- #
- #
- jb = 0
- while jb < nb :
- if projection_def[jb][0] == cname:
- break
- else :
- jb = jb + 1
- #
- if jb == nb :
- print 'Zone "'+cname+'" does not exist!\n'
- print 'so far choice is :'
- for jb in range(nb): print projection_def[jb][0]
- sys.exit(0)
- #
- #
- vproj = projection_def[jb][:]
- #
- #print 'For ', projection_def[jb][0], ' we have vproj =', vproj, '\n'
- #
- return vproj
- def __font_unity__():
- #
- params = {'font.family':'Arial','font.size':16,'xtick.labelsize':16,'ytick.labelsize':16,'axes.labelsize':16}
- mpl.rcParams.update(params)
- big_fixed_fonts = { 'fontname':'Arial', 'fontweight':'normal', 'fontsize':16 }
- label_fonts = { 'fontname':'Arial', 'fontweight':'normal', 'fontsize':16 }
- colorbar_fonts = { 'fontname':'Arial', 'fontweight':'normal', 'fontsize':16 }
- return big_fixed_fonts, label_fonts, colorbar_fonts
- def __force_min_and_max__(rm, rp, Xin):
- idx_bad = nmp.where(nmp.logical_not(nmp.isfinite(Xin)))
- Xin[idx_bad] = 0.
- idx1 = nmp.where(Xin <= rm); Xin[idx1] = rm + abs(rp-rm)*1.E-4
- idx2 = nmp.where(Xin >= rp); Xin[idx2] = rp - abs(rp-rm)*1.E-4
- Xin[idx_bad] = nmp.nan
- def __font_unity_big__():
- #
- params = {'font.family':'Trebuchet MS','text.fontsize':20,'xtick.labelsize':16,'ytick.labelsize': 16,'axes.labelsize':18}
- mpl.rcParams.update(params)
- title_fonts = { 'fontname':'Trebuchet MS', 'fontweight':'normal', 'fontsize':20 }
- big_fixed_fonts = { 'fontname':'monaco', 'fontweight':'normal', 'fontsize':20 }
- label_fonts = { 'fontname':'Trebuchet MS', 'fontweight':'normal', 'fontsize':16 }
- colorbar_fonts = { 'fontname':'Tahoma', 'fontweight':'normal', 'fontsize':14 }
- return title_fonts, big_fixed_fonts, label_fonts, colorbar_fonts
-
- # params = { 'font.family': 'Ubuntu Mono',
- # 'legend.fontsize': 14,
- # 'text.fontsize': 14,
- # 'xtick.labelsize': 12,
- # 'ytick.labelsize': 12,
- # 'axes.labelsize': 14}
- # mpl.rcParams.update(params)
- #
- # font_ttl = { 'fontname':'Bitstream Vera Sans Mono', 'fontweight':'normal', 'fontsize':14 }
- # font_ylb = { 'fontname':'Tahoma', 'fontweight':'normal', 'fontsize':12 }
|