Changeset 1438 in lmdz_wrf for trunk/tools/drawing_tools.py


Ignore:
Timestamp:
Feb 8, 2017, 7:54:43 PM (8 years ago)
Author:
lfita
Message:

adding: plot_WindRose: Function to plot a wind rose (from where the dinw blows)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/drawing_tools.py

    r1420 r1438  
    8383# plot_2lines_time: Function to plot two time-lines in different axes (x/x2 or y/y2)
    8484# plot_lines: Function to plot a collection of lines
     85# plot_WindRose: Function to plot a wind rose (from where the dinw blows)
    8586# plot_ZQradii: Function to plot following radial averages only at exact grid poins
    8687# transform: Function to transform the values and the axes
     
    80428043
    80438044    return
     8045
     8046def plot_WindRose(ang, speed, dime, lpvals, thetalabs, windu, titimg, kfig, figname, \
     8047  close, origfilen, outputfile=False, ev=None, eunit=None):
     8048    """ Function to plot a wind rose (from where the dinw blows)
     8049      ang= angle of the winds
     8050      speed= speed of the winds
     8051      Nang= number of angles to split the total circumference
     8052      Nspeed= number of speed sections to split the wind distribution
     8053      maxspeed= maximum wind speed to be plotted
     8054      dime= number of winds to plot
     8055      lpvals= values to configure the kind of Wind Rose to plot
     8056        lpvals[0]: kind of Wind Rose
     8057        lpvals[1]: specie of kind of Wind Rose
     8058        lpvals[>=2]: specific values for the specie Wind Rose
     8059        'anglespeedfreq';[Nang];[Nspeed];[maxspeed];[cbar];[maxfreq] grid of frequencies of each angle and speed
     8060          following a given discretization
     8061        'linepoint';[kind];[val1];[...;[valN]]: consecutive (time, height, level, ...) line-point angle and speed valules
     8062          'multicol';[extravarn];[line];[marker];[colbar]
     8063          'multicoltime';[extravarn];[line];[marker];[colbar];[timekind];[timefmt];[timelabel]
     8064          'singlecol';[line];[marker];[col]
     8065        'scatter';[kind];[val1];[...;[valN]]: a cross for each wind at different values (time, height, level, ...)
     8066          'multicol';[extravarn];[marker];[colbar]
     8067          'multicoltime';[extravarn];[line];[marker];[colbar];[timekind];[timefmt];[timelabel]
     8068          'singlecol';[marker];[col]
     8069      windu= units of the wind speed
     8070      thetalabs= kind of labels for the angles of the wind-rose
     8071        'cardianals': Following combinations of 'N', 'E', 'S', 'W' according to Nang
     8072      titimg= title of the image
     8073      kfig= kind of figure
     8074      figname= name of the figure
     8075      close= wether figure has to be closed or not
     8076      origfilen= Name of the file from which the data cames from
     8077      outputfile= wether file with wind and angle frequencies has to be created (only valid for 'anglespeedfreq')
     8078      ev= extra values (for certain Wind Roses: 'linepoint/scatter' 'multicol' & 'multicoltime')
     8079      eunits= units of the extravalues (for certain Wind Roses)
     8080    """
     8081    fname = 'plot_WindRose'
     8082
     8083    if lpvals[0] == 'anglespeedfreq':
     8084        # Computing statistics
     8085        Nang = gen.auto_val(lpvals[1], 8)
     8086        Nspeed = gen.auto_val(lpvals[2], 8)
     8087        maxspeed = gen.auto_val(lpvals[3], 40.)
     8088        freqcbar = gen.auto_val(lpvals[4], 'spectral_r')
     8089        maxfreq = lpvals[5]
     8090
     8091        dang = 2.*np.pi / (Nang)
     8092        dang2 = dang/2.
     8093
     8094        nspeed = 0.
     8095        xspeed = maxspeed
     8096        dspeed = maxspeed/(Nspeed)
     8097
     8098        # Adding one extra partition for the last range
     8099        #Nang = Nang + 1
     8100        Nspeed = Nspeed + 1
     8101
     8102        # Angle localized
     8103        angfound = np.zeros((dime), dtype=bool)
     8104        # Angles's distirbution
     8105        angdistrib = np.zeros((Nang), dtype=np.float)
     8106        # Wind speed distirbution following angle
     8107        ang_speeddistrib = {}
     8108        # Wind speed distirbution following angle & speed
     8109        speedang_speeddistrib = {}
     8110        for it in range(dime):
     8111            for iang in range(Nang):
     8112                # initial/ending of the angle section
     8113                iasec = iang*dang - dang/2.
     8114                easec = iasec + dang
     8115   
     8116                if ang[it] >= iasec and ang[it] < easec:
     8117                    Siang = str(iang)
     8118                    angfound[it] = True
     8119                    angdistrib[iang] = angdistrib[iang] + 1
     8120                    if ang_speeddistrib.has_key(iang):
     8121                        speeds = ang_speeddistrib[iang]
     8122                        ang_speeddistrib[iang] = speeds + [speed[iang]]
     8123                    else:
     8124                        ang_speeddistrib[iang] = [speed[it]]
     8125                    # initial/ending of the speed section
     8126                    for ispd in range(Nspeed):
     8127                        issec = ispd*dspeed - dspeed/2.
     8128                        essec = issec + dspeed
     8129                        if speed[it] >= issec and speed[it] < essec:
     8130                            Siaspd = Siang + '_' + str(ispd)
     8131                            if speedang_speeddistrib.has_key(Siaspd):
     8132                                speedangs = speedang_speeddistrib[Siaspd]
     8133                                speedang_speeddistrib[Siaspd]= speedangs + [speed[it]]
     8134                            else:
     8135                                speedang_speeddistrib[Siaspd]= [speed[it]]
     8136                            break
     8137            if not angfound[it]:
     8138                print warnmsg
     8139                print 'angle:',ang[it],': not located within:', dang*np.arange(Nang)-\
     8140                  dang/2.
     8141   
     8142    lkind = lpvals[1]
     8143
     8144    # Getting time values and ticks
     8145    if lkind == 'multicoltime':
     8146        if lpvals[0] == 'linepoint':
     8147            timekind = lpvals[7]
     8148            timefmt = lpvals[8]
     8149        elif lpvals[0] == 'scatter':
     8150            timekind = lpvals[6]
     8151            timefmt = lpvals[7]
     8152        timepos, timelabels = CFtimes_plot(ev, eunit, timekind, timefmt)
     8153   
     8154    if lpvals[0] == 'anglespeedfreq':
     8155        # Distribution of Frequencies
     8156        TOTwinds = 0
     8157        freqs = np.zeros((Nspeed,Nang), dtype=np.float)
     8158        for ian in range(Nang):
     8159            for isp in range(Nspeed):
     8160                Siaspd = str(ian) + '_' + str(isp)
     8161                if speedang_speeddistrib.has_key(Siaspd):
     8162                    Nwind = len(speedang_speeddistrib[Siaspd])
     8163                    freqs[isp,ian] = Nwind
     8164                    TOTwinds = TOTwinds + Nwind
     8165   
     8166        if np.sum(freqs) != TOTwinds:
     8167            print errormsg
     8168            print 'number of located frequencies:', freqs, 'and number of values:',  \
     8169              TOTwinds, 'differ!!'
     8170            quit(-1)
     8171
     8172        # Normalizing
     8173        freqs = freqs*1./TOTwinds
     8174        freqs = ma.masked_equal(freqs, 0.)
     8175   
     8176        # Filling with zeros up to the highest speed
     8177        for iang in range(Nang):
     8178            xfreq = freqs[:,iang].max()
     8179            if not np.all(freqs.mask[:,iang]):
     8180                indicesc = gen.multi_index_mat(freqs.mask[:,iang], False)
     8181                xind = np.max(indicesc)
     8182                freqs[0:xind+1,iang]= np.where(freqs.mask[0:xind+1,iang], 0.,        \
     8183                  freqs[0:xind+1,iang])
     8184
     8185        if type(maxfreq) == type('s'):
     8186            if maxfreq == 'auto': maxfreq = freqs.max()
     8187
     8188    # Plot
     8189    plt.rc('text', usetex=True)
     8190    ax = plt.subplot(111, projection='polar')
     8191
     8192    # Rosekind
     8193    # Scatter
     8194    if lpvals[0] == 'fill':
     8195        plt.fill_between(ang, speed, 0.)
     8196    elif lpvals[0] == 'anglespeedfreq':
     8197        angs = np.arange(Nang,dtype=np.float)*dang - dang/2.
     8198        spds = np.arange(Nspeed,dtype=np.float)*dspeed - dspeed/2.
     8199        spds[0] = 0.
     8200        x, y = gen.lonlat2D(angs,spds)
     8201        plt.pcolormesh(x, y, freqs, cmap=freqcbar, vmin=0., vmax=maxfreq)
     8202        cbar = plt.colorbar()
     8203        cbar.set_label('Frequencies (1)')
     8204        plt.grid()
     8205        if type(thetalabs) != type('auto'):
     8206            ax.set_thetagrids((angs+dang/2.)*180./np.pi, thetalabs)
     8207
     8208    elif lpvals[0] == 'linepoint':
     8209        if lkind == 'multicol':
     8210            ltyp = gen.auto_val(lpvals[3],'-')
     8211            lmrk = gen.auto_val(lpvals[4],'x')
     8212            colbar = gen.auto_val(lpvals[5],'spectral_r')
     8213            Nang = gen.auto_val(lpvals[6],8)
     8214            # Setting up colors for each label
     8215            #   From: http://stackoverflow.com/questions/15235630/matplotlib-pick-up-one-color-associated-to-one-value-in-a-colorbar
     8216            vcolmin = np.min(ev)
     8217            vcolmax = np.max(ev)
     8218            my_cmap = plt.cm.get_cmap(colbar)
     8219            norm = mpl.colors.Normalize(vcolmin, vcolmax)
     8220
     8221            for ie in range(dime-1):
     8222                labcol = my_cmap(norm(ev[ie]))
     8223                plt.plot([ang[ie], ang[ie+1]], [speed[ie], speed[ie+1]], ltyp, marker=lmrk, color=labcol)
     8224            # FROM: http://stackoverflow.com/questions/8342549/matplotlib-add-colorbar-to-a-sequence-of-line-plots
     8225            # For matplotlib v1.3 or greater the code becomes:
     8226            sm = plt.cm.ScalarMappable(cmap=colbar, norm=norm)
     8227            # fake up the array of the scalar mappable. Urgh...
     8228            sm._A = []
     8229            cbar = plt.colorbar(sm)
     8230            cbar.set_label(eunit)
     8231        elif lkind == 'multicoltime':
     8232            ltyp = gen.auto_val(lpvals[3],'-')
     8233            lmrk = gen.auto_val(lpvals[4],'x')
     8234            colbar = gen.auto_val(lpvals[5],'spectral_r')
     8235            Nang = gen.auto_val(lpvals[6],8)
     8236            timekind = lpvals[7]
     8237            timefmt = lpvals[8]
     8238            timelabel = lpvals[9].replace('!',' ')
     8239            # Setting up colors for each label
     8240            #   From: http://stackoverflow.com/questions/15235630/matplotlib-pick-up-one-color-associated-to-one-value-in-a-colorbar
     8241            vcolmin = np.min(ev)
     8242            vcolmax = np.max(ev)
     8243            my_cmap = plt.cm.get_cmap(colbar)
     8244            norm = mpl.colors.Normalize(vcolmin, vcolmax)
     8245
     8246            for ie in range(dime-1):
     8247                labcol = my_cmap(norm(ev[ie]))
     8248                lcolS = gen.coldec_hex(labcol[0:3])
     8249                plt.plot([ang[ie], ang[ie+1]], [speed[ie], speed[ie+1]], ltyp, marker=lmrk, color=lcolS)
     8250   
     8251            # FROM: http://stackoverflow.com/questions/8342549/matplotlib-add-colorbar-to-a-sequence-of-line-plots
     8252            # For matplotlib v1.3 or greater the code becomes:
     8253            sm = plt.cm.ScalarMappable(cmap=colbar, norm=norm)
     8254            # fake up the array of the scalar mappable. Urgh...
     8255            sm._A = []
     8256            cbar = plt.colorbar(sm, ticks=timepos)
     8257            cbar.set_label(timelabel)
     8258            cbar.ax.set_yticklabels(timelabels)
     8259
     8260            # An attempt using text...
     8261            #maxt = np.max(timepos)
     8262            #for it in range(len(timelabels)):
     8263            #    daxistT = 0.6
     8264            #    iaxistT = (1. - daxistT)/2.
     8265            #    itt = (timepos[it]-timepos[0])*daxistT/(maxt-timepos[0])
     8266            #    labcol = my_cmap(norm(timepos[it]))
     8267            #    plt.annotate(timelabels[it], xy=(0.87,iaxistT+itt), color=labcol,        \
     8268            #      xycoords='figure fraction', multialignment='center')
     8269            #plt.annotate(timelabel, xy=(0.97,0.5), color='k', rotation=90,               \
     8270            #  rotation_mode="anchor", xycoords='figure fraction', horizontalalignment='center')
     8271        elif lkind == 'singlecol':
     8272            ltyp = gen.auto_val(lpvals[2],'-')
     8273            lmrk = gen.auto_val(lpvals[3],'x')
     8274            lcol = gen.auto_val(lpvals[4],'b')
     8275            Nang = gen.auto_val(lpvals[5],8)
     8276            plt.plot(ang, speed, ltyp, marker=lmrk, color=lcol)
     8277   
     8278    elif lpvals[0] == 'scatter':
     8279        if lkind == 'multicol':
     8280            lmrk = gen.auto_val(lpvals[3],'x')
     8281            colbar = gen.auto_val(lpvals[4],'spectral_r')
     8282            Nang = gen.auto_val(lpvals[5],8)
     8283            plt.scatter(ang, speed, c=ev, cmap=colbar, marker=lmrk)
     8284            cbar = plt.colorbar()
     8285            cbar.set_label(eunit)
     8286        elif lkind == 'multicoltime':
     8287            lmrk = gen.auto_val(lpvals[3],'x')
     8288            colbar = gen.auto_val(lpvals[4],'spectral_r')
     8289            Nang = gen.auto_val(lpvals[5],8)
     8290            timekind = lpvals[6]
     8291            timefmt = lpvals[7]
     8292            timelabel = lpvals[8].replace('!',' ')
     8293            plt.scatter(ang, speed, c=ev, cmap=colbar, marker=lmrk)
     8294            cbar = plt.colorbar(ticks=timepos)
     8295            cbar.set_label(timelabel)
     8296            cbar.ax.set_yticklabels(timelabels)
     8297        elif lkind == 'singlecol':
     8298            lmrk = gen.auto_val(lpvals[2],'x')
     8299            lcol = gen.auto_val(lpvals[3],'b')
     8300            Nang = gen.auto_val(lpvals[4],8)
     8301            plt.plot(ang, speed, ',', marker=lmrk, color=lcol)
     8302   
     8303    if thetalabs == 'cardinals':
     8304        if Nang == 4:
     8305            thetalabs = ['N', 'E', 'S', 'W']
     8306        elif Nang == 8:
     8307            thetalabs = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']
     8308        elif Nang == 16:
     8309            thetalabs= ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW',\
     8310              'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW']
     8311        else:
     8312            print errormsg
     8313            print '  ' + fname + ': number of angles:', Nang, "not ready for '" +    \
     8314              thetalabs + "' !!"
     8315            print '    available ones: 4, 8, 16'
     8316            quit(-1)
     8317
     8318        dang = 2.*np.pi / (Nang)       
     8319        angs = np.arange(Nang,dtype=np.float)*dang - dang/2.
     8320        ax.set_thetagrids((angs+dang/2.)*180./np.pi, thetalabs)
     8321   
     8322    ax.set_theta_zero_location('N')
     8323    ax.set_theta_direction(-1)
     8324    plt.annotate('wind (' + units_lunits(windu) + ')', xy=(0.75,0.06), color='k',    \
     8325      xycoords='figure fraction', horizontalalignment='center')
     8326
     8327    plt.title(gen.latex_text(titimg))
     8328
     8329    output_kind(kfig, figname, close)
     8330
     8331    # Creation of the output file
     8332    if lpvals[0] == 'anglespeedfreq' and outputfile:
     8333        print '  ' + fname + ': Writting netCDF of frequencies of wind angle and ' + \
     8334          'speeds...'
     8335        newnc = NetCDFFile(figname + '.nc', 'w')
     8336
     8337        # Dimension creation
     8338        newdim = newnc.createDimension('angle', Nang)
     8339        newdim = newnc.createDimension('speed', Nspeed)
     8340        newdim = newnc.createDimension('bounds', 2)
     8341
     8342        # Dimension variable
     8343        newvar = newnc.createVariable('angle', 'f8', ('angle'))
     8344        ncvar.basicvardef(newvar, 'angle', 'angle from which wind blows', 'degree')
     8345        newvar[:] = angs
     8346        newvar.setncattr('cell_method','angle_bounds')
     8347
     8348        newvar = newnc.createVariable('angle_bounds', 'f8', ('angle','bounds'))
     8349        ncvar.basicvardef(newvar,'angle_bounds', 'bounds of the angle sections',     \
     8350         'degree')
     8351        for iang in range(Nang):
     8352            # initial/ending of the angle section
     8353            iasec = iang*dang - dang/2.
     8354            if iasec < 0.: iasec = 2.*np.pi + iasec
     8355            easec = iasec + dang
     8356            newvar[iang,0] = iasec*180./np.pi
     8357            newvar[iang,1] = easec*180./np.pi
     8358        newnc.sync()
     8359
     8360        newvar = newnc.createVariable('speed', 'f8', ('speed'))
     8361        ncvar.basicvardef(newvar, 'speed', 'speed of wind', windu)
     8362        newvar[:] = spds
     8363        newvar.setncattr('cell_method','speed_bounds')
     8364
     8365        newvar = newnc.createVariable('speed_bounds', 'f8', ('speed', 'bounds'))
     8366        ncvar.basicvardef(newvar,'speed_bounds','bounds of the speed sections',windu)
     8367        for ispd in range(Nspeed):
     8368            # initial/ending of the speed section
     8369            issec = ispd*dspeed - dspeed/2.
     8370            if issec < 0.: issec = 0.
     8371            essec = issec + dspeed
     8372            newvar[ispd,0] = issec
     8373            newvar[ispd,1] = essec
     8374        newnc.sync()
     8375
     8376        # Variables
     8377        newvar = newnc.createVariable('frequency', 'f4', ('speed', 'angle'),         \
     8378          fill_value=gen.fillValueF)
     8379        ncvar.basicvardef(newvar, 'frequency', 'frequency of angle and speed', '1')
     8380        newvar[:] = freqs[:]
     8381        newnc.sync()
     8382
     8383        # Global values
     8384        newnc.setncattr('author', 'L. Fita')
     8385        newattr = ncvar.set_attributek(newnc, 'institution', unicode('Laboratoire ' +\
     8386          'de M' + unichr(233) + 't' + unichr(233) + 'orologie Dynamique'), 'U')
     8387        newnc.setncattr('university', 'Pierre Marie Curie - Jussieu')
     8388        newnc.setncattr('center', 'Centre National de Recherches Scientifiques')
     8389        newnc.setncattr('city', 'Paris')
     8390        newnc.setncattr('country', 'France')
     8391        newnc.setncattr('script', 'nc_var_tools.py')
     8392        newnc.setncattr('function', fname)
     8393        newnc.setncattr('version', '1.0')
     8394        newnc.setncattr('original_file', origfilen)
     8395
     8396        newnc.sync()
     8397        newnc.close()
     8398        print "Successful creation of file with frequencies '" + figname + ".nc' !!"   
     8399
     8400    return
Note: See TracChangeset for help on using the changeset viewer.