barakuda_plot_extra.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. import sys
  2. import numpy as nmp
  3. import matplotlib as mpl
  4. import matplotlib.pyplot as plt
  5. import matplotlib.colors as colors
  6. from math import trunc
  7. # Mine:
  8. import barakuda_orca as brkdo
  9. # Old savefig option:
  10. # savefig(cfignm+'.'+cfig_type, dpi=100, facecolor='w', edgecolor='w', orientation='portrait'
  11. # Time-series:
  12. WDTH_TS = 13.2
  13. FIG_SIZE_TS = (WDTH_TS,4.2)
  14. DPI_TS = 120
  15. AXES_TS = [0.08, 0.05, 0.89, 0.89]
  16. # For projections :
  17. # =================
  18. # lcc = Lambert conformal conic
  19. #
  20. # ['natarct', 'lcc', -60., 40., 80., 72., 55., -32., 10., 'l' ], # NATL + Arctic
  21. # my zone PROJ llcrnrlon llcrnrlat urcrnrlon urcrnrlat lat1 lon0 mer/par continent-res
  22. projection_def = [
  23. ['nseas', 'lcc', -55., 40., 55., 75., 60., -20., 10., 'l' ], # Nordic seas
  24. ['natarct', 'lcc', -52., 38., 110., 75., 60., -15., 10., 'l' ], # NATL + Arctic
  25. ['labir', 'lcc', -62., 48., -10., 75., 50., -30., 5., 'l' ],
  26. ['labsp', 'lcc', -60., 48., 50., 75.5, 50., -30., 10., 'l' ],
  27. ['npol', 'stere', -75., 45., 100., 60., 80., -30., 10., 'l' ],
  28. ['npol2', 'stere', -55., 40., 145., 40., 80., -5., 10., 'l' ], # North Pole
  29. ['spstere', 'stere', 0., 0., 0., 0., -48., 90., 10., 'l' ], # South Pole Default matplotlib!
  30. ['matl' , 'cyl', -82.,-21., 12., 79., 30., -30., 15., 'l' ], # Nordic seas
  31. ['atmed', 'lcc', -18., 33., -2., 42., 30., -10., 5., 'h' ],
  32. ['kav7' , 'kav', 0., 0., 0., 0., 0., 0., 0., 'l' ] ] # global map-monde
  33. #
  34. # ['spol2', 'stere', -45.,-35., 130., -35., -88., 5., 10., 'l' ], # South Pole
  35. # ['spol2','stere', -45.,-38., 130.,-35., -90., -5., 10., 'l' ], # South Pole
  36. #=================================================================================
  37. # ['natarct','lcc', -65., 35., 88., 70., 50., -30., 10., 'h' ], # NATL + Arctic
  38. def plot_nproj_extra(czone, rmin, rmax, dc, xlon, xlat, XF, XI,
  39. cfignm='fig', lkcont=False, cpal='jet', cbunit=' ',
  40. cfig_type='pdf', ctitle=' ', lforce_lim=False,
  41. cb_orient='vertical', i_cb_subsamp=1, dpi_fig=140,
  42. xlon_o=[ 0. ], xlat_o=[ 0. ], XI_o=[ 0. ], rice_crit=0.15):
  43. # Plot projection with basemap...
  44. #===================================================================================
  45. # INPUT:
  46. # xlon and xlat can be 1D or 2D !!!
  47. #
  48. #===================================================================================
  49. from mpl_toolkits.basemap import Basemap
  50. from mpl_toolkits.basemap import shiftgrid
  51. import barakuda_colmap
  52. font_ttl, font_ylb, font_clb = __font_unity__()
  53. # For projections :
  54. vp = __give_proj__(czone) ; # projection information
  55. l_ice_obs = False
  56. if len(nmp.shape(XI_o)) > 1: l_ice_obs = True
  57. # must work with XFtmp rather than XF, because sometimes XF is overwrited...
  58. [ny, nx] = nmp.shape(XF)
  59. XFtmp = nmp.zeros(ny*nx) ; XFtmp.shape = [ny, nx]
  60. XFtmp[:,:] = XF[:,:]
  61. XItmp = nmp.zeros(ny*nx) ; XItmp.shape = [ny, nx]
  62. XItmp[:,:] = XI[:,:]
  63. if l_ice_obs:
  64. [ny2, nx2] = nmp.shape(XI_o)
  65. XIotmp = nmp.zeros(ny2*nx2) ; XIotmp.shape = [ny2, nx2]
  66. XIotmp[:,:] = XI_o[:,:]
  67. if len(nmp.shape(xlat)) == 1 and len(nmp.shape(xlon)) == 1:
  68. #if czone == 'kav7' and xlon[0] >= 0.:
  69. # # Shifting data and longitude to be consistent with map projection
  70. # XItmp, xlon = shiftgrid(180.+xlon[0], XItmp, xlon, start=False, cyclic=360.0)
  71. # XFtmp, xlon = shiftgrid(180.+xlon[0], XFtmp, xlon, start=False, cyclic=360.0)
  72. LON_2D, LAT_2D = nmp.meshgrid(xlon,xlat)
  73. else:
  74. LAT_2D = nmp.zeros(ny*nx) ; LAT_2D.shape = [ny, nx] ; LAT_2D[:,:] = xlat[:,:]
  75. LON_2D = nmp.zeros(ny*nx) ; LON_2D.shape = [ny, nx] ; LON_2D[:,:] = xlon[:,:]
  76. if lforce_lim: __force_min_and_max__(rmin, rmax, XFtmp)
  77. vc = __vcontour__(rmin, rmax, dc)
  78. vci = __vcontour__(0., 1., 0.1)
  79. # Colorbar position/size if horizontal
  80. vcbar = [0.1, 0.08, 0.86, 0.03]
  81. # Figure/canvas size:
  82. if cb_orient == 'horizontal':
  83. if czone == 'natarct':
  84. vfig_size = [ 5.8, 5.6 ]; vsporg = [0.08, 0.1, 0.9, 0.92]
  85. vcbar = [0.05, 0.08, 0.9, 0.03]
  86. if czone == 'npol2':
  87. vfig_size = [ 4.4, 5.6 ]; vsporg = [0.01, 0.15, 1., 0.8]
  88. vcbar = [0.05, 0.065, 0.92, 0.03]
  89. if czone == 'kav7':
  90. vfig_size = [ 8.1, 5.6 ]; vsporg = [0.001, 0.15, 1., 0.8]
  91. vcbar = [0.04, 0.08, 0.92, 0.03]
  92. else:
  93. # Vertical color bar on the rhs
  94. vfig_size = [ 7., 7. ]; vsporg = [0.1, 0.1, 0.85, 0.85]
  95. if czone == 'nseas': vfig_size = [ 7., 5.4 ]; vsporg = [0.085, 0.03, 0.9, 0.94]
  96. if czone == 'natarct': vfig_size = [ 7.7, 7. ]; vsporg = [0.07, 0.033, 0.92, 0.93]
  97. if czone == 'spstere': vfig_size = [ 7., 5.8 ]; vsporg = [0.075, 0.035, 0.93, 0.93]
  98. if czone == 'npol2': vfig_size = [ 7., 7.1 ]; vsporg = [0.085, 0.03, 0.91, 0.94]
  99. #if czone == 'kav7': vfig_size = [ 7., 5. ]; vsporg = [0.085, 0.03, 0.91, 0.94]
  100. fig = plt.figure(num = 1, figsize=(vfig_size), dpi=None, facecolor='w', edgecolor='k')
  101. ax = plt.axes(vsporg, facecolor = 'w')
  102. ## Colmap:
  103. colmap = barakuda_colmap.chose_colmap(cpal)
  104. pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
  105. mpl.rcParams['contour.negative_linestyle'] = 'solid'; plt.contour.negative_linestyle='solid'
  106. colmapi = barakuda_colmap.chose_colmap('blanc')
  107. #pal_normi = colors.Normalize(vmin = 0., vmax = 1., clip = True)
  108. if vp[1] == 'lcc' or vp[1] == 'cyl' :
  109. carte = Basemap(llcrnrlon=vp[2],llcrnrlat=vp[3],urcrnrlon=vp[4],urcrnrlat=vp[5],\
  110. resolution=vp[9],area_thresh=1000.,projection=vp[1],\
  111. lat_1=vp[6],lon_0=vp[7])
  112. elif vp[1] == 'stere' :
  113. if vp[0] == 'spstere' or vp[0] == 'npstere':
  114. carte = Basemap(projection=vp[0], boundinglat=vp[6], lon_0=vp[7], resolution=vp[9])
  115. else:
  116. carte = Basemap(llcrnrlon=vp[2],llcrnrlat=vp[3],urcrnrlon=vp[4],urcrnrlat=vp[5],\
  117. resolution=vp[9],area_thresh=1000.,projection='stere',\
  118. lat_0=vp[6],lon_0=vp[7])
  119. elif vp[1] == 'kav' :
  120. print ' *** plot_nproj.barakuda_plot => Projection '+vp[0]+' / '+str(vp[7])+' / '+vp[9]
  121. carte = Basemap(projection=vp[0],lon_0=vp[7],resolution=vp[9])
  122. else:
  123. print 'ERROR: barakuda_plot.py => proj type '+vp[1]+' unknown!!!'; sys.exit(0)
  124. x0,y0 = carte(LON_2D,LAT_2D)
  125. if l_ice_obs:
  126. x2,y2 = carte(xlon_o,xlat_o)
  127. cf = carte.contourf(x0, y0, XFtmp, vc, cmap = colmap, norm = pal_norm)
  128. # Black contours if needed :
  129. if lkcont:
  130. ckf = carte.contour(x0, y0, XFtmp, vc, colors='k', linewidths=0.5)
  131. if cpal != 'ice':
  132. for c in cf.collections: c.set_zorder(0.5) # Changing zorder so black cont. on top
  133. for c in ckf.collections: c.set_zorder(0.5) # of filled cont. and under continents (zorder 1)
  134. # Adding Sea-ice:
  135. cfi = carte.contourf(x0, y0, XItmp, [rice_crit, 1.], cmap = colmapi)
  136. cf2 = carte.contour( x0, y0, XItmp, [rice_crit], colors='k', linewidths=0.5)
  137. for c in cfi.collections: c.set_zorder(0.75)
  138. for c in cf2.collections: c.set_zorder(1)
  139. if l_ice_obs:
  140. cf3 = carte.contour( x2, y2, XIotmp, [rice_crit], colors='r', linewidths=2.)
  141. for c in cf3.collections: c.set_zorder(1)
  142. carte.drawcoastlines() ; carte.fillcontinents(color='grey') ; carte.drawmapboundary()
  143. if vp[1] == 'lcc' or vp[1] == 'cyl':
  144. carte.drawmeridians(nmp.arange(-360,360,vp[8]), labels=[0,0,0,1])
  145. carte.drawparallels(nmp.arange( -90, 90,vp[8]), labels=[1,0,1,0])
  146. if vp[1] == 'stere':
  147. carte.drawmeridians(nmp.arange(-180,180,20), labels=[0,0,0,1])
  148. carte.drawparallels(nmp.arange( -90, 90,10), labels=[1,0,0,0])
  149. #plt.title(ctitle, **font_ttl)
  150. # ADDING COLORBAR
  151. # ===============
  152. if cb_orient == 'horizontal':
  153. clbax = fig.add_axes(vcbar) # axes for colorbar
  154. clb = plt.colorbar(cf, cax=clbax, ticks=vc, drawedges=lkcont, orientation='horizontal')
  155. for t in clb.ax.get_xticklabels(): t.set_font.size(10)
  156. else:
  157. clb = plt.colorbar(cf, ticks=vc, drawedges=lkcont)
  158. for t in clb.ax.get_yticklabels(): t.set_fontsize(16)
  159. if i_cb_subsamp > 1:
  160. cn_clb = [] ; jcpt = 0
  161. for rtck in vc:
  162. if jcpt % i_cb_subsamp == 0:
  163. if float(int(rtck)) == round(rtck,0):
  164. cn_clb.append(str(int(rtck))) ; # we can drop the ".0"
  165. else:
  166. cn_clb.append(str(rtck)) ; # keeping the decimals...
  167. else:
  168. cn_clb.append(' ')
  169. jcpt = jcpt + 1
  170. clb.ax.set_xticklabels(cn_clb)
  171. clb.set_label('('+cbunit+')', **font_clb)
  172. font_lab = { 'fontname':'Arial', 'fontweight':'normal', 'fontsize':24 }
  173. ax.annotate(ctitle, xy=(0.4, 0.95), xycoords='axes fraction', **font_lab)
  174. plt.savefig(cfignm+'.'+cfig_type, dpi=dpi_fig, orientation='portrait', transparent=True) ; #, transparent=True, acecolor='w', edgecolor='w',
  175. plt.close(1)
  176. del LON_2D, LAT_2D, XFtmp
  177. return
  178. # LOCAL functions
  179. # ===============
  180. def __message__(ccr):
  181. # Find the CONF from CONF-EXP and exit if CONF does not exist!
  182. i = 0 ; conf = ''
  183. while i < len(ccr) and ccr[i] != '-' : conf = conf+ccr[i]; i=i+1
  184. print 'conf =', conf, '\n'
  185. return conf
  186. def __get_mat__(cf):
  187. f1 = open(cf, 'r') # for reading
  188. lines1=f1.readlines()
  189. f1.close()
  190. zm = []
  191. jy = 0
  192. for l in lines1:
  193. if l[0] != '#':
  194. jy = jy + 1
  195. ls = l.split()
  196. zm.append([])
  197. for c in ls:
  198. zm[jy-1].append(float(c))
  199. zxm = array(zm)
  200. print 'Shape zxm = ',nmp.shape(zxm), '\n'
  201. return zxm
  202. def __vcontour__(zmin, zmax, zdc):
  203. #
  204. #
  205. lngt = zmax - zmin
  206. #
  207. ncont = lngt/zdc
  208. #
  209. vcont = nmp.arange(zmin, zmax + zdc, zdc)
  210. #
  211. #lat_min
  212. return vcont
  213. def __name_coor_ticks__(lon_min=0., lon_max=360., dlon=30., lat_min=-90., lat_max=90., dlat=15., lon_ext=0):
  214. #
  215. # Builds nice ticks for X and Y (lon, lat) axes!
  216. #
  217. # Arrange longitude axis !
  218. VX = nmp.arange(lon_min, lon_max+lon_ext+dlon, dlon); VX0 = nmp.arange(lon_min, lon_max+lon_ext+dlon, dlon);
  219. ivf = nmp.where(VX>180); VX0[ivf] = VX[ivf] - 360
  220. cn_lon = []
  221. for rlon in VX0:
  222. jlon = int(rlon)
  223. if jlon < 0:
  224. cn_lon.append(str(-jlon)+r'$^{\circ}$W')
  225. else:
  226. if jlon == 0:
  227. cn_lon.append(str(jlon)+r'$^{\circ}$')
  228. else:
  229. cn_lon.append(str(jlon)+r'$^{\circ}$E')
  230. #
  231. # Arrange latitude axis !
  232. VY = nmp.arange(lat_min, lat_max+dlat, dlat)
  233. cn_lat = []
  234. for rlat in VY:
  235. jlat = int(rlat)
  236. if jlat < 0:
  237. cn_lat.append(str(-jlat)+r'$^{\circ}$S')
  238. else:
  239. if jlat == 0:
  240. cn_lat.append(str(jlat)+r'$^{\circ}$')
  241. else:
  242. cn_lat.append(str(jlat)+r'$^{\circ}$N')
  243. #
  244. return VX, VY, cn_lon, cn_lat
  245. def __give_proj__(cname):
  246. #
  247. #
  248. nb =nmp.shape(projection_def)[0] ; #print 'nb =', nb
  249. #
  250. # Initializing :
  251. vproj = [ 'NC', 'NC', 0., 0., 0., 0., 0., 0., 'NC' ]
  252. #
  253. #
  254. jb = 0
  255. while jb < nb :
  256. if projection_def[jb][0] == cname:
  257. break
  258. else :
  259. jb = jb + 1
  260. #
  261. if jb == nb :
  262. print 'Zone "'+cname+'" does not exist!\n'
  263. print 'so far choice is :'
  264. for jb in range(nb): print projection_def[jb][0]
  265. sys.exit(0)
  266. #
  267. #
  268. vproj = projection_def[jb][:]
  269. #
  270. #print 'For ', projection_def[jb][0], ' we have vproj =', vproj, '\n'
  271. #
  272. return vproj
  273. def __font_unity__():
  274. #
  275. params = {'font.family':'Arial','font.size':16,'xtick.labelsize':16,'ytick.labelsize':16,'axes.labelsize':16}
  276. mpl.rcParams.update(params)
  277. big_fixed_fonts = { 'fontname':'Arial', 'fontweight':'normal', 'fontsize':16 }
  278. label_fonts = { 'fontname':'Arial', 'fontweight':'normal', 'fontsize':16 }
  279. colorbar_fonts = { 'fontname':'Arial', 'fontweight':'normal', 'fontsize':16 }
  280. return big_fixed_fonts, label_fonts, colorbar_fonts
  281. def __force_min_and_max__(rm, rp, Xin):
  282. idx_bad = nmp.where(nmp.logical_not(nmp.isfinite(Xin)))
  283. Xin[idx_bad] = 0.
  284. idx1 = nmp.where(Xin <= rm); Xin[idx1] = rm + abs(rp-rm)*1.E-4
  285. idx2 = nmp.where(Xin >= rp); Xin[idx2] = rp - abs(rp-rm)*1.E-4
  286. Xin[idx_bad] = nmp.nan
  287. def __font_unity_big__():
  288. #
  289. params = {'font.family':'Trebuchet MS','text.fontsize':20,'xtick.labelsize':16,'ytick.labelsize': 16,'axes.labelsize':18}
  290. mpl.rcParams.update(params)
  291. title_fonts = { 'fontname':'Trebuchet MS', 'fontweight':'normal', 'fontsize':20 }
  292. big_fixed_fonts = { 'fontname':'monaco', 'fontweight':'normal', 'fontsize':20 }
  293. label_fonts = { 'fontname':'Trebuchet MS', 'fontweight':'normal', 'fontsize':16 }
  294. colorbar_fonts = { 'fontname':'Tahoma', 'fontweight':'normal', 'fontsize':14 }
  295. return title_fonts, big_fixed_fonts, label_fonts, colorbar_fonts
  296. # params = { 'font.family': 'Ubuntu Mono',
  297. # 'legend.fontsize': 14,
  298. # 'text.fontsize': 14,
  299. # 'xtick.labelsize': 12,
  300. # 'ytick.labelsize': 12,
  301. # 'axes.labelsize': 14}
  302. # mpl.rcParams.update(params)
  303. #
  304. # font_ttl = { 'fontname':'Bitstream Vera Sans Mono', 'fontweight':'normal', 'fontsize':14 }
  305. # font_ylb = { 'fontname':'Tahoma', 'fontweight':'normal', 'fontsize':12 }