barakuda_plot.py 73 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949
  1. # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
  2. #
  3. ########################################################################
  4. #
  5. # B a r a K u d a
  6. #
  7. # Ploting functions and utilities
  8. #
  9. ## Authors:
  10. # --------
  11. # 2010-2015: Laurent Brodeau (original primitive code)
  12. # 2016: Saeed Falahat (update to fancy grown-up coding!) :D
  13. #
  14. #######################################################################
  15. import os
  16. import sys
  17. import numpy as nmp
  18. import matplotlib as mpl
  19. mpl.use('Agg')
  20. import matplotlib.pyplot as plt
  21. import matplotlib.colors as colors
  22. reload(sys)
  23. sys.setdefaultencoding('utf8')
  24. # Some defaults:
  25. #WDTH_DEF = 10.
  26. #HGHT_DEF = 4.
  27. WDTH_DEF = 9.
  28. HGHT_DEF = 3.6
  29. FIG_SIZE_DEF = ( WDTH_DEF , HGHT_DEF )
  30. RAT_XY = WDTH_DEF/10.
  31. DPI_DEF = 120
  32. AXES_DEF = [0.09, 0.082, 0.89, 0.84]
  33. # Colors for line: (https://www.daftlogic.com/projects-hex-colour-tester.htm)
  34. b_blu = '#2C558A'
  35. b_red = '#AD0000'
  36. b_gre = '#3DE079' ; #b_gre = '#3A783E' ; # b_gre = '#42BD82'
  37. b_prp = '#8C008C'
  38. b_org = '#ED7C4C'
  39. clr_inf_box='0.9'
  40. v_dflt_colors = [b_blu, b_red, b_gre, b_org, b_prp, 'pink', '0.5', 'b', 'g', 'brown', 'orange',
  41. '0.25','0.75','k' ]
  42. nmax_colors = len(v_dflt_colors)
  43. # Some projections to use with BaseMap:
  44. #
  45. # zone PROJ llcrnrlon llcrnrlat urcrnrlon urcrnrlat lat1 lon0 mer/par continent-res
  46. # (lcc = Lambert conformal conic)
  47. projection_def = [
  48. ['nseas', 'lcc', -55., 40., 55., 75., 60., -20., 10., 'l' ], # Nordic seas
  49. ['natarct', 'lcc', -60., 40., 80., 72., 55., -32., 10., 'l' ], # NATL + Arctic
  50. ['labir', 'lcc', -62., 48., -10., 75., 50., -30., 5., 'l' ],
  51. ['labsp', 'lcc', -60., 48., 50., 75.5, 50., -30., 10., 'l' ],
  52. ['npol', 'stere', -75., 45., 100., 60., 80., -30., 10., 'l' ],
  53. ['npol2', 'stere', -55., 40., 145., 40., 80., -5., 10., 'l' ], # North Pole
  54. ['spstere', 'stere', 0., 0., 0., 0., -48., 90., 10., 'l' ], # South Pole Default matplotlib!
  55. ['matl' , 'cyl', -82.,-21., 12., 79., 30., -30., 15., 'l' ], # Nordic seas
  56. ['atmed', 'lcc', -18., 33., -2., 42., 30., -10., 5., 'h' ],
  57. ['kav7' , 'kav', 0., 0., 0., 0., 0., 0., 0., 'l' ] ] # global map-monde
  58. class plot :
  59. ''' This class encapsulates all the plot routines
  60. In order to use it you need to type as follows:
  61. plot(function name without the prefix __) (all the arguments of the function)
  62. for example for __vert_section we do as follows:
  63. plot("vert_section")(VX, VZ, XF, XMSK, rmin, rmax, dc, lkcont=True, cpal='jet',
  64. xmin=-80., xmax=85., dx=5, cfignm='fig', cbunit='', cxunit=' ',
  65. zmin = 0., zmax = 5000., l_zlog=False, cfig_type='png',
  66. czunit=' ', ctitle=' ', lforce_lim=False, i_cb_subsamp=1, l_z_increase=False )
  67. The reason to prefix all the function with double underscore __ is that all these function become private members of
  68. the plot class and they can not be accessed directly outside of the class. That is, you need to call these functios through the call wrapper
  69. as seen below in the function __call__.
  70. '''
  71. def __init__(self,splot) :
  72. self.splot = splot
  73. def __call__(self,*args, **kw) :
  74. if "_"+self.__class__.__name__+ "__" + self.splot in self.__class__.__dict__.keys() :
  75. self.__class__.__dict__["_"+self.__class__.__name__+ "__" + self.splot](self,*args, **kw)
  76. else :
  77. print "function " + "__" + self.splot + " does not exist"
  78. sys.exit()
  79. # Functions:
  80. def __vert_section(self, VX, VZ, XF, XMSK, rmin, rmax, dc, lkcont=False, cpal='jet', lzonal=True,
  81. xmin=-80., xmax=85., dx=5, cfignm='fig', cbunit='', cxunit=' ',
  82. zmin = 0., zmax = 5000., l_zlog=False, cfig_type='png',
  83. czunit=' ', ctitle=' ', lforce_lim=False, i_cb_subsamp=1, l_z_increase=False ):
  84. import barakuda_colmap as bcm
  85. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=DPI_DEF)
  86. zVZ = __prepare_z_log_axis__(l_zlog, VZ)
  87. if lforce_lim: __force_min_and_max__(rmin, rmax, XF)
  88. i_x_sbsmp = 1
  89. dxgap = nmp.amax(VX) - nmp.amin(VX)
  90. if dxgap > 140.: dx = 5.; i_x_sbsmp = 2
  91. if dxgap < 50.: dx = 2.
  92. if dxgap < 25.: dx = 1.
  93. cbgcol='w'
  94. if not lkcont:
  95. cbgcol='k'
  96. XF = nmp.ma.masked_where(XMSK == 0, XF) ; # Masking where mask is zero!
  97. fig = plt.figure(num = 1, figsize=(WDTH_DEF , RAT_XY*5.), dpi=None, facecolor='w', edgecolor='k')
  98. ax = plt.axes([0.07, 0.06, 0.98, 0.88], facecolor=cbgcol)
  99. vc = __vcontour__(rmin, rmax, dc)
  100. # Colormap:
  101. colmap = bcm.chose_colmap(cpal)
  102. pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
  103. if lkcont:
  104. from barakuda_tool import drown
  105. Xtmp = nmp.zeros(nmp.shape(XF))
  106. Xtmp[:,:] = XF[:,:]
  107. drown(Xtmp, XMSK, k_ew=2, nb_max_inc=5, nb_smooth=5)
  108. cf = plt.contourf(VX, zVZ, Xtmp, vc, cmap=colmap, norm=pal_norm, zorder=0.1)
  109. plt.contour( VX, zVZ, Xtmp, vc, colors='k', linewidths=0.2, zorder=0.5)
  110. del Xtmp
  111. else:
  112. cf = plt.pcolormesh(VX, zVZ, XF, cmap=colmap, norm=pal_norm)
  113. # Colorbar:
  114. __nice_colorbar__(cf, plt, vc, i_sbsmp=i_cb_subsamp, lkc=lkcont, cunit=cbunit, cfont=font_clb, fontsize=10)
  115. # Masking "rock":
  116. if lkcont:
  117. pal_lsm = bcm.chose_colmap('mask')
  118. norm_lsm = colors.Normalize(vmin = 0., vmax = 1., clip = False)
  119. prock = nmp.ma.masked_where(XMSK > 0.5, XMSK)
  120. cm = plt.pcolormesh(VX, zVZ, prock, cmap=pal_lsm, norm=norm_lsm, zorder=1)
  121. # X-axis:
  122. if lzonal:
  123. __nice_longitude_axis__(ax, plt, xmin, xmax, dx*i_x_sbsmp, axt='x')
  124. else:
  125. __nice_latitude_axis__(ax, plt, xmin, xmax, dx*i_x_sbsmp, axt='x')
  126. # Depth-axis:
  127. __nice_depth_axis__(ax, plt, zmin, zmax, l_log=l_zlog, l_z_inc=l_z_increase, cunit=czunit, cfont=font_xylb)
  128. plt.title(ctitle, **font_ttl)
  129. plt.savefig(cfignm+'.'+cfig_type, dpi=DPI_DEF, orientation='portrait', transparent=False) ; #vert_section
  130. print ' => '+cfignm+'.'+cfig_type+' created!'
  131. plt.close(1)
  132. return
  133. def __2d(self,VX, VY, XF, XMSK, rmin, rmax, dc, corca='ORCA1', lkcont=True, cpal='jet',
  134. cfignm='fig', cbunit='', ctitle=' ', lforce_lim=False, i_cb_subsamp=1, cb_orient='vertical',
  135. cfig_type='pdf', lat_min=-75., lat_max=75., lpix=False, vcont_spec = []):
  136. #
  137. # Plot nicely a field given on ORCA coordinates on 2D world map without using any projection
  138. #
  139. # if VX = [0] and VY = [0] => ignoring lon and lat...
  140. import barakuda_tool as bt
  141. import barakuda_orca as bo
  142. import barakuda_colmap as bcm
  143. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=DPI_DEF)
  144. i_lat_lon = 1
  145. if len(VX) == 1 or len(VY) == 1: i_lat_lon = 0 ; # no long. and lat. provided !
  146. if corca[:5] == 'eORCA':
  147. # don't know how to lat-lon 2d plot eORCA
  148. # so just plot without projections
  149. i_lat_lon = 0
  150. # First drowning the field:
  151. if not lpix:
  152. # Don't want to modify XF array, working with XFtmp:
  153. [ny, nx] = nmp.shape(XF)
  154. XFtmp = nmp.zeros((ny,nx))
  155. XFtmp[:,:] = XF[:,:]
  156. bt.drown(XFtmp, XMSK, k_ew=2, nb_max_inc=20, nb_smooth=10)
  157. else:
  158. XFtmp = XF
  159. ilon_ext = 32
  160. if lforce_lim: __force_min_and_max__(rmin, rmax, XFtmp)
  161. XMSK0 = bo.lon_reorg_orca(XMSK, VX, ilon_ext=ilon_ext)
  162. XF0 = bo.lon_reorg_orca(XFtmp, VX, ilon_ext=ilon_ext)
  163. if i_lat_lon == 1:
  164. [ny, nx] = nmp.shape(XF0)
  165. dlong = abs(VX[11] - VX[10])
  166. VX0 = nmp.arange(0.,nx)
  167. VX0 = VX0*dlong + dlong/2.
  168. if i_lat_lon == 1:
  169. vert_rat = (lat_max - lat_min)/(75. + 75.)
  170. fig_size = (WDTH_DEF , RAT_XY*4.76*vert_rat) ; #lolo 4.76 => 1080x520 when on 77S->75N
  171. else:
  172. fig_size = (WDTH_DEF , RAT_XY*float(nx)/float(ny)*5.)
  173. # FIGURE
  174. # ~~~~~~
  175. fig = plt.figure(num = 1, figsize=fig_size, dpi=None, facecolor='w', edgecolor='k')
  176. ax = plt.axes([0.05, 0.06, 1., 0.86], facecolor = '0.5')
  177. vc = __vcontour__(rmin, rmax, dc)
  178. # Colmap:
  179. colmap = bcm.chose_colmap(cpal)
  180. pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
  181. if lpix:
  182. # Pixelized plot:
  183. XF0 = nmp.ma.masked_where(XMSK0 == 0, XF0)
  184. if i_lat_lon == 1:
  185. cf = plt.pcolormesh(VX0, VY, XF0, cmap = colmap, norm = pal_norm)
  186. else:
  187. cf = plt.imshow( XF0, cmap = colmap, norm = pal_norm)
  188. else:
  189. # Contour fill plot:
  190. if i_lat_lon == 1:
  191. cf = plt.contourf(VX0, VY, XF0, vc, cmap = colmap, norm = pal_norm)
  192. else:
  193. cf = plt.contourf( XF0, vc, cmap = colmap, norm = pal_norm)
  194. for c in cf.collections: c.set_zorder(0.15)
  195. if lkcont:
  196. if i_lat_lon == 1:
  197. cfk = plt.contour(VX0, VY, XF0, vc, colors='k', linewidths = 0.2)
  198. else:
  199. cfk = plt.contour( XF0, vc, colors='k', linewidths = 0.2)
  200. for c in cfk.collections: c.set_zorder(0.25)
  201. # contour for specific values on the ploted field:
  202. if len(vcont_spec) >= 1:
  203. if i_lat_lon == 1:
  204. cfs = plt.contour(VX0, VY, XF0, vcont_spec, colors='black', linewidths = 1.5)
  205. else:
  206. cfs = plt.contour( XF0, vcont_spec, colors='black', linewidths = 1.5)
  207. plt.clabel(cfs, inline=1, fmt='%4.1f', fontsize=10)
  208. for c in cfs.collections: c.set_zorder(0.35)
  209. if not lpix:
  210. # Putting land-sea mask on top of current plot, cleaner than initial masking...
  211. # because won't influence contours since they are done
  212. # field needs to be DROWNED prior to this though!!!
  213. idx_land = nmp.where(XMSK0[:,:] < 0.5)
  214. XF0 = nmp.ma.masked_where(XMSK0[:,:] > 0.5, XF0)
  215. XF0[idx_land] = 1000.
  216. if i_lat_lon == 1:
  217. cf0 = plt.pcolormesh(VX0, VY, XF0, cmap=bcm.chose_colmap("mask"))
  218. else:
  219. cf0 = plt.imshow( XF0, cmap=bcm.chose_colmap("mask"))
  220. # Colorbar:
  221. ifsize = 14.*100./float(DPI_DEF)
  222. if i_lat_lon == 1: ifsize = int(ifsize*vert_rat); ifsize=max(ifsize,6)
  223. __nice_colorbar__(cf, plt, vc, i_sbsmp=i_cb_subsamp, lkc=lkcont,
  224. cb_or=cb_orient, cunit=cbunit, cfont=font_clb, fontsize=ifsize)
  225. # X and Y nice ticks:
  226. if i_lat_lon == 1:
  227. [vvx, vvy, clon, clat] = __name_coor_ticks__(lon_ext=ilon_ext);
  228. plt.yticks(vvy,clat) ; plt.xticks(vvx,clon)
  229. plt.axis([ 0., 360.+ilon_ext-2., lat_min, lat_max])
  230. else:
  231. #ax.set_xlim(0., 360.+ilon_ext-2.)
  232. plt.axis([ 0., float(nx)+ilon_ext-2., 0, float(ny)])
  233. plt.title(ctitle, **font_ttl)
  234. plt.savefig(cfignm+'.'+cfig_type, dpi=DPI_DEF, orientation='portrait', transparent=False) ; #2d
  235. print ' => '+cfignm+'.'+cfig_type+' created!'
  236. plt.close(1)
  237. del XFtmp, XF0
  238. return
  239. def __2d_reg(self,VX, VY, XF, XMSK, rmin, rmax, dc, lkcont=False, cpal='jet',
  240. cfignm='fig', cfig_type='pdf', cbunit=' ', ctitle='',
  241. cb_orient='vertical', lat_min=-77., lat_max=77., i_cb_subsamp=1,
  242. lpix=False, l_continent_pixel=True, colorbar_fs=14,
  243. col_min='k', col_max='k', vcont_spec = []):
  244. import barakuda_tool as bt
  245. import barakuda_colmap as bcm
  246. font_ttl, font_xylb, font_clb, font_inf = __font_unity__()
  247. # Don't want to modify XF array, working with XFtmp:
  248. [ny, nx] = nmp.shape(XF)
  249. XFtmp = nmp.zeros(ny*nx) ; XFtmp.shape = [ny, nx]
  250. XFtmp[:,:] = XF[:,:]
  251. # First drowning the field:
  252. bt.drown(XFtmp, XMSK, k_ew=0, nb_max_inc=20, nb_smooth=10)
  253. iskp = 28 ; iext = 32
  254. # Extending / longitude:
  255. VXe = bt.extend_domain(VX, iext, skp_west_deg=iskp) ; nxe = len(VXe)
  256. XFe = bt.extend_domain(XFtmp, iext, skp_west_deg=iskp)
  257. XMSKe = bt.extend_domain(XMSK, iext, skp_west_deg=iskp)
  258. # FIGURE
  259. rat_vert = 1. / ( ( 77. + 77. ) / ( lat_max - lat_min ) )
  260. if cb_orient == 'horizontal':
  261. # Horizontal colorbar!
  262. if ctitle == '':
  263. fig = plt.figure(num = 1, figsize=(12.4,7.*rat_vert), dpi=None, facecolor='w', edgecolor='k')
  264. ax = plt.axes([0.05, -0.01, 0.93, 1.], facecolor = 'white')
  265. else:
  266. fig = plt.figure(num = 1, figsize=(12.4,7.4*rat_vert), dpi=None, facecolor='w', edgecolor='k')
  267. ax = plt.axes([0.05, -0.01, 0.93, 0.96], facecolor = 'white')
  268. else:
  269. # Vertical colorbar!
  270. fig = plt.figure(num = 1, figsize=(12.4,6.*rat_vert), dpi=None, facecolor='w', edgecolor='k')
  271. ax = plt.axes([0.046, 0.06, 1.02, 0.88], facecolor = 'white')
  272. vc = __vcontour__(rmin, rmax, dc)
  273. # Colmap:
  274. pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
  275. mpl.rcParams['contour.negative_linestyle'] = 'solid'
  276. plt.contour.negative_linestyle='solid'
  277. if lpix:
  278. cf = plt.pcolormesh(VXe, VY, XFe, cmap = cpal, norm = pal_norm)
  279. else:
  280. cf = plt.contourf(VXe, VY, XFe, vc, cmap = cpal, norm = pal_norm, extend="both")
  281. for c in cf.collections: c.set_zorder(0.15)
  282. cf.cmap.set_under(col_min)
  283. cf.cmap.set_over(col_max)
  284. # contour for specific values on the ploted field:
  285. if len(vcont_spec) >= 1:
  286. cfs = plt.contour(VXe, VY, XFe, vcont_spec, colors='w', linewidths = 1.)
  287. #plt.clabel(cfs, inline=1, fmt='%4.1f', fontsize=12)
  288. if lkcont:
  289. cfk = plt.contour(VXe, VY, XFe, vc, colors='k', linewidths = 0.2)
  290. for c in cfk.collections: c.set_zorder(0.25)
  291. # Putting land-sea mask on top of current plot, cleaner than initial masking...
  292. # because won't influence contours since they are done
  293. # field needs to be DROWNED prior to this though!!!
  294. if l_continent_pixel:
  295. idx_land = nmp.where(XMSKe[:,:] < 0.5)
  296. XFe = nmp.ma.masked_where(XMSKe[:,:] > 0.5, XFe)
  297. XFe[idx_land] = 1000.
  298. cf0 = plt.pcolor(VXe, VY, XFe, cmap = bcm.chose_colmap("mask"))
  299. else:
  300. # Masking with contour rather than pixel:
  301. cf0 = plt.contourf(VXe, VY, XMSKe, [ 0., 0.1 ], cmap = bcm.chose_colmap("mask"))
  302. for c in cf0.collections: c.set_zorder(5)
  303. plt.contour(VXe, VY, XMSKe, [ 0.25 ], colors='k', linewidths = 1.)
  304. # COLOR BAR:
  305. __nice_colorbar__(cf, plt, vc, i_sbsmp=i_cb_subsamp, lkc=lkcont, cb_or=cb_orient, cunit=cbunit, cfont=font_clb, fontsize=colorbar_fs)
  306. # X and Y nice ticks:
  307. print "VXe[0], VXe[nxe-1] =>", VXe[0], VXe[nxe-1]
  308. rlon_min = round(VXe[0],0) ; rlon_max = round(VXe[nxe-1],0)
  309. print "rlon_min, rlon_max =>", rlon_min, rlon_max
  310. [vvx, vvy, clon, clat] = __name_coor_ticks__(lon_min=rlon_min, lon_max=rlon_max, dlon=30., lon_ext=iext-iskp)
  311. plt.yticks(vvy,clat) ; plt.xticks(vvx,clon)
  312. plt.axis([ rlon_min, rlon_max, lat_min, lat_max])
  313. if ctitle != ' ': plt.title(ctitle, **font_ttl)
  314. plt.savefig(cfignm+'.'+cfig_type, dpi=110, orientation='portrait', transparent=False)
  315. print ' => '+cfignm+'.'+cfig_type+' created!'
  316. plt.close(1)
  317. return
  318. def __2d_box(self,XF, XMSK, rmin, rmax, dc, lkcont=True,
  319. cpal='jet', cfignm='fig', cbunit='', ctitle=' ', lforce_lim=False,
  320. i_cb_subsamp=1, cfig_type='pdf', lcontours=True,
  321. x_offset=0., y_offset=0., vcont_spec = [], lcont_mask=False):
  322. import barakuda_colmap as bcm
  323. if lforce_lim: __force_min_and_max__(rmin, rmax, XF)
  324. [ ny , nx ] = XF.shape
  325. vert_rat = float(ny)/float(nx)
  326. print "Vert. ratio, nx, ny =", vert_rat, nx, ny
  327. # Masking field:
  328. if lcontours:
  329. idxm = nmp.where(XMSK[:,:] == 0); XF[idxm] = -9999.9 # c'est NaN qui merde!!!
  330. else:
  331. XF = nmp.ma.masked_where(XMSK == 0, XF)
  332. font_ttl, font_xylb, font_clb, font_inf = __font_unity__()
  333. # FIGURE
  334. # ~~~~~~
  335. fig = plt.figure(num = 1, figsize=(7.,6.*vert_rat), dpi=None, facecolor='w', edgecolor='k')
  336. ax = plt.axes([0.07, 0.05, 0.9, 0.9], facecolor = 'gray')
  337. vc = __vcontour__(rmin, rmax, dc); #print vc, '\n'
  338. # Colmap:
  339. colmap = bcm.chose_colmap(cpal)
  340. pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
  341. if lcontours:
  342. cf = plt.contourf(XF, vc, cmap = colmap, norm = pal_norm)
  343. for c in cf.collections: c.set_zorder(0.5)
  344. else:
  345. cf = plt.pcolor(XF, cmap = colmap, norm = pal_norm)
  346. # contour for specific values on the ploted field:
  347. if len(vcont_spec) >= 1:
  348. cfs = plt.contour(XF, vcont_spec, colors='white', linewidths = 1.)
  349. plt.clabel(cfs, inline=1, fmt='%4.1f', fontsize=10)
  350. if lkcont:
  351. cfk = plt.contour(XF, vc, colors='k', linewidths = 0.1)
  352. for c in cfk.collections: c.set_zorder(0.75)
  353. # contour for continents:
  354. if lcontours and lcont_mask:
  355. cfm = plt.contour(XMSK, [ 0.7 ], colors='k', linewidths = 1.)
  356. for c in cfm.collections: c.set_zorder(1.)
  357. # Colorbar:
  358. __nice_colorbar__(cf, plt, vc, i_sbsmp=i_cb_subsamp, lkc=lkcont, cunit=cbunit, cfont=font_clb)
  359. if x_offset > 0 or y_offset > 0 : __add_xy_offset__(plt, x_offset, y_offset)
  360. plt.axis([ 0., nx-1, 0, ny-1])
  361. plt.title(ctitle, **font_ttl)
  362. # Prevents from using scientific notations in axess ticks numbering:
  363. ax.get_xaxis().get_major_formatter().set_useOffset(False)
  364. plt.savefig(cfignm+'.'+cfig_type, dpi=100, orientation='portrait', transparent=True)
  365. print ' => '+cfignm+'.'+cfig_type+' created!'
  366. plt.close(1)
  367. return
  368. def __zonal(self,VYn, VZn, VY1=[0.],VZ1=[0.], VY2=[0.],VZ2=[0.], VY3=[0.],VZ3=[0.],
  369. cfignm='fig_zonal', zmin=-100., zmax=100., dz=25., i_z_jump=1,
  370. xmin=-90., xmax=90., dx=15., cfig_type='png', cxunit=r'Latitude ($^{\circ}$N)',
  371. czunit='', ctitle='', lab='', lab1='', lab2='', lab3='', box_legend=(0.6, 0.75),
  372. loc_legend='lower center', fig_size=FIG_SIZE_DEF):
  373. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=DPI_DEF)
  374. ny = len(VYn)
  375. if len(VZn) != ny: print 'ERROR: plot_zonal.barakuda_plot => VYn and VZn do not agree in size'; sys.exit(0)
  376. lp1=False ; lp2=False ; lp3=False
  377. if len(VZ1) > 1 and len(VZ1)==len(VY1): lp1=True
  378. if len(VZ2) > 1 and len(VZ2)==len(VY2): lp2=True
  379. if len(VZ3) > 1 and len(VZ3)==len(VY3): lp3=True
  380. if fig_size==FIG_SIZE_DEF: fig_size = (fig_size[0], 1.5*fig_size[1]) # extend height if == to default
  381. # Do we put the legend outside of the plot?
  382. l_legend_out = False ; y_leg = 0.
  383. if loc_legend == 'out':
  384. l_legend_out = True
  385. y_leg = 0.1 ; # Figure needs to be vertically extended in that case
  386. fig_size = (fig_size[0],(1.+y_leg)*fig_size[1])
  387. fig = plt.figure(num = 1, figsize=fig_size, facecolor='w', edgecolor='k')
  388. ax = plt.axes([0.08, 0.075, 0.9, 0.85])
  389. plt.plot(VYn, VZn*0.0, 'k', linewidth=1)
  390. plt.plot(VYn, VZn, 'k', linewidth=3., label=lab)
  391. if lp1: plt.plot(VY1, VZ1, color=b_red, linewidth=2., label=lab1)
  392. if lp2: plt.plot(VY2, VZ2, color=b_blu, linewidth=2., label=lab2)
  393. if lp3: plt.plot(VY3, VZ3, color=b_gre, linewidth=2., label=lab3)
  394. # X-axis
  395. __nice_latitude_axis__(ax, plt, xmin, xmax, dx, axt='x')
  396. # Y-axis:
  397. __nice_y_axis__(ax, plt, zmin, zmax, dz, i_sbsmp=i_z_jump, cunit=czunit, cfont=font_xylb, dy_minor=0)
  398. # Legend:
  399. __fancy_legend__(ax, plt, loc_leg=loc_legend, ylg=y_leg, leg_out=l_legend_out, ncol=1)
  400. plt.title(ctitle, **font_ttl)
  401. plt.savefig(cfignm+'.'+cfig_type, dpi=DPI_DEF, orientation='portrait', transparent=False)
  402. plt.close(1)
  403. return
  404. def __nproj(self,czone, rmin, rmax, dc, xlon, xlat, XF,
  405. cfignm='fig', lkcont=False, cpal='jet', cbunit=' ',
  406. cfig_type='pdf', ctitle=' ', lforce_lim=False,
  407. cb_orient='vertical', i_cb_subsamp=1, dpi_fig=DPI_DEF, lpcont=True):
  408. # Plot projection with basemap...
  409. #===================================================================================
  410. # INPUT:
  411. # xlon and xlat can be 1D or 2D !!!
  412. #
  413. # lpcont=True => do contourf
  414. # lpcont=False => do pcolor
  415. #
  416. #===================================================================================
  417. from mpl_toolkits.basemap import Basemap
  418. from mpl_toolkits.basemap import shiftgrid
  419. import barakuda_colmap as bcm
  420. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=dpi_fig)
  421. # For projections :
  422. vp = __give_proj__(czone) ; # projection information
  423. # must work with XFtmp rather than XF, because sometimes XF is overwrited...
  424. [ny, nx] = nmp.shape(XF)
  425. XFtmp = nmp.zeros(ny*nx) ; XFtmp.shape = [ny, nx]
  426. XFtmp[:,:] = XF[:,:]
  427. if len(nmp.shape(xlat)) == 1 and len(nmp.shape(xlon)) == 1:
  428. if czone == 'kav7' and xlon[0] >= 0.:
  429. # Shifting data and longitude to be consistent with map projection
  430. XFtmp, xlon = shiftgrid(180.+xlon[0], XFtmp, xlon, start=False, cyclic=360.0)
  431. LON_2D, LAT_2D = nmp.meshgrid(xlon,xlat)
  432. else:
  433. LAT_2D = nmp.zeros(ny*nx) ; LAT_2D.shape = [ny, nx] ; LAT_2D[:,:] = xlat[:,:]
  434. LON_2D = nmp.zeros(ny*nx) ; LON_2D.shape = [ny, nx] ; LON_2D[:,:] = xlon[:,:]
  435. if lforce_lim: __force_min_and_max__(rmin, rmax, XFtmp)
  436. vc = __vcontour__(rmin, rmax, dc)
  437. # Colorbar position/size if horizontal
  438. vcbar = [0.1, 0.08, 0.86, 0.03]
  439. # Figure/canvas size:
  440. if cb_orient == 'horizontal':
  441. if czone == 'natarct':
  442. vfig_size = [ 5.8, 5.6 ]; vsporg = [0.08, 0.1, 0.9, 0.92]
  443. vcbar = [0.05, 0.08, 0.9, 0.03]
  444. if czone == 'npol2':
  445. vfig_size = [ 4.4, 5.6 ]; vsporg = [0.01, 0.15, 1., 0.8]
  446. vcbar = [0.05, 0.065, 0.92, 0.03]
  447. if czone == 'kav7':
  448. vfig_size = [ 8.1, 5.6 ]; vsporg = [0.001, 0.15, 1., 0.8]
  449. vcbar = [0.04, 0.08, 0.92, 0.03]
  450. else:
  451. # Vertical color bar on the rhs
  452. rw = 5.
  453. vfig_size = [ rw, rw ]; vsporg = [0.1, 0.1, 0.85, 0.85]
  454. if czone == 'nseas': vfig_size = [ rw , 0.7*rw ]; vsporg = [0.08, 0.07, 0.85, 0.85]
  455. if czone == 'natarct': vfig_size = [ rw , rw ]; vsporg = [0.065, 0.04, 0.95, 0.92]
  456. if czone == 'spstere': vfig_size = [ rw , 0.76*rw ]; vsporg = [0.11, 0.05, 0.82, 0.89]
  457. if czone == 'npol2': vfig_size = [ rw , 0.96*rw ] ; vsporg = [0.1, 0.05, 0.86, 0.9]
  458. fig = plt.figure(num = 1, figsize=(vfig_size), dpi=None, facecolor='w', edgecolor='k')
  459. ax = plt.axes(vsporg, facecolor = 'w')
  460. ## Colmap:
  461. colmap = bcm.chose_colmap(cpal)
  462. pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
  463. mpl.rcParams['contour.negative_linestyle'] = 'solid'; plt.contour.negative_linestyle='solid'
  464. if vp[1] == 'lcc' or vp[1] == 'cyl' :
  465. carte = Basemap(llcrnrlon=vp[2],llcrnrlat=vp[3],urcrnrlon=vp[4],urcrnrlat=vp[5],\
  466. resolution=vp[9],area_thresh=1000.,projection=vp[1],\
  467. lat_1=vp[6],lon_0=vp[7])
  468. elif vp[1] == 'stere' :
  469. if vp[0] == 'spstere' or vp[0] == 'npstere':
  470. carte = Basemap(projection=vp[0], boundinglat=vp[6], lon_0=vp[7], resolution=vp[9])
  471. else:
  472. carte = Basemap(llcrnrlon=vp[2],llcrnrlat=vp[3],urcrnrlon=vp[4],urcrnrlat=vp[5],\
  473. resolution=vp[9],area_thresh=1000.,projection='stere',\
  474. lat_0=vp[6],lon_0=vp[7])
  475. elif vp[1] == 'kav' :
  476. print ' *** plot_nproj.barakuda_plot => Projection '+vp[0]+' / '+str(vp[7])+' / '+vp[9]
  477. carte = Basemap(projection=vp[0],lon_0=vp[7],resolution=vp[9])
  478. else:
  479. print 'ERROR: barakuda_plot.py => proj type '+vp[1]+' unknown!!!'; sys.exit(0)
  480. x0,y0 = carte(LON_2D,LAT_2D)
  481. if lpcont:
  482. cf = carte.contourf(x0, y0, XFtmp, vc, cmap = colmap, norm = pal_norm)
  483. # Black contours if needed :
  484. if lkcont:
  485. ckf = carte.contour(x0, y0, XFtmp, vc, colors='k', linewidths=0.5)
  486. if cpal != 'ice':
  487. for c in cf.collections: c.set_zorder(0.5) # Changing zorder so black cont. on top
  488. for c in ckf.collections: c.set_zorder(1.) # of filled cont. and under continents (zorder 1)
  489. else:
  490. cf = carte.pcolor(x0, y0, XFtmp, cmap = colmap, norm = pal_norm)
  491. carte.drawcoastlines() ; carte.fillcontinents(color='grey') ; carte.drawmapboundary()
  492. if vp[1] == 'lcc' or vp[1] == 'cyl':
  493. carte.drawmeridians(nmp.arange(-360,360,vp[8]), labels=[0,0,0,1])
  494. carte.drawparallels(nmp.arange( -90, 90,vp[8]), labels=[1,0,0,0])
  495. if vp[1] == 'stere':
  496. carte.drawmeridians(nmp.arange(-180,180,20), labels=[0,0,0,1])
  497. carte.drawparallels(nmp.arange( -90, 90,10), labels=[1,0,0,0])
  498. plt.title(ctitle, **font_ttl)
  499. # Colorbar:
  500. if cb_orient == 'horizontal':
  501. clbax = fig.add_axes(vcbar) # new axes for colorbar!
  502. __nice_colorbar__(cf, plt, vc, cax_other=clbax, i_sbsmp=i_cb_subsamp, lkc=(lkcont and lpcont), cb_or='horizontal', cunit=cbunit, cfont=font_clb, fontsize=10)
  503. else:
  504. __nice_colorbar__(cf, plt, vc, i_sbsmp=i_cb_subsamp, lkc=(lkcont and lpcont), cunit=cbunit, cfont=font_clb, fontsize=12)
  505. plt.savefig(cfignm+'.'+cfig_type, dpi=dpi_fig, orientation='portrait', transparent=False) ; #, transparent=True, acecolor='w', edgecolor='w',trans
  506. plt.close(1)
  507. print ' *** created figure '+cfignm+'.'+cfig_type+'\n'
  508. del LON_2D, LAT_2D, XFtmp
  509. return
  510. def __2d_box_2f(self,XF1, XF2, XMSK, rmin, rmax, dc, vcont_spec2, corca='ORCA1', lkcont=True,
  511. cpal='jet', cfignm='fig', cbunit='', ctitle=' ', lforce_lim=False,
  512. i_cb_subsamp=1, cfig_type='pdf', lcontours=True,
  513. x_offset=0., y_offset=0., vcont_spec1 = []):
  514. # Take 2 fields as imput and shows contours of second field (vcont_spec2) on top of field 1
  515. import matplotlib.colors as colors # colmap and co.
  516. import barakuda_colmap as bcm
  517. if nmp.shape(XF1) != nmp.shape(XF2):
  518. print 'ERROR barakuda_plot.plot_2d_box_2f: fields F1 and F2 dont have the same shape!'
  519. sys.exit(0)
  520. font_ttl, font_xylb, font_clb, font_inf = __font_unity__()
  521. if lforce_lim: __force_min_and_max__(rmin, rmax, XF1)
  522. [ ny , nx ] = XF1.shape
  523. vert_rat = float(ny)/float(nx)
  524. print "Vert. ratio, nx, ny =", vert_rat, nx, ny
  525. # Masking field:
  526. if lcontours:
  527. idxm = nmp.where(XMSK[:,:] == 0); XF1[idxm] = -9999.9 # c'est NaN qui merde!!!
  528. else:
  529. XF1 = nmp.ma.masked_where(XMSK == 0, XF1)
  530. # FIGURE
  531. # ~~~~~~
  532. fig = plt.figure(num = 1, figsize=(7.,6.*vert_rat), dpi=None, facecolor='w', edgecolor='k')
  533. ax = plt.axes([0.07, 0.05, 0.9, 0.9], facecolor = 'gray')
  534. vc = __vcontour__(rmin, rmax, dc); #print vc, '\n'
  535. # Colmap:
  536. colmap = bcm.chose_colmap(cpal)
  537. pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
  538. if lcontours:
  539. cf = plt.contourf(XF1, vc, cmap = colmap, norm = pal_norm)
  540. for c in cf.collections: c.set_zorder(0.5)
  541. else:
  542. cf = plt.pcolor(XF1, cmap = colmap, norm = pal_norm)
  543. # contour for specific values on the ploted field:
  544. if len(vcont_spec1) >= 1:
  545. cfs1 = plt.contour(XF1, vcont_spec1, colors='white', linewidths = 1.)
  546. plt.clabel(cfs1, inline=1, fmt='%4.1f', fontsize=10)
  547. # Contours of field F2:
  548. cfs2 = plt.contour(XF2, vcont_spec2, colors=b_red, linewidths = 1.3)
  549. #plt.clabel(cfs1, inline=1, fmt='%4.1f', fontsize=10)
  550. if lkcont:
  551. cfk = plt.contour(XF1, vc, colors='k', linewidths = 0.1)
  552. for c in cfk.collections: c.set_zorder(0.75)
  553. # contour for continents:
  554. if lcontours:
  555. cfm = plt.contour(XMSK, [ 0.7 ], colors='k', linewidths = 0.4)
  556. for c in cfm.collections: c.set_zorder(1.)
  557. # Colorbar:
  558. __nice_colorbar__(cf, plt, vc, i_sbsmp=i_cb_subsamp, lkc=lkcont, cunit=cbunit, cfont=font_clb)
  559. if x_offset > 0 or y_offset > 0 : __add_xy_offset__(plt, x_offset, y_offset)
  560. plt.axis([ 0., nx-1, 0, ny-1])
  561. plt.title(ctitle, **font_ttl)
  562. plt.savefig(cfignm+'.'+cfig_type, dpi=100, orientation='portrait', transparent=True)
  563. print ' => '+cfignm+'.'+cfig_type+' created!'
  564. plt.close(1)
  565. del Xtmp
  566. return
  567. def __trsp_sig_class(self,VT, vsigma_bounds, XF, rmin, rmax, dc,
  568. lkcont=True, cpal='sigtr', dt=5., cfignm='fig',
  569. cfig_type='pdf', ctitle='', vcont_spec1 = [],
  570. i_cb_subsamp=2):
  571. # Plot transport by sigma class...
  572. if nmp.sum(XF) == 0.:
  573. print '\n WARNING: plot_trsp_sig_class => doing nothing, arrays contains only 0!\n'
  574. else:
  575. import matplotlib.colors as colors # colmap and co.
  576. import barakuda_colmap as bcm
  577. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=DPI_DEF)
  578. fig = plt.figure(num = 1, figsize=(WDTH_DEF , RAT_XY*6.), dpi=None, facecolor='w', edgecolor='k') ; #trsp_sig_class
  579. ax = plt.axes([0.075, -0.025, 0.9, 0.98], facecolor = 'w')
  580. vc = __vcontour__(rmin, rmax, dc)
  581. nbins = len(vsigma_bounds) - 1
  582. # Colmap:
  583. colmap = bcm.chose_colmap(cpal)
  584. pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
  585. mpl.rcParams['contour.negative_linestyle'] = 'solid'
  586. plt.contour.negative_linestyle='solid'
  587. #cf = plt.contourf(VT, vsigma_bounds[:-1], XF, vc, cmap = colmap, norm = pal_norm)
  588. cf = plt.pcolormesh(VT, vsigma_bounds[:-1], XF, cmap = colmap, norm = pal_norm)
  589. if lkcont:
  590. cfc = plt.contour(VT, vsigma_bounds[:-1], XF, nmp.arange(-3.,3.,0.5), colors='k', linewidths=0.4)
  591. # contour for specific values on the ploted field:
  592. if len(vcont_spec1) >= 1:
  593. cfs1 = plt.contour(VT, vsigma_bounds[:-1], XF, vcont_spec1, colors='white', linewidths = 1.)
  594. plt.clabel(cfs1, inline=1, fmt='%4.1f', fontsize=11, manual=[(2080,2.)] )
  595. __nice_colorbar__(cf, plt, vc, i_sbsmp=i_cb_subsamp, cb_or='horizontal', cunit='Sv', cfont=font_clb, fontsize=10)
  596. # AXES:
  597. x1 = int(min(VT)) ; x2 = int(max(VT))+1
  598. plt.axis([x1, x2, vsigma_bounds[nbins], vsigma_bounds[0]])
  599. __nice_x_axis__(ax, plt, x1, x2, dt, cfont=font_xylb, dx_minor=__time_axis_minor_ticks__(dt))
  600. plt.yticks( nmp.flipud(vsigma_bounds) )
  601. label_big = { 'fontname':'Trebuchet MS', 'fontweight':'normal', 'fontsize':18 }
  602. plt.ylabel(r'$\sigma_0$', **label_big)
  603. plt.title(ctitle, **font_ttl)
  604. plt.savefig(cfignm+'.'+cfig_type, dpi=DPI_DEF, orientation='portrait', transparent=False) ; #trsp_sig_class
  605. print ' => '+cfignm+'.'+cfig_type+' created!'
  606. plt.close(1)
  607. return
  608. def __vert_section_extra(self,VX, VZ, XF, XMSK, Vcurve, rmin, rmax, dc, lkcont=True, cpal='jet', xmin=-80., xmax=85.,
  609. cfignm='fig', cbunit='', cxunit=' ', zmin = 0., zmax = 5000., l_zlog=False,
  610. cfig_type='pdf', czunit=' ', ctitle=' ', lforce_lim=False, fig_size=(8.,8.) ):
  611. import matplotlib.colors as colors # colmap and co.
  612. import barakuda_colmap as bcm
  613. zVZ = __prepare_z_log_axis__(l_zlog, VZ)
  614. XF = nmp.ma.masked_where(XMSK == 0, XF)
  615. if lforce_lim: __force_min_and_max__(rmin, rmax, XF)
  616. #
  617. font_ttl, font_xylb, font_clb, font_inf = __font_unity__()
  618. fig = plt.figure(num = 1, figsize=fig_size, dpi=None, facecolor='w', edgecolor='k')
  619. ax = plt.axes([0.1, 0.065, 0.92, 0.89], facecolor = 'gray')
  620. vc = __vcontour__(rmin, rmax, dc)
  621. # Colmap:
  622. colmap = bcm.chose_colmap(cpal)
  623. pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
  624. cf = plt.contourf(VX, zVZ, XF, vc, cmap = colmap, norm = pal_norm)
  625. if lkcont: plt.contour(VX, zVZ, XF, vc, colors='k', linewidths=0.2)
  626. # Colorbar:
  627. __nice_colorbar__(cf, plt, vc, i_sbsmp=i_cb_subsamp, cunit=cbunit, cfont=font_clb, fontsize=10)
  628. # X-axis:
  629. __nice_x_axis__(ax, plt, xmin, xmax, dx, cunit=cxunit, cfont=font_xylb)
  630. plt.plot(VX,Vcurve, 'w', linewidth=2)
  631. for zz in zVZ[:]: plt.plot(VX,VX*0.+zz, 'k', linewidth=0.3)
  632. # Depth axis:
  633. __nice_depth_axis__(ax, plt, zmin, zmax, l_log=l_zlog, l_z_inc=False, cunit=czunit, cfont=font_xylb)
  634. plt.title(ctitle, **font_ttl)
  635. plt.savefig(cfignm+'.'+cfig_type, dpi=100, orientation='portrait', transparent=True)
  636. print ' => '+cfignm+'.'+cfig_type+' created!'
  637. plt.close(1)
  638. #
  639. return
  640. def __hovmoeller(self, VT, VY, XF, XMSK, rmin, rmax, dc, c_y_is='depth',
  641. lkcont=False, cpal='jet', tmin=0., tmax=50., dt=5,
  642. ymin=0., ymax=5000., dy=100., l_ylog=False,
  643. cfignm='fig', cbunit='', ctunit=' ', cfig_type='png',
  644. cyunit=' ', ctitle=' ', i_cb_subsamp=1,
  645. l_y_increase=False ):
  646. #
  647. # c_y_is : 'depth', 'latitude'
  648. # lkcont : use contours rather than "pcolormesh"
  649. #
  650. import barakuda_colmap as bcm
  651. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=DPI_DEF)
  652. if c_y_is == 'depth':
  653. zVY = __prepare_z_log_axis__(l_ylog, VY)
  654. vax = [0.095, 0.06, 0.92, 0.88]
  655. else:
  656. zVY = VY
  657. vax = [0.05, 0.06, 0.98, 0.88]
  658. # Masking where mask is zero!
  659. XF = nmp.ma.masked_where(XMSK == 0, XF)
  660. fig = plt.figure(num = 1, figsize=(WDTH_DEF , RAT_XY*5.), dpi=None, facecolor='w', edgecolor='k')
  661. ax = plt.axes(vax, facecolor='gray')
  662. vc = __vcontour__(rmin, rmax, dc)
  663. # Colormap:
  664. colmap = bcm.chose_colmap(cpal)
  665. pal_norm = colors.Normalize(vmin = rmin, vmax = rmax, clip = False)
  666. if lkcont:
  667. cf = plt.contourf(VT, zVY, XF, vc, cmap = colmap, norm = pal_norm)
  668. #plt.contour( VT, zVY, XF, vc, colors='k', linewidths=0.2)
  669. else:
  670. cf = plt.pcolormesh(VT, zVY, XF, cmap = colmap, norm = pal_norm)
  671. __nice_colorbar__(cf, plt, vc, i_sbsmp=i_cb_subsamp, cunit=cbunit, cfont=font_clb, fontsize=10)
  672. # Time-axis:
  673. __nice_x_axis__(ax, plt, tmin, tmax, dt, cunit=ctunit, cfont=font_xylb, dx_minor=__time_axis_minor_ticks__(dt))
  674. # Y-axis:
  675. if c_y_is == 'depth':
  676. __nice_depth_axis__(ax, plt, ymin, ymax, l_log=l_ylog, l_z_inc=l_y_increase, cunit=cyunit, cfont=font_xylb)
  677. elif c_y_is == 'latitude':
  678. __nice_latitude_axis__(ax, plt, ymin, ymax, dy, axt='y')
  679. else:
  680. print 'ERROR: plot_hoevmoller.barakuda_plot => axis "'+c_y_is+'" not supported!'; sys.exit(0)
  681. plt.title(ctitle, **font_ttl)
  682. plt.savefig(cfignm+'.'+cfig_type, dpi=DPI_DEF, orientation='portrait', transparent=False) ; #vert_section
  683. print ' => '+cfignm+'.'+cfig_type+' created!'
  684. plt.close(1)
  685. return
  686. def __oscillation_index(self, VT, VF, ymax=2.5, dy=0.5, yplusminus=0.,
  687. tmin=0., tmax=0., dt=5,
  688. cfignm='fig', cfig_type='png', cyunit='', ctitle=''):
  689. #--------------------------------------------------------------------------------------
  690. # Plot a ENSO / AMO / PDO -like graph from a time series VF that
  691. # has already been smoothed and detrended
  692. #--------------------------------------------------------------------------------------
  693. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=DPI_DEF)
  694. Nt = len(VT)
  695. if len(VF) != Nt: print 'ERROR: oscillation_index.barakuda_plot => VT and VF do not agree in size'; sys.exit(0)
  696. vf_plus = nmp.zeros(Nt) ; vf_mins = nmp.zeros(Nt)
  697. vf_plus[:] = VF[:] ; vf_mins[:] = VF[:]
  698. vf_plus[nmp.where(VF[:] < 0. )] = 0.
  699. vf_mins[nmp.where(VF[:] > 0. )] = 0.
  700. vf_plus[0] = 0. ; vf_mins[0] = 0.
  701. vf_plus[-1] = 0. ; vf_mins[-1] = 0.
  702. t1 = tmin ; t2 = tmax
  703. if tmin == 0. and tmax == 0.:
  704. t1 = float(int(min(VT)))
  705. t2 = float(int(round(max(VT),0)))
  706. fig = plt.figure(num = 2, figsize=FIG_SIZE_DEF, facecolor='w', edgecolor='k')
  707. ax = plt.axes(AXES_DEF)
  708. if yplusminus > 0.:
  709. plt.plot(VT, 0.*VT+yplusminus, 'r--', linewidth=1.5)
  710. plt.plot(VT, 0.*VT-yplusminus, 'b--', linewidth=1.5)
  711. plt.fill(VT, vf_plus, b_red, VT, vf_mins, b_blu, linewidth=0)
  712. plt.plot(VT, VF[:], 'k', linewidth=0.7)
  713. plt.plot(VT, 0.*VT, 'k', linewidth=0.7)
  714. __nice_x_axis__(ax, plt, t1, t2, dt, cfont=font_xylb)
  715. __nice_y_axis__(ax, plt, -ymax, ymax, dy, cunit=cyunit, cfont=font_xylb)
  716. plt.title(ctitle, **font_ttl)
  717. plt.savefig(cfignm+'.'+cfig_type, dpi=DPI_DEF, orientation='portrait', transparent=True)
  718. plt.close(2)
  719. return
  720. def __1d_mon_ann(self,VTm, VTy, VDm, VDy, cfignm='fig', dt=5, cyunit='', ctitle='',
  721. ymin=0, ymax=0, dy=0, i_y_jump=1, mnth_col='b', plt_m03=False, plt_m09=False,
  722. cfig_type='png', l_tranparent_bg=True, fig_size=FIG_SIZE_DEF, y_cst_to_add=-9999.):
  723. # if you specify ymin and ymax you can also specify y increment (for y grid) as dy
  724. #
  725. # plt_m03 => plot march values on top in green
  726. # plt_m09 => plot september values on top in green
  727. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=DPI_DEF)
  728. Nt1 = len(VTm) ; Nt2 = len(VTy)
  729. if len(VTm) != len(VDm): print 'ERROR: plot_1d_mon_ann.barakuda_plot => VTm and VDm do not agree in size'; sys.exit(0)
  730. if len(VTy) != len(VDy): print 'ERROR: plot_1d_mon_ann.barakuda_plot => VTy and VDy do not agree in size'; sys.exit(0)
  731. l_add_monthly = True
  732. if Nt1 == Nt2: l_add_monthly = False
  733. y_leg = 0.
  734. if plt_m03 or plt_m09:
  735. # We put the legend outside of the plot...
  736. y_leg = 0.075*2. ; # Figure needs to be vertically extended in that case
  737. fig_size = (fig_size[0],(1.+y_leg)*fig_size[1])
  738. fig = plt.figure(num = 1, figsize=fig_size, facecolor='w', edgecolor='k')
  739. ax = plt.axes(AXES_DEF) ; #1d_mon_ann
  740. if mnth_col == 'g': mnth_col = b_gre
  741. if mnth_col == 'b': mnth_col = b_blu
  742. if y_cst_to_add > -9000.:
  743. plt.plot(VTm, VTm*0.+y_cst_to_add, 'k', label=None, linewidth=1.8)
  744. if l_add_monthly:
  745. plt.plot(VTm, VDm, mnth_col, label=r'monthly', linewidth=1)
  746. plt.plot(VTy, VDy, b_red, label=r'annual', linewidth=2)
  747. ax.get_yaxis().get_major_formatter().set_useOffset(False); # Prevents from using scientific notations in axess ticks numbering
  748. if l_add_monthly:
  749. if plt_m03: plt.plot(VTm[2:Nt1:12], VDm[2:Nt1:12], 'orange', label=r'March', linewidth=2)
  750. if plt_m09: plt.plot(VTm[8:Nt1:12], VDm[8:Nt1:12], 'orange', label=r'September', linewidth=2)
  751. if plt_m03 or plt_m09:
  752. box = ax.get_position()
  753. ax.set_position([box.x0, box.y0 + box.height*y_leg, box.width, box.height*(1.-y_leg)])
  754. plt.legend(bbox_to_anchor=(0.95, -0.075), ncol=2, shadow=True, fancybox=True)
  755. # Time bounds for t-axis:
  756. dcorr = 0.
  757. x1 = float(int(min(VTy)))
  758. #x2 = float(int(max(VTy)))
  759. x2 = round(max(VTy),0)
  760. #if min(VTy)-x1==0.5:
  761. #x1 = int(min(VTy)-dcorr)
  762. #x2 = int(max(VTy)+dcorr)
  763. mean_val = nmp.mean(VDy)
  764. df = max( abs(min(VDm)-mean_val), abs(max(VDm)-mean_val) )
  765. if ymin==0 and ymax==0:
  766. y1, y2, dy = __suitable_axis_dx__(min(VDm)-0.2*df, max(VDm)+0.2*df, nb_val=10.)
  767. elif dy == 0:
  768. y1, y2, dy = __suitable_axis_dx__(ymin, ymax, nb_val=10.)
  769. else:
  770. y1=ymin ; y2=ymax
  771. __nice_y_axis__(ax, plt, y1, y2, dy, i_sbsmp=i_y_jump, cunit=cyunit, cfont=font_xylb, dy_minor=0)
  772. __nice_x_axis__(ax, plt, x1, x2, dt, cfont=font_xylb, dx_minor=__time_axis_minor_ticks__(dt))
  773. plt.title(ctitle, **font_ttl)
  774. cf_fig = cfignm+'.'+cfig_type
  775. plt.savefig(cf_fig, dpi=DPI_DEF, orientation='portrait', transparent=l_tranparent_bg)
  776. print ' => '+cfignm+'.'+cfig_type+' created!'
  777. plt.close(1)
  778. def __1d_multi(self,vt, XD, vlabels, cfignm='fig', dt=5, i_t_jump=1, cyunit=None, ctitle='',
  779. cfig_type='png', ymin=0, ymax=0, lzonal=False, xmin=0, xmax=0,
  780. loc_legend='lower center', line_styles=[], fig_size=FIG_SIZE_DEF,
  781. l_tranparent_bg=True, cxunit=None, lmask=True, cinfo='', y_cst_to_add=-9999.):
  782. # lzonal => zonally averaged curves...
  783. if lzonal:
  784. font_ttl, font_big_fixed, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=DPI_DEF, size='big')
  785. else:
  786. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=DPI_DEF)
  787. # Number of lines to plot:
  788. [ nb_plt, nbt ] = XD.shape
  789. if len(vt) != nbt: print 'ERROR: plot_1d_multi.barakuda_plot.py => vt and XD do not agree in shape! =>', len(vt), nbt,'\n'; sys.exit(0)
  790. if len(vlabels) != nb_plt: print 'ERROR: plot_1d_multi.barakuda_plot.py => wrong number of labels...'; sys.exit(0)
  791. n0 = len(line_styles)
  792. if n0 > 0 and n0 != nb_plt: print 'ERROR: plot_1d_multi.barakuda_plot.py => wrong number line styles!!!'; sys.exit(0)
  793. nb_col, nb_row = __nb_col_row_legend__(nb_plt) ; # nb of columns and rows for legend
  794. # Do we put the legend outside of the plot?
  795. l_legend_out = False ; y_leg = 0.
  796. if loc_legend == 'out':
  797. l_legend_out = True
  798. y_leg = 0.075*nb_row ; # Figure needs to be vertically extended in that case
  799. fig_size = (fig_size[0],(1.+y_leg)*fig_size[1])
  800. # Masking the time-series shorter than others (masked with -999.)
  801. if lmask: XD = nmp.ma.masked_where(XD < -900., XD)
  802. if lzonal:
  803. fig = plt.figure(num = 1, figsize=fig_size, facecolor='w', edgecolor='k')
  804. ax = plt.axes([0.08, 0.11, 0.88, 0.83])
  805. else:
  806. fig = plt.figure(num = 1, figsize=fig_size, facecolor='w', edgecolor='k')
  807. ax = plt.axes(AXES_DEF) ; #1d_multi
  808. if y_cst_to_add > -9000.:
  809. plt.plot(vt, vt*0.+y_cst_to_add, 'k', label=None, linewidth=1.8)
  810. if lzonal: plt.plot(vt, XD[0,:]*0., 'k', linewidth=1)
  811. if n0 <= 0 and nb_plt > nmax_colors:
  812. print 'ERROR: plot_1d_multi.barakuda_plot => not enough colors defined in "v_dflt_colors", extend it!!!'
  813. sys.exit(0)
  814. for jp in range(nb_plt):
  815. if n0 > 0:
  816. plt.plot(vt, XD[jp,:], line_styles[jp], label=vlabels[jp], linewidth=2)
  817. else:
  818. plt.plot(vt, XD[jp,:], v_dflt_colors[jp], label=vlabels[jp], linewidth=2)
  819. #ax.get_yaxis().get_major_formatter().set_useOffset(False) ; # Prevents from using scientific notations in axess ticks numbering
  820. if lzonal:
  821. dt = 15. ; # x-axis increment (latitude!)
  822. if xmin == 0 and xmax == 0:
  823. x1 = -90. ; x2 = 90.
  824. else:
  825. x1 = xmin ; x2 = xmax
  826. else:
  827. if xmin == 0 and xmax == 0:
  828. x1 = int(vt[0])
  829. x2 = int(round(vt[len(vt)-1]+0.4))
  830. else:
  831. x1 = xmin ; x2 = xmax
  832. if ymin==0 and ymax==0:
  833. ymin = nmp.min(XD[:,:])
  834. ymax = nmp.max(XD[:,:])
  835. ymin, ymax, dy = __suitable_axis_dx__(ymin, ymax, nb_val=10.)
  836. if lzonal:
  837. __nice_x_axis__(ax, plt, x1, x2, 10., cunit=r'Latitude ($^{\circ}$N)', cfont=font_xylb, dx_minor=5.)
  838. else:
  839. __nice_x_axis__(ax, plt, x1, x2, dt, i_sbsmp=i_t_jump, cunit=cxunit, cfont=font_xylb, dx_minor=__time_axis_minor_ticks__(dt))
  840. __nice_y_axis__(ax, plt, ymin, ymax, dy, i_sbsmp=1, cunit=cyunit, cfont=font_xylb, dy_minor=0)
  841. plt.title(ctitle, **font_ttl)
  842. if cinfo != '':
  843. # Ading info:
  844. yp = 0.95
  845. if loc_legend != '0' and l_legend_out: yp = -0.1
  846. props = dict(boxstyle='round', facecolor='w') ;#, alpha=0.5)
  847. ax.text(0.05, yp, cinfo, transform=ax.transAxes,
  848. verticalalignment='top', bbox=props, fontsize=10)
  849. __fancy_legend__(ax, plt, loc_leg=loc_legend, ylg=y_leg, leg_out=l_legend_out, ncol=nb_col)
  850. cf_fig = cfignm+'.'+cfig_type
  851. plt.savefig(cf_fig, dpi=DPI_DEF, orientation='portrait', transparent=l_tranparent_bg) ; #1d_multi
  852. plt.close(1)
  853. print ' => Multi figure "'+cf_fig+'" created!'
  854. def __1d(self,vt, VF, cfignm='fig', dt=5, i_t_jump=1, cyunit='', ctitle='',
  855. cfig_type='png', ymin=0, ymax=0, xmin=0, xmax=0,
  856. loc_legend='lower center', line_styles='-', fig_size=FIG_SIZE_DEF,
  857. l_tranparent_bg=False, cxunit='', lmask=True):
  858. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=DPI_DEF)
  859. # Number of lines to plot:
  860. nbt = len(VF)
  861. if len(vt) != nbt: print 'ERROR: plot_1d.barakuda_plot.py => vt and VF do not agree in shape!'; sys.exit(0)
  862. # Masking the time-series shorter than others (masked with -999.)
  863. if lmask: VF = nmp.ma.masked_where(VF < -900., VF)
  864. fig = plt.figure(num = 1, figsize=fig_size, facecolor='w', edgecolor='k')
  865. ax = plt.axes(AXES_DEF) ; #1d
  866. plt.plot(vt, VF[:], line_styles, linewidth=2)
  867. ax.get_yaxis().get_major_formatter().set_useOffset(False) ; # Prevents from using scientific notations in axess ticks numbering
  868. if xmin == 0 and xmax == 0:
  869. x1 = int(vt[0])
  870. x2 = int(round(vt[len(vt)-1]+0.4))
  871. else:
  872. x1 = xmin ; x2 = xmax
  873. if ymin==0 and ymax==0:
  874. mean_val = nmp.mean(VF[:])
  875. dA = max( abs(nmp.min(VF[:])-mean_val), abs(nmp.max(VF[:])-mean_val) )
  876. plt.axis( [x1, x2, nmp.min(VF[:])-0.2*dA, nmp.max(VF[:])+0.2*dA] )
  877. else:
  878. plt.axis([x1, x2, ymin, ymax])
  879. print nmp.arange(x1, x2+dt, dt)
  880. __nice_x_axis__(ax, plt, x1, x2, dt, i_sbsmp=i_t_jump, cfont=font_xylb)
  881. if cyunit != '': plt.ylabel('('+cyunit+')', **font_xylb)
  882. if cxunit != '': plt.xlabel('('+cxunit+')', **font_xylb)
  883. plt.title(ctitle, **font_ttl)
  884. cf_fig = cfignm+'.'+cfig_type
  885. plt.savefig(cf_fig, dpi=DPI_DEF, orientation='portrait', transparent=l_tranparent_bg) ; #1d
  886. plt.close(1)
  887. print ' => Multi figure "'+cf_fig+'" created!'
  888. def __spectrum(self,vfrq, Vspec, cfignm='fig', cyunit='', log_x=True, log_y=False,
  889. year_min=3., year_max = 50., rmax_amp = 10., rmin_amp = 0.,
  890. cfig_type='png', vnoise=[ 0 ], vrci95=[ 0 ], lab95_xpos=0.5, lplot_1onF=False,
  891. cnoise='White noise', lplot_freq_ax=True):
  892. l_do_ci95 = False ; l_do_ci95m = False
  893. nnoise = len(vnoise); nl95 = len(vrci95)
  894. if nnoise != 1 and nl95 != 1:
  895. if nl95 != len(Vspec) or nl95 != nnoise:
  896. print "ERROR: plot_spectrum.barakuda_plot.py => length of 95 CI array and/or noise array doesnt match spectrum length!"
  897. sys.exit(0)
  898. l_do_ci95 = True
  899. l_do_ci95m = True
  900. font_ttl, font_xylb, font_clb, font_inf = __font_unity__()
  901. print "avant:", rmin_amp, rmax_amp
  902. if log_y:
  903. if rmin_amp <= 0.: rmin_amp = 0.01
  904. rmin_amp = 20.*nmp.log10(rmin_amp); rmax_amp = 20.*nmp.log10(rmax_amp)
  905. print "apres:", rmin_amp, rmax_amp
  906. # Spectral axis:
  907. x_min = 1./year_max ; x_max = 1./year_min ; # min and max in frequency!
  908. clbnd = str(int(round(year_min)))
  909. if log_x:
  910. cvee = [ '50','45','40','35','30','25','22','20','17','15','13','12','11','10','9','8','7','6','5','4','3' ]
  911. if year_max == 40.: cvee = cvee[2:]
  912. if year_max == 35.: cvee = cvee[3:]
  913. if year_min == 5.: cvee = cvee[:-2]
  914. else:
  915. cvee = [ '50','30','20','15','12','10','9','8','7','6','5','4', '3' ]
  916. lvee = []
  917. civee = []
  918. for ce in cvee:
  919. lvee.append(float(ce))
  920. civee.append(str(round(1./float(ce),3)))
  921. vee = nmp.asarray(lvee)
  922. print civee[:]
  923. rnoise = nmp.mean(vnoise[5:20])
  924. rrci95 = nmp.mean(vrci95[5:20])
  925. fig = plt.figure(num = 1, figsize=(8.,4.), facecolor='w', edgecolor='k')
  926. if lplot_freq_ax:
  927. ax = plt.axes([0.069, 0.13, 0.9, 0.8])
  928. else:
  929. ax = plt.axes([0.08, 0.13, 0.9, 0.83])
  930. if log_x:
  931. ifr1 = 1
  932. vfl = nmp.log10(vfrq[ifr1:])
  933. if not log_y:
  934. if l_do_ci95:
  935. plt.plot(vfl, vnoise[ifr1:], '--k' , linewidth=1.8, label=cnoise)
  936. plt.plot(vfl, vnoise[ifr1:]+vrci95[ifr1:], '0.4', linewidth=1.8, label='95% CI')
  937. plt.plot(vfl, vnoise[ifr1:]-vrci95[ifr1:], '0.4', linewidth=1.8)
  938. plt.plot(vfl, Vspec[ifr1:], '*-k', linewidth=2.)
  939. #if lplot_1onF: plt.plot(vfl, 1./vfl, b_red, linewidth=2)
  940. else:
  941. if l_do_ci95:
  942. plt.plot(vfl, 20.*nmp.log10(vnoise[ifr1:]), '--k' , linewidth=1.8, label=cnoise)
  943. plt.plot(vfl, 20.*nmp.log10(vnoise[ifr1:]+vrci95[ifr1:]), '0.4', linewidth=1.8, label='95% CI')
  944. plt.plot(vfl, 20.*nmp.log10(vnoise[ifr1:]-vrci95[ifr1:]), '0.4', linewidth=1.8)
  945. plt.plot(vfl, 20.*nmp.log10(Vspec[ifr1:]), '*-k', linewidth=2.)
  946. else:
  947. if not log_y:
  948. if l_do_ci95:
  949. plt.plot(vfrq, vnoise, '--k' , linewidth=1.8)
  950. plt.plot(vfrq, vnoise+vrci95, '0.4', linewidth=1.8)
  951. plt.plot(vfrq, vnoise-vrci95, '0.4', linewidth=1.8)
  952. plt.plot(vfrq, Vspec, '*-k', linewidth=2)
  953. if lplot_1onF: plt.plot(vfrq[1:], 0.03*1./vfrq[1:], b_red, linewidth=2)
  954. else:
  955. if l_do_ci95:
  956. plt.plot(vfrq, 20.*nmp.log10(vnoise), '--k' , linewidth=1.8)
  957. plt.plot(vfrq, 20.*nmp.log10(vnoise+vrci95), '0.4', linewidth=1.8)
  958. plt.plot(vfrq, 20.*nmp.log10(vnoise-vrci95), '0.4', linewidth=1.8)
  959. plt.plot(vfrq, 20.*nmp.log10(Vspec), '*-k', linewidth=2)
  960. plt.ylabel('Amplitude Spectrum ('+cyunit+')', color='k', **font_xylb)
  961. plt.xlabel('Period (years)', color='k', **font_xylb)
  962. if log_x:
  963. x1=nmp.log10(x_max) ; x2=nmp.log10(x_min)
  964. plt.axis([x1, x2, rmin_amp, rmax_amp])
  965. if lplot_freq_ax:
  966. plt.xticks(nmp.log10(1./vee[:]),cvee[:])
  967. else:
  968. print ''
  969. vee_n = nmp.arange(vee[0], vee[len(vee)-1]-1, -1.)
  970. print vee_n[:]
  971. cvee_n = []
  972. for rr in vee_n:
  973. cr = str(int(rr))
  974. if cr in cvee:
  975. cvee_n.append(cr)
  976. else:
  977. cvee_n.append('')
  978. print 'cvee =>', cvee[:]
  979. print 'cvee_n =>', cvee_n[:]
  980. plt.xticks(nmp.log10(1./vee_n[:]),cvee_n[:])
  981. else:
  982. x1=x_max; x2=x_min
  983. plt.axis([x1, x2, rmin_amp, rmax_amp])
  984. plt.xticks(1./vee[:],cvee[:], color='k')
  985. ax.grid(color='0.4', linestyle='-', linewidth=0.3)
  986. plt.legend(loc='upper left', shadow=False, fancybox=True)
  987. if lplot_freq_ax:
  988. ax2 = ax.twiny()
  989. ax2.set_xlabel('Frequency (cpy)', color='k', **font_xylb)
  990. if log_x:
  991. plt.axis([x1, x2, rmin_amp, rmax_amp])
  992. for jp in range(1,18,2): civee[jp] = ''
  993. plt.xticks(nmp.log10(1./vee[:]),civee)
  994. #ax2.xaxis.set_ticks(nmp.log10(1./vee[:]))
  995. else:
  996. plt.axis([x1, x2, rmin_amp, rmax_amp])
  997. plt.xticks(1./vee[:],civee)
  998. for t in ax2.get_xticklabels(): t.set_fontsize(14)
  999. ax2.xaxis.labelpad = 12 ; # move label upwards a bit...
  1000. plt.savefig(cfignm+'.'+cfig_type, dpi=100, facecolor='w', edgecolor='w', orientation='portrait', transparent=False)
  1001. plt.close(1)
  1002. def __del__(self) :
  1003. plot.__counter -= 1
  1004. #
  1005. def __pow_spectrum_ssh(self, vk1, vps1, clab1=None, clr1=b_gre, lw1=6, \
  1006. cfig_name='fig_spectrum_SSH.png', cinfo='', logo_on=True, \
  1007. L_min=7., L_max=5000., P_min_y=-6, P_max_y=6, \
  1008. l_show_k11o3=False, l_show_k5=False, l_show_k4=False, l_show_k2=False, \
  1009. vk2=[], vps2=[], clab2=None, clr2=b_org, lw2=3, \
  1010. vk3=[], vps3=[], clab3=None, clr3=b_blu, lw3=4, \
  1011. vk4=[], vps4=[], clab4=None, clr4='0.5', lw4=3 ):
  1012. #------------------------------------------------------------------
  1013. ## L_min=7. ; L_max : min and max wave-length for x-axis (km)
  1014. #------------------------------------------------------------------
  1015. #
  1016. # r2Pi = 2.*nmp.pi # k is in rad/[space unit]
  1017. r2Pi = 1. # k is in cycle/[space unit]
  1018. #
  1019. font_ttl, font_xylb, font_clb, font_inf = __font_unity__(fig_dpi=80)
  1020. #
  1021. # x-axis (lambda):
  1022. k_min = r2Pi/L_max ; k_max = r2Pi/L_min
  1023. xdef_l = nmp.asarray([ 4000., 2500., 1500., 1000., 700., 500., 300., 200., 150., 100., 70., 50., 40., 25., 15., 10., 7., 5., 4., 3., 2. ])
  1024. (idx1,) = nmp.where(xdef_l>L_max) ; (idx2,) = nmp.where(xdef_l<L_min)
  1025. xtcks_l = nmp.delete(xdef_l,nmp.concatenate((idx1,idx2)))
  1026. cxtcks_l = []
  1027. for rr in xtcks_l: cxtcks_l.append(str(int(rr)))
  1028. xtcks_k = r2Pi/xtcks_l
  1029. fig = plt.figure(num = 1, figsize=(9.,9.), facecolor='w', edgecolor='k')
  1030. ax = plt.axes([0.1, 0.07, 0.875, 0.86])
  1031. if len(vk3) > 1 and len(vps3) > 1:
  1032. plt.plot(nmp.log10(vk3), nmp.log10(vps3), '-', color=clr3, linewidth=lw3, label=clab3, zorder=10)
  1033. if len(vk2) > 1 and len(vps2) > 1:
  1034. plt.plot(nmp.log10(vk2), nmp.log10(vps2), '-', color=clr2, linewidth=lw2, label=clab2, zorder=15)
  1035. if len(vk4) > 1 and len(vps4) > 1:
  1036. plt.plot(nmp.log10(vk4), nmp.log10(vps4), '-', color=clr4, linewidth=lw4, label=clab4, zorder=4)
  1037. plt.plot( nmp.log10(vk1), nmp.log10(vps1), '-', color=clr1, linewidth=lw1, label=clab1, zorder=5)
  1038. nl = len(vk1)
  1039. #i1=4 ; i2=nl-0.4*nl ; rfct = 1.
  1040. i1=int(0.53*float(nl)) ; i2=nl ; rfct = 3.
  1041. if l_show_k2:
  1042. plt.plot(nmp.log10(vk1[i1:i2]), nmp.log10((vk1[i1:i2]**-2.)/(rfct*1.E7)), '--', color='k', linewidth=2, label=r'k$^\mathregular{-2}$', zorder=2)
  1043. if l_show_k4:
  1044. plt.plot(nmp.log10(vk1[i1:i2]), nmp.log10((vk1[i1:i2]**-4.)/(rfct*3.E8)), '-', color='0.6', linewidth=2, label=r'k$^\mathregular{-4}$', zorder=1)
  1045. if l_show_k5:
  1046. plt.plot(nmp.log10(vk1[i1:i2]), nmp.log10((vk1[i1:i2]**-5.)/(rfct*2.E10)), '--', color='0.6', linewidth=2, label=r'k$^\mathregular{-5}$', zorder=2)
  1047. if l_show_k11o3:
  1048. plt.plot(nmp.log10(vk1[i1:i2]), nmp.log10((vk1[i1:i2]**(-11./3.))/(rfct*1.E9)), '-.', color='0.6', linewidth=2, label=r'k$^\mathregular{-11/3}$', zorder=2)
  1049. # Bottom X-axis:
  1050. plt.xticks( nmp.log10(xtcks_k), cxtcks_l)
  1051. ax.set_xlim(nmp.log10(k_min), nmp.log10(k_max))
  1052. ax.grid(color='k', linestyle='-', linewidth=0.2)
  1053. plt.xlabel('Wave-length [km]')
  1054. #
  1055. # Y-axis:
  1056. ax.set_ylim(P_min_y,P_max_y)
  1057. cytcks = []
  1058. for ii in range(P_min_y,P_max_y+1): cytcks.append(r'$\mathregular{10^{'+str(ii)+'}}$')
  1059. plt.yticks( nmp.arange(P_min_y,P_max_y+1,1) , nmp.asarray(cytcks))
  1060. plt.ylabel(r'SSH PSD [$\mathregular{m^2}$/(cy/km)]', color='k')
  1061. #
  1062. if clab1 != None: plt.legend(loc='best', shadow=True, fancybox=True) ; #lulu
  1063. #
  1064. # Top X-axis:
  1065. ax2 = ax.twiny()
  1066. P_max_x = 1 ; P_min_x = -4
  1067. cxtcks_k = []
  1068. for ii in range(P_min_x,P_max_x+1): cxtcks_k.append(r'$\mathregular{10^{'+str(ii)+'}}$')
  1069. plt.xticks( nmp.arange(P_min_x,P_max_x+1,1) , nmp.asarray(cxtcks_k))
  1070. ax2.set_xlim(nmp.log10(k_min), nmp.log10(k_max))
  1071. #ax2.grid(color='0.3', linestyle='--', linewidth=0.2)
  1072. [t.set_color('0.3') for t in ax2.xaxis.get_ticklabels()]
  1073. plt.xlabel('Wave-number [cy/km]', color='0.3')
  1074. #
  1075. if cinfo != '': ax2.annotate(cinfo, xy=(0.08, 0.24), xycoords='axes fraction', bbox={'facecolor':clr_inf_box, 'alpha':1., 'pad':10}, zorder=100, **font_inf)
  1076. #
  1077. if logo_on:
  1078. fon = { 'fontname':'Arial', 'fontweight':'normal', 'fontsize':10 }
  1079. ax2.annotate('© Ocean Next, 2018', xy=(0.84, -0.06), xycoords='axes fraction', color='0.5', zorder=100, **fon)
  1080. #
  1081. plt.savefig(cfig_name, dpi=120, facecolor='w', edgecolor='w', orientation='portrait')
  1082. plt.close(1)
  1083. return 0
  1084. # LOCAL functions
  1085. # ===============
  1086. def __get_mat__(cf):
  1087. f1 = open(cf, 'r')
  1088. lines1=f1.readlines()
  1089. f1.close()
  1090. zm = [] ; jy = 0
  1091. for l in lines1:
  1092. if l[0] != '#':
  1093. jy = jy + 1
  1094. ls = l.split()
  1095. zm.append([])
  1096. for c in ls:
  1097. zm[jy-1].append(float(c))
  1098. zxm = array(zm)
  1099. print 'Shape zxm = ',nmp.shape(zxm), '\n'
  1100. return zxm
  1101. def __vcontour__(zmin, zmax, zdc):
  1102. if (zmin,zmax) == (0.,0.) or (zmin,zmax) == (0,0):
  1103. vcont = [0.]
  1104. else:
  1105. lngt = zmax - zmin
  1106. ncont = lngt/zdc
  1107. vcont = nmp.arange(zmin, zmax + zdc, zdc)
  1108. return vcont
  1109. def __name_longitude_ticks__(lon_min=0., lon_max=360., dlon=30., lon_ext=0):
  1110. #
  1111. # Builds nice ticks for X (lon) axis!
  1112. #
  1113. # Arrange longitude axis !
  1114. VX = nmp.arange(lon_min, lon_max+lon_ext+dlon, dlon); VX0 = nmp.arange(lon_min, lon_max+lon_ext+dlon, dlon);
  1115. ivf = nmp.where(VX>180); VX0[ivf] = VX[ivf] - 360
  1116. cn_lon = []
  1117. for rlon in VX0:
  1118. jlon = int(rlon)
  1119. if jlon < 0:
  1120. cn_lon.append(str(-jlon)+r'$^{\circ}$W')
  1121. else:
  1122. if jlon == 0:
  1123. cn_lon.append(str(jlon)+r'$^{\circ}$')
  1124. else:
  1125. cn_lon.append(str(jlon)+r'$^{\circ}$E')
  1126. return VX, cn_lon
  1127. def __name_latitude_ticks__(lat_min=-90., lat_max=90., dlat=15.):
  1128. #
  1129. # Builds nice ticks for Y (lat) axis!
  1130. #
  1131. # Arrange latitude axis !
  1132. VY = nmp.arange(lat_min, lat_max+dlat, dlat)
  1133. cn_lat = []
  1134. for rlat in VY:
  1135. jlat = int(rlat)
  1136. if jlat < 0:
  1137. cn_lat.append(str(-jlat)+r'$^{\circ}$S')
  1138. else:
  1139. if jlat == 0:
  1140. cn_lat.append(str(jlat)+r'$^{\circ}$')
  1141. else:
  1142. cn_lat.append(str(jlat)+r'$^{\circ}$N')
  1143. return VY, cn_lat
  1144. def __name_coor_ticks__(lon_min=0., lon_max=360., dlon=30., lat_min=-90., lat_max=90., dlat=15., lon_ext=0):
  1145. # Builds nice ticks for X and Y (lon, lat) axes!
  1146. VX, cn_lon = __name_longitude_ticks__(lon_min=lon_min, lon_max=lon_max, dlon=dlon, lon_ext=lon_ext)
  1147. VY, cn_lat = __name_latitude_ticks__(lat_min=lat_min, lat_max=lat_max, dlat=dlat)
  1148. return VX, VY, cn_lon, cn_lat
  1149. def __give_proj__(cname):
  1150. nb =nmp.shape(projection_def)[0]
  1151. vproj = [ 'NC', 'NC', 0., 0., 0., 0., 0., 0., 'NC' ]
  1152. jb = 0
  1153. while jb < nb :
  1154. if projection_def[jb][0] == cname:
  1155. break
  1156. else :
  1157. jb = jb + 1
  1158. if jb == nb :
  1159. print 'Zone "'+cname+'" does not exist!\n'
  1160. print 'so far choice is :'
  1161. for jb in range(nb): print projection_def[jb][0]
  1162. sys.exit(0)
  1163. vproj = projection_def[jb][:]
  1164. return vproj
  1165. def __font_unity__(fig_dpi=100., size='normal'):
  1166. rat = 100./float(fig_dpi)
  1167. if size == 'big': rat = 1.25*rat
  1168. params = { 'font.family':'Trebuchet MS',
  1169. 'font.size': int(13.*rat),
  1170. 'legend.fontsize': int(13.*rat),
  1171. 'xtick.labelsize': int(13.*rat),
  1172. 'ytick.labelsize': int(13.*rat),
  1173. 'axes.labelsize': int(13.*rat),
  1174. 'legend.facecolor': 'white',
  1175. 'figure.facecolor': 'white' }
  1176. mpl.rcParams.update(params)
  1177. title_fonts = { 'fontname':'Trebuchet MS' , 'fontweight':'normal', 'fontsize':int(15.*rat) }
  1178. label_fonts = { 'fontname':'Trebuchet MS' , 'fontweight':'normal', 'fontsize':int(14.*rat) }
  1179. colorbar_fonts = { 'fontname':'Trebuchet MS' , 'fontweight':'normal', 'fontsize':int(13.*rat) }
  1180. info_fonts = { 'fontname':'Ubuntu Mono' , 'fontweight':'normal', 'fontsize':int(13.*rat) }
  1181. return title_fonts, label_fonts, colorbar_fonts, info_fonts
  1182. def __force_min_and_max__(rm, rp, Xin):
  1183. idx_bad = nmp.where(nmp.logical_not(nmp.isfinite(Xin)))
  1184. Xin[idx_bad] = 0.
  1185. idx1 = nmp.where(Xin <= rm); Xin[idx1] = rm + abs(rp-rm)*1.E-4
  1186. idx2 = nmp.where(Xin >= rp); Xin[idx2] = rp - abs(rp-rm)*1.E-4
  1187. Xin[idx_bad] = nmp.nan
  1188. def __subsample_colorbar__(i_sbsmp, vcc, clb_hndl, cb_or='vertical'):
  1189. cb_labs = []
  1190. # First checking if vcc countains integers or not...
  1191. lcint = False
  1192. vc = vcc.astype(nmp.int64) ; # integer version of vcc
  1193. if nmp.max(nmp.abs(vcc))>5 and nmp.sum(vcc-vc) == 0. : lcint=True
  1194. cpt = 0
  1195. nn = int(round(abs(vcc[-1]-vcc[0])/abs(vcc[0]-vcc[1]),0))
  1196. if nn % 2 != 0: cpt = 1
  1197. for rr in vcc:
  1198. if cpt % i_sbsmp == 0:
  1199. if lcint:
  1200. cr = str(int(rr))
  1201. else:
  1202. cr = str(round(float(rr),6))
  1203. cb_labs.append(cr)
  1204. else:
  1205. cb_labs.append(' ')
  1206. cpt = cpt + 1
  1207. if cb_or == 'horizontal':
  1208. clb_hndl.ax.set_xticklabels(cb_labs)
  1209. else:
  1210. clb_hndl.ax.set_yticklabels(cb_labs)
  1211. del cb_labs, vc
  1212. def __nice_colorbar__(fig_hndl, plt_hndl, vcc,
  1213. cax_other=None, i_sbsmp=1, lkc=False, cb_or='vertical', cunit=None, cfont=None, fontsize=0):
  1214. if cb_or not in {'horizontal','vertical'}:
  1215. print "ERROR: only 'vertical' or 'horizontal' can be specified for the colorbar orientation!"
  1216. cb_or = 'vertical'
  1217. if cb_or == 'horizontal':
  1218. if cax_other is not None:
  1219. clb = plt_hndl.colorbar(fig_hndl, cax=cax_other, ticks=vcc, drawedges=lkc, orientation='horizontal',
  1220. pad=0.07, shrink=1., aspect=40, extend='both')
  1221. else:
  1222. clb = plt_hndl.colorbar(fig_hndl, ticks=vcc, drawedges=lkc, orientation='horizontal',
  1223. pad=0.07, shrink=1., aspect=40, extend='both')
  1224. else:
  1225. if cax_other is not None:
  1226. clb = plt_hndl.colorbar(fig_hndl, cax=cax_other, ticks=vcc, drawedges=lkc,
  1227. pad=0.03, extend='both')
  1228. else:
  1229. clb = plt_hndl.colorbar(fig_hndl, ticks=vcc, drawedges=lkc,
  1230. pad=0.03, extend='both')
  1231. if i_sbsmp > 1: __subsample_colorbar__(i_sbsmp, vcc, clb, cb_or=cb_or)
  1232. if not cunit is None:
  1233. if cfont is None:
  1234. clb.set_label(cunit)
  1235. else:
  1236. clb.set_label(cunit, **cfont)
  1237. if fontsize > 0:
  1238. if cb_or == 'horizontal':
  1239. for t in clb.ax.get_xticklabels(): t.set_fontsize(fontsize) # Font size for colorbar ticks!
  1240. else:
  1241. for t in clb.ax.get_yticklabels(): t.set_fontsize(fontsize) # Font size for colorbar ticks!
  1242. def _add_xy_offset__(plt_hndl, ixo, iyo):
  1243. if ( ixo != 0. ):
  1244. locs, labels = plt_hndl.xticks() ; jl=0
  1245. vlabs = []
  1246. for ll in locs:
  1247. clab = str(int(locs[jl])+int(ixo))
  1248. vlabs.append(clab); jl=jl+1
  1249. plt_hndl.xticks(locs,vlabs)
  1250. if ( y_offset != 0. ):
  1251. locs, labels = plt_hndl.yticks() ; jl=0; vlabs = []
  1252. for ll in locs:
  1253. clab = str(int(locs[jl])+int(iyo))
  1254. vlabs.append(clab); jl=jl+1
  1255. plt_hndl.yticks(locs,vlabs)
  1256. del vlabs
  1257. def __subsample_axis__(plt_hndl, cax, i_sbsmp, icpt=1):
  1258. ax_lab = []
  1259. if cax == 'x':
  1260. locs, labels = plt_hndl.xticks()
  1261. elif cax == 'y':
  1262. locs, labels = plt_hndl.yticks()
  1263. else:
  1264. print ' Error: __subsample_axis__.barakuda_plot => only "x" or "y" please'; sys.exit(0)
  1265. cpt = icpt # with ipct = 1: tick priting will start at y1+dt on x axis rather than y1
  1266. for rr in locs:
  1267. if cpt % i_sbsmp == 0:
  1268. if rr%1.0 == 0.:
  1269. cr = str(int(rr)) # it's something like 22.0, we want 22 !!!
  1270. else:
  1271. cr = str(rr)
  1272. ax_lab.append(cr)
  1273. else:
  1274. ax_lab.append(' ')
  1275. cpt = cpt + 1
  1276. if cax == 'x': plt_hndl.xticks(locs,ax_lab)
  1277. if cax == 'y': plt_hndl.yticks(locs,ax_lab)
  1278. del ax_lab
  1279. def __nice_x_axis__(ax_hndl, plt_hndl, x_0, x_H, dx, i_sbsmp=1, cunit=None, cfont=None, dx_minor=0):
  1280. x_l = x_0
  1281. if x_0%dx != 0.: x_l = float(int(x_0/dx))*dx
  1282. if x_H%dx != 0.: x_H = float(int(x_H/dx)+1)*dx
  1283. plt_hndl.xticks( nmp.arange(x_l, x_H+dx, dx) )
  1284. locs, labels = plt_hndl.xticks()
  1285. ax_hndl.get_xaxis().get_major_formatter().set_useOffset(False) ; # Prevents from using scientific notations in axess ticks numbering...
  1286. if i_sbsmp > 1: __subsample_axis__( plt, 'x', i_sbsmp)
  1287. if not cunit is None:
  1288. if cfont is None:
  1289. plt_hndl.xlabel(cunit)
  1290. else:
  1291. plt_hndl.xlabel(cunit, **cfont)
  1292. # Add minor x-ticks and corresponding grid:
  1293. if dx_minor > 0:
  1294. locs, labels = plt_hndl.xticks()
  1295. ax_hndl.set_xticks( nmp.arange(locs[0], locs[len(locs)-1] , dx_minor) , minor=True)
  1296. ax_hndl.grid(which='both')
  1297. ax_hndl.grid(which='minor', color='k', linestyle='-', linewidth=0.1)
  1298. ax_hndl.grid(which='major', color='k', linestyle='-', linewidth=0.2)
  1299. ax_hndl.set_xlim(x_l,x_H+dx/1000.)
  1300. def __nice_y_axis__(ax_hndl, plt_hndl, y_0, y_H, dy, i_sbsmp=1, cunit=None, cfont=None, dy_minor=0):
  1301. y_l = y_0
  1302. if y_0%dy != 0.: y_l = float(int(y_0/dy))*dy
  1303. plt_hndl.yticks( nmp.arange(y_l, y_H+dy, dy) )
  1304. locs, labels = plt_hndl.yticks()
  1305. ax_hndl.get_yaxis().get_major_formatter().set_useOffset(False) ; # Prevents from using scientific notations in axess ticks numbering...
  1306. if i_sbsmp > 1: __subsample_axis__( plt, 'y', i_sbsmp)
  1307. if not cunit is None:
  1308. if cfont is None:
  1309. plt_hndl.ylabel(cunit)
  1310. else:
  1311. plt_hndl.ylabel(cunit, **cfont)
  1312. # Add minor y-ticks and corresponding grid:
  1313. if dy_minor > 0:
  1314. locs, labels = plt_hndl.yticks()
  1315. ax_hndl.set_yticks( nmp.arange(locs[0], locs[len(locs)-1] , dy_minor) , minor=True)
  1316. ax_hndl.grid(which='both')
  1317. ax_hndl.grid(which='minor', color='k', linestyle='-', linewidth=0.1)
  1318. ax_hndl.grid(which='major', color='k', linestyle='-', linewidth=0.2)
  1319. ax_hndl.set_ylim(y_0,y_H+dy/1000.)
  1320. def __nice_depth_axis__(ax_hndl, plt_hndl, z0, zK, l_log=False, l_z_inc=True, cunit=None, cfont=None):
  1321. ax_hndl.get_yaxis().get_major_formatter().set_useOffset(False)
  1322. if l_log:
  1323. y_log_ofs = 10.
  1324. vyview_list = [ 3. , 10. , 25., 50. , 100. , 250. , 500. , 1000. , 2500., 5000. ]
  1325. nd = len(vyview_list)
  1326. vyview = nmp.zeros(nd)
  1327. for jn in range(nd): vyview[jn] = vyview_list[jn]
  1328. vyview_log = nmp.log10(vyview + y_log_ofs)
  1329. ylab = []
  1330. for rr in vyview_list: ylab.append(str(int(rr)))
  1331. z0 = nmp.log10(z0+y_log_ofs)
  1332. zK = nmp.log10(zK+y_log_ofs)
  1333. ax_hndl.set_yticks(vyview_log)
  1334. ax_hndl.get_yaxis().set_major_formatter(mpl.ticker.ScalarFormatter())
  1335. ax_hndl.set_yticklabels(ylab)
  1336. if l_z_inc:
  1337. ax_hndl.set_ylim(z0,zK)
  1338. else:
  1339. ax_hndl.set_ylim(zK+(zK-z0)/50. , z0)
  1340. ax_hndl.grid(color='k', linestyle='-', linewidth=0.5)
  1341. if not cunit is None:
  1342. if cfont is None:
  1343. plt_hndl.ylabel(cunit)
  1344. else:
  1345. plt_hndl.ylabel(cunit, **cfont)
  1346. def __nice_latitude_axis__(ax_hndl, plt_hndl, lmin, lmax, dl, axt='x'):
  1347. if axt == 'x':
  1348. ax_hndl.get_xaxis().get_major_formatter().set_useOffset(False)
  1349. elif axt == 'y':
  1350. ax_hndl.get_yaxis().get_major_formatter().set_useOffset(False)
  1351. else:
  1352. print 'ERROR barakuda_plot.__nice_latitude_axis__: only accept "x" or "y" for axt!'
  1353. sys.exit(0)
  1354. [vvl, ctck] = __name_latitude_ticks__(lat_min=lmin, lat_max=lmax, dlat=dl)
  1355. if axt == 'x':
  1356. plt_hndl.xticks(vvl,ctck)
  1357. ax_hndl.set_xlim(lmin,lmax)
  1358. else:
  1359. plt_hndl.yticks(vvl,ctck)
  1360. ax_hndl.set_ylim(lmin,lmax)
  1361. def __nice_longitude_axis__(ax_hndl, plt_hndl, lmin, lmax, dl, axt='x'):
  1362. if axt == 'x':
  1363. ax_hndl.get_xaxis().get_major_formatter().set_useOffset(False)
  1364. elif axt == 'y':
  1365. ax_hndl.get_yaxis().get_major_formatter().set_useOffset(False)
  1366. else:
  1367. print 'ERROR barakuda_plot.__nice_longitude_axis__: only accept "x" or "y" for axt!'
  1368. sys.exit(0)
  1369. [vvl, ctck] = __name_longitude_ticks__(lon_min=lmin, lon_max=lmax, dlon=dl)
  1370. if axt == 'x':
  1371. plt_hndl.xticks(vvl,ctck)
  1372. ax_hndl.set_xlim(lmin,lmax)
  1373. else:
  1374. plt_hndl.yticks(vvl,ctck)
  1375. ax_hndl.set_ylim(lmin,lmax)
  1376. def __prepare_z_log_axis__(l_log, vz):
  1377. import math
  1378. nk = len(vz)
  1379. zvz = nmp.zeros(nk)
  1380. if l_log:
  1381. for jk in range(nk):
  1382. zvz[jk] = math.log10(vz[jk])
  1383. else:
  1384. zvz= vz
  1385. return zvz
  1386. def __nb_col_row_legend__(nn):
  1387. if nn <= 3:
  1388. nbc = 1 ; nbr = nn
  1389. elif nn == 4:
  1390. nbc = 2 ; nbr = 2
  1391. elif nn > 4 and nn <= 6:
  1392. nbc = 2 ; nbrfull = 2; nfull = nbc*nbrfull; nbr = nbrfull + nn/nfull
  1393. elif nn > 6 and nn <= 9:
  1394. nbc = 3 ; nbrfull = 2; nfull = nbc*nbrfull; nbr = nbrfull + nn/nfull
  1395. elif nn > 9 and nn <= 16:
  1396. nbc = 4 ; nbrfull = 3; nfull = nbc*nbrfull; nbr = nbrfull + nn/nfull
  1397. else:
  1398. nbc = 4 ; nbr = nn/nbc + 1
  1399. return nbc, nbr
  1400. def __time_axis_minor_ticks__(dt):
  1401. dt_mnr=0
  1402. if ((dt>=2) and (dt<10) and (dt%2 == 0)) or (dt==5) : dt_mnr=1
  1403. if (dt>=10) and (dt<50) and (dt%5 == 0) : dt_mnr=5
  1404. if (dt>=50) and (dt%50 == 0) : dt_mnr=10
  1405. return dt_mnr
  1406. def __suitable_axis_dx__(hmin, hmax, nb_val=20, lsym0=False):
  1407. if (hmin,hmax) == (0.,0.) or (hmin,hmax) == (0,0):
  1408. dh = 0.
  1409. else:
  1410. dh = abs(hmax - hmin)/float(nb_val)
  1411. lfound = False
  1412. iexp = 20
  1413. while not lfound :
  1414. if dh%(10.**(iexp-1)) != dh: lfound = True
  1415. iexp = iexp - 1
  1416. if iexp < 1:
  1417. dh = round(dh, -iexp)
  1418. else:
  1419. dh = round(dh,0)
  1420. dh = round(dh/(10.**iexp),0)*10.**iexp
  1421. dhi = dh*10.**(-iexp)
  1422. if dhi == 3.: dh = 2.5*10.**(iexp)
  1423. if dhi in [4.,6.,7.]: dh = 5.*10.**(iexp)
  1424. if dhi in [8.,9.]: dh = 10.*10.**(iexp) ; iexp=iexp+1
  1425. hmin = float(int(hmin*10.**(-iexp)))*10.**iexp
  1426. hmax = float(int((hmax+dh)*10.**(-iexp)))*10.**iexp
  1427. if lsym0:
  1428. # Force symetry about 0 !
  1429. hmax = max(abs(hmax),abs(hmin))
  1430. if hmax%dh != 0.: hmax = float(int(hmax/dh))*dh
  1431. hmin = -hmax
  1432. return hmin, hmax, dh
  1433. def __fancy_legend__(ax_hndl, plt_hndl, loc_leg='0', ylg=0, leg_out=False, ncol=1):
  1434. if loc_leg != '0':
  1435. if leg_out:
  1436. # Shrink Y axis's height by % on the bottom
  1437. box = ax_hndl.get_position()
  1438. ax_hndl.set_position([box.x0, box.y0 + box.height*ylg, box.width, box.height*(1.-ylg)])
  1439. plt_hndl.legend(bbox_to_anchor=(0.95, -0.075), ncol=ncol, shadow=True, fancybox=True)
  1440. else:
  1441. plt_hndl.legend(loc=loc_leg, ncol=ncol, shadow=True, fancybox=True)