nemo_imshow_2d_field.py 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. #!/usr/bin/env python
  2. # B a r a K u d a
  3. #
  4. # Prepare 2D maps (monthly) that will later become a GIF animation!
  5. # NEMO output and observations needed
  6. #
  7. # L. Brodeau, May 2018
  8. import sys
  9. import os
  10. from string import replace
  11. import numpy as nmp
  12. from netCDF4 import Dataset
  13. import matplotlib as mpl
  14. mpl.use('Agg')
  15. import matplotlib.pyplot as plt
  16. import matplotlib.colors as colors
  17. import warnings
  18. warnings.filterwarnings("ignore")
  19. import barakuda_colmap as bcm
  20. import barakuda_tool as bt
  21. #CNEMO = 'NATL60'
  22. #CNEMO = 'NANUK025'
  23. color_top = 'white'
  24. #color_top = 'k'
  25. fig_type='png'
  26. narg = len(sys.argv)
  27. if narg < 6: print 'Usage: '+sys.argv[0]+' <CONF> <file> <variable> <snapshot> <LSM_file>'; sys.exit(0)
  28. CNEMO = sys.argv[1] ; cf_fld = sys.argv[2] ; cv_in=sys.argv[3] ; jt=int(sys.argv[4]) ; cf_lsm=sys.argv[5]
  29. i2=0
  30. j2=0
  31. if CNEMO == 'NATL60':
  32. i1 = 0 ; j1 = 0 ; i2 = 0 ; j2 = 0 ; rfact_zoom = 1. ; vcb = [0.6, 0.1, 0.39, 0.025] ; font_rat = 7.
  33. x_cnf = 160. ; y_cnf = 2300. ; # where to put label of conf on Figure...
  34. elif CNEMO == 'NANUK1':
  35. i1 = 0 ; j1 = 0 ; i2 = 0 ; j2 = 0 ; rfact_zoom = 4. ; vcb = [0.5, 0.875, 0.49, 0.02] ; font_rat = 0.16*rfact_zoom
  36. elif CNEMO == 'NANUK025':
  37. i1 = 0 ; j1 = 0 ; i2 = 0 ; j2 = 0 ; rfact_zoom = 2. ; vcb = [0.5, 0.875, 0.49, 0.02] ; font_rat = 0.5*rfact_zoom
  38. x_cnf = 30. ; y_cnf = 540. ; # where to put label of conf on Figure...
  39. elif CNEMO == 'CREG025':
  40. i1 = 0 ; j1 = 0 ; i2 = 0 ; j2 = 0 ; rfact_zoom = 2.
  41. vcb = [0.6, 0.975, 0.38, 0.02] ; font_rat = 0.5*rfact_zoom
  42. x_cnf = 20. ; y_cnf = 560. ; # where to put label of conf on Figure...
  43. elif CNEMO == 'eNATL4':
  44. i1 = 0 ; j1 = 0 ; i2 = 0 ; j2 = 0 ; rfact_zoom = 2. ; vcb = [0.6, 0.11, 0.39, 0.025] ; font_rat = 0.5*rfact_zoom
  45. elif CNEMO == 'eNATL60':
  46. i1 = 0 ; j1 = 0 ; i2 = 0 ; j2 = 0 ; rfact_zoom = 1. ; vcb = [0.6, 0.1, 0.39, 0.025] ; font_rat = 5.
  47. x_cnf = 160. ; y_cnf = 4000. ; # where to put label of conf on Figure...
  48. elif CNEMO == 'eNATL1':
  49. i1 = 0 ; j1 = 0 ; i2 = 0 ; j2 = 0 ; rfact_zoom = 6.
  50. vcb = [0.62, 0.11, 0.35, 0.025] ; font_rat = 0.12*rfact_zoom
  51. x_cnf = 4. ; y_cnf = 120. ; # where to put label of conf on Figure...
  52. else:
  53. print '\n PROBLEM: "'+CNEMO+'" is an unknown config!!!'
  54. sys.exit(0)
  55. laplacian = False
  56. l_log_field = False
  57. l_pow_field = False
  58. cextend='both'
  59. l_hide_cb_ticks = False
  60. if cv_in in ['sosstsst','tos']:
  61. cfield = 'SST'
  62. tmin=0. ; tmax=28. ; df = 1.
  63. cpal_fld = 'ncview_nrl'
  64. cunit = r'SST ($^{\circ}$C)'
  65. cb_jump = 1
  66. if cv_in in ['Bathymetry']:
  67. cfield = 'Bathymetry'
  68. #tmin=100. ; tmax=4500. ; df = 100.
  69. tmin=0. ; tmax=5000. ; df = 100.
  70. #cpal_fld = 'ocean'
  71. #cpal_fld = 'Blues'
  72. cpal_fld = 'PuBu'
  73. #cpal_fld = 'ncview_ssec'
  74. #cpal_fld = 'ncview_hotres'
  75. #cpal_fld = 'ncview_helix'
  76. cunit = r'Bathymetry (m)'
  77. cb_jump = 10
  78. l_pow_field = True
  79. pow_field = 1.5
  80. #l_log_field = False
  81. cextend='max'
  82. l_hide_cb_ticks=True
  83. if cv_in == 'sossheig':
  84. cfield = 'SSH'
  85. tmin=-0.3 ; tmax=0.3 ; df = 0.1
  86. cpal_fld = 'ncview_jaisnc'
  87. cunit = r'SSH (m)'
  88. cb_jump = 1
  89. elif cv_in == 'somxl010':
  90. cfield == 'MLD'
  91. tmin=50. ; tmax=1500. ; df = 50.
  92. cpal_fld = 'viridis_r'
  93. # Time record stuff...
  94. bt.chck4f(cf_fld)
  95. id_fld = Dataset(cf_fld)
  96. list_var = id_fld.variables.keys()
  97. if 'time_counter' in list_var:
  98. vtime = id_fld.variables['time_counter'][:]
  99. Nt = len(vtime)
  100. print '\n There is a "time_counter" in file '+cf_fld+' !'
  101. print ' => '+str(Nt)+' snapshots!'
  102. if jt <= 0 or jt > Nt: print ' PROBLEM: your time record does not exist!', jt ; sys.exit(0)
  103. else:
  104. print '\n There is NO "time_counter" in file '+cf_fld+' !'
  105. Nt = 0
  106. id_fld.close()
  107. bt.chck4f(cf_lsm)
  108. print '\n *** Reading "tmask" in meshmask file...'
  109. id_lsm = Dataset(cf_lsm)
  110. nb_dim = len(id_lsm.variables['tmask'].dimensions)
  111. Ni = id_lsm.dimensions['x'].size
  112. Nj = id_lsm.dimensions['y'].size
  113. if i2 == 0: i2 = Ni
  114. if j2 == 0: j2 = Nj
  115. if nb_dim == 4: XMSK = id_lsm.variables['tmask'][0,0,j1:j2,i1:i2] ; # t, y, x
  116. if nb_dim == 3: XMSK = id_lsm.variables['tmask'][0, j1:j2,i1:i2] ; # t, y, x
  117. id_lsm.close()
  118. print ' done.'
  119. print '\n According to "tmask" the shape of the domain is Ni, Nj =', Ni, Nj
  120. # Stuff for size of figure respecting pixels...
  121. print ' *** we are going to show: i1,i2,j1,j2 =>', i1,i2,j1,j2, '\n'
  122. nx_res = i2-i1
  123. ny_res = j2-j1
  124. yx_ratio = float(ny_res)/float(nx_res)
  125. nxr = int(rfact_zoom*nx_res) ; # widt image (in pixels)
  126. nyr = int(rfact_zoom*ny_res) ; # height image (in pixels)
  127. dpi = 110
  128. rh = float(nxr)/float(dpi) ; # width of figure as for figure...
  129. ###font_rat = nxr/1080.
  130. pmsk = nmp.ma.masked_where(XMSK[:,:] > 0.2, XMSK[:,:]*0.+40.)
  131. idx_oce = nmp.where(XMSK[:,:] > 0.5)
  132. #font_rat
  133. #params = { 'font.family':'Ubuntu',
  134. params = { 'font.family':'Helvetica Neue',
  135. 'font.weight': 'normal',
  136. 'font.size': int(12.*font_rat),
  137. 'legend.fontsize': int(12.*font_rat),
  138. 'xtick.labelsize': int(12.*font_rat),
  139. 'ytick.labelsize': int(12.*font_rat),
  140. 'axes.labelsize': int(12.*font_rat) }
  141. mpl.rcParams.update(params)
  142. cfont_clb = { 'fontname':'Helvetica Neue', 'fontweight':'medium', 'fontsize':int(12.*font_rat), 'color':color_top }
  143. cfont_date = { 'fontname':'Ubuntu Mono', 'fontweight':'normal', 'fontsize':int(12.*font_rat), 'color':'w' }
  144. cfont_mail = { 'fontname':'Times New Roman', 'fontweight':'normal', 'fontstyle':'italic', 'fontsize':int(14.*font_rat), 'color':'0.8'}
  145. cfont_titl = { 'fontname':'Helvetica Neue', 'fontweight':'light', 'fontsize':int(30.*font_rat), 'color':'w' }
  146. # Colormaps for fields:
  147. pal_fld = bcm.chose_colmap(cpal_fld)
  148. if l_log_field:
  149. norm_fld = colors.LogNorm( vmin = tmin, vmax = tmax, clip = False)
  150. if l_pow_field:
  151. norm_fld = colors.PowerNorm(gamma=pow_field, vmin = tmin, vmax = tmax, clip = False)
  152. else:
  153. norm_fld = colors.Normalize(vmin = tmin, vmax = tmax, clip = False)
  154. pal_lsm = bcm.chose_colmap('land_dark')
  155. norm_lsm = colors.Normalize(vmin = 0., vmax = 1., clip = False)
  156. if Nt == 0:
  157. cfig = cv_in+'_'+CNEMO+'_'+cpal_fld+'.'+fig_type
  158. else:
  159. cfig = 'snapshot_'+str(jt)+'_'+cv_in+'_'+CNEMO+'_'+cpal_fld+'.'+fig_type
  160. fig = plt.figure(num = 1, figsize=(rh,rh*yx_ratio), dpi=None, facecolor='w', edgecolor='0.5')
  161. #ax = plt.axes([0.065, 0.05, 0.9, 1.], axisbg = '0.5')
  162. ax = plt.axes([0., 0., 1., 1.], axisbg = '0.5')
  163. vc_fld = nmp.arange(tmin, tmax + df, df)
  164. print '\n *** Opening file '+cf_fld
  165. id_fld = Dataset(cf_fld)
  166. if Nt > 0:
  167. print ' => Reading record #'+str(jt)+' of '+cv_in+' in '+cf_fld
  168. XFLD = id_fld.variables[cv_in][jt-1,j1:j2,i1:i2] ; # t, y, x
  169. else:
  170. print ' => Reading 2D field '+cv_in+' in '+cf_fld+' (no time records...)'
  171. XFLD = id_fld.variables[cv_in][j1:j2,i1:i2] ; # t, y, x
  172. id_fld.close()
  173. print ' Done!\n'
  174. if XMSK.shape != XFLD.shape:
  175. print '\n PROBLEM: field and mask do not agree in shape!'
  176. print XMSK.shape , XFLD.shape
  177. sys.exit(0)
  178. print ' *** Shape of field and mask => ', nmp.shape(XFLD)
  179. del XMSK
  180. print 'Ploting'
  181. cf = plt.imshow(XFLD[:,:], cmap = pal_fld, norm = norm_fld, interpolation='none')
  182. print 'LOLO: XFLD[4,4] = ', XFLD[4,4], nmp.isnan(XFLD[4,4])
  183. del XFLD
  184. print 'Done!'
  185. cm = plt.imshow(pmsk, cmap = pal_lsm, norm = norm_lsm, interpolation='none')
  186. del pmsk
  187. plt.axis([ 0, Ni, 0, Nj])
  188. #plt.title('NEMO: '+cfield+', coupled '+CNEMO+', '+cday+' '+chour+':00', **cfont_title)
  189. #ax2 = plt.axes([0.3, 0.08, 0.4, 0.025])
  190. ax2 = plt.axes(vcb)
  191. clb = mpl.colorbar.ColorbarBase(ax2, ticks=vc_fld, cmap=pal_fld, norm=norm_fld, orientation='horizontal', extend=cextend)
  192. if cb_jump > 1:
  193. cb_labs = [] ; cpt = 0
  194. for rr in vc_fld:
  195. if cpt % cb_jump == 0:
  196. if df >= 1.: cb_labs.append(str(int(rr)))
  197. if df < 1.: cb_labs.append(str(rr))
  198. else:
  199. cb_labs.append(' ')
  200. cpt = cpt + 1
  201. clb.ax.set_xticklabels(cb_labs)
  202. clb.set_label(cunit, **cfont_clb)
  203. clb.ax.yaxis.set_tick_params(color=color_top) ; # set colorbar tick color
  204. #clb.outline.set_edgecolor(color_top) ; # set colorbar edgecolor
  205. if l_hide_cb_ticks: clb.ax.tick_params(axis=u'both', which=u'both',length=0) ; # remove ticks!
  206. plt.setp(plt.getp(clb.ax.axes, 'xticklabels'), color=color_top) ; # set colorbar ticklabels
  207. del cf
  208. #x_annot = nxr-nxr*0.22.*font_rat ; y_annot = 150
  209. x_annot = 650 ; y_annot = 1035
  210. #ax.annotate('Date: '+cday+' '+chour+':00', xy=(1, 4), xytext=(x_annot, y_annot), **cfont_date)
  211. #ax.annotate('laurent.brodeau@ocean-next.fr', xy=(1, 4), xytext=(x_annot+150, 20), **cfont_mail)
  212. ax.annotate(CNEMO, xy=(1, 4), xytext=(x_cnf, y_cnf), **cfont_titl)
  213. plt.savefig(cfig, dpi=dpi, orientation='portrait', facecolor='k')
  214. print cfig+' created!\n'
  215. plt.close(1)
  216. del cm, fig, ax, clb