def get_EOFs(var1, num=3, scaling=2):
    lat = var1.getAxis(1)
    lon = var1.getAxis(2)
    var = MV.array(var1 - np.mean(var1, axis=0))
    var.setAxis(1, lat)
    var.setAxis(2, lon)
    solver = Eof(var, weights='area')
    eofs = solver.eofs(neofs=num, eofscaling=scaling)
    pc = solver.pcs(npcs=num, pcscaling=scaling)
    vari = solver.varianceFraction(num)
    eigv = solver.eigenvalues(num)
    return eofs, pc, vari, eigv
Пример #2
0
end_year = 2000
start_time = cdtime.comptime(start_year)
end_time = cdtime.comptime(end_year)

# Load variable ---
d = f('sst',time=(start_time,end_time),longitude=(0,360),latitude=(-90,90)) # Provide proper variable name

# Reomove annual cycle ---
d_anom = cdutil.ANNUALCYCLE.departures(d)

# EOF (take only first variance mode...) ---
solver = Eof(d_anom, weights='area')
eof = solver.eofsAsCovariance(neofs=1)
pc = solver.pcs(npcs=1, pcscaling=1) # pcscaling=1: scaled to unit variance 
                                     # (divided by the square-root of their eigenvalue)
frac = solver.varianceFraction()

# Sign control if needed ---
eof = eof * -1
pc = pc * -1

#===========================================================================================================
# Plot
#-----------------------------------------------------------------------------------------------------------
# Create canvas ---
canvas = vcs.init(geometry=(900,800))

canvas.open()
template = canvas.createtemplate()

# Turn off no-needed information -- prevent overlap
Пример #3
0
def eof_analysis_get_variance_mode(
    mode,
    timeseries,
    eofn,
    eofn_max=None,
    debug=False,
    EofScaling=False,
    save_multiple_eofs=False,
):
    """
    NOTE: Proceed EOF analysis
    Input
    - mode (string): mode of variability is needed for arbitrary sign
                     control, which is characteristics of EOF analysis
    - timeseries (cdms2 variable): time varying 2d array, so 3d array
                                  (time, lat, lon)
    - eofn (integer): Target eofs to be return
    - eofn_max (integer): number of eofs to diagnose (1~N)
    Output
      1) When 'save_multiple_eofs = False'
        - eof_Nth: eof pattern (map) for given eofs as eofn
        - pc_Nth: corresponding principle component time series
        - frac_Nth: cdms2 array but for 1 single number which is float.
                 Preserve cdms2 array type for netCDF recording.
                 fraction of explained variance
        - reverse_sign_Nth: bool
        - solver
      2) When 'save_multiple_eofs = True'
        - eof_list: list of eof patterns (map) for given eofs as eofn
        - pc_list: list of corresponding principle component time series
        - frac_list: list of cdms2 array but for 1 single number which is float.
                 Preserve cdms2 array type for netCDF recording.
                 fraction of explained variance
        - reverse_sign_list: list of bool
        - solver
    """
    if debug:
        print("Lib-EOF: timeseries.shape:", timeseries.shape)
    debug_print("Lib-EOF: solver", debug)

    if eofn_max is None:
        eofn_max = eofn
        save_multiple_eofs = False

    # EOF (take only first variance mode...) ---
    solver = Eof(timeseries, weights="area")
    debug_print("Lib-EOF: eof", debug)

    # pcscaling=1 by default, return normalized EOFs
    eof = solver.eofsAsCovariance(neofs=eofn_max, pcscaling=1)
    debug_print("Lib-EOF: pc", debug)

    if EofScaling:
        # pcscaling=1: scaled to unit variance
        # (i.e., divided by the square-root of their eigenvalue)
        pc = solver.pcs(npcs=eofn_max, pcscaling=1)
    else:
        pc = solver.pcs(npcs=eofn_max)  # pcscaling=0 by default

    # fraction of explained variance
    frac = solver.varianceFraction()
    debug_print("Lib-EOF: frac", debug)

    # For each EOFs...
    eof_list = []
    pc_list = []
    frac_list = []
    reverse_sign_list = []

    for n in range(0, eofn_max):
        eof_Nth = eof[n]
        pc_Nth = pc[:, n]
        frac_Nth = cdms2.createVariable(frac[n])

        # Arbitrary sign control, attempt to make all plots have the same sign
        reverse_sign = arbitrary_checking(mode, eof_Nth)

        if reverse_sign:
            eof_Nth = MV2.multiply(eof_Nth, -1.0)
            pc_Nth = MV2.multiply(pc_Nth, -1.0)

        # time axis
        pc_Nth.setAxis(0, timeseries.getTime())

        # Supplement NetCDF attributes
        frac_Nth.units = "ratio"
        pc_Nth.comment = "".join(
            [
                "Non-scaled time series for principal component of ",
                str(eofn),
                "th variance mode",
            ]
        )

        # append to lists for returning
        eof_list.append(eof_Nth)
        pc_list.append(pc_Nth)
        frac_list.append(frac_Nth)
        reverse_sign_list.append(reverse_sign)

    # return results
    if save_multiple_eofs:
        return eof_list, pc_list, frac_list, reverse_sign_list, solver
    else:
        # Remove unnecessary dimensions (make sure only taking requested eofs)
        eof_Nth = eof_list[eofn - 1]
        pc_Nth = pc_list[eofn - 1]
        frac_Nth = frac_list[eofn - 1]
        reverse_sign_Nth = reverse_sign_list[eofn - 1]
        return eof_Nth, pc_Nth, frac_Nth, reverse_sign_Nth, solver
Пример #4
0
def NatureRevisions_Figure5(D):
    aerosol_start = cdtime.comptime(1950,1,1)
    aerosol_stop = cdtime.comptime(1975,12,31)
    aerosolsolver=Eof(D.ALL.mma(time=(aerosol_start,aerosol_stop)),weights='area')
    fac=da.get_orientation(aerosolsolver)
    plt.subplot(221)
    m=b.landplot(fac*aerosolsolver.eofs()[0],vmin=-.1,vmax=.1)
    m.fillcontinents(color="gray",zorder=0)
    
    varex= str(int(100*np.round(aerosolsolver.varianceFraction()[0],2)))
    plt.title("(a)")#: 1950-1975 historical fingerprint ("+varex+"% of variance explained)",fontsize=8)
    m.drawcoastlines(color='gray')
    plt.ylim(-60,90)
    plt.colorbar(orientation='horizontal',label='EOF loading')
    plt.subplot(222)
    Plotting.time_plot(fac*aerosolsolver.pcs()[:,0],color=cm.Greys(.8),lw=1)
    plt.title("(b)")#: Associated PC",fontsize=8)
    plt.ylabel("Temporal amplitude")

    plt.subplot(223)

    target_obs,cru_proj,dai_proj=pdsi_time_series(D,aerosol_start,aerosol_stop,aerosols=True)
    plt.legend(fontsize=6)
    plt.title("(c)")#: Projections on fingerprint",fontsize=8)
    plt.subplot(224)

   # target_obs = D.ALL.get_tree_ring_projection(solver = aerosolsolver)(time=(aerosol_start,aerosol_stop))
    L=len(target_obs)
    modslopes,noiseterm = D.ALL.sn_at_time(aerosol_start,L,overlapping=True,solver=aerosolsolver)
    ns=np.std(noiseterm)
    signal = float(cmip5.get_linear_trends(target_obs))
    plt.hist(modslopes/ns,20,normed=True,color=get_dataset_color("h85"),alpha=.5)
    lab = str(aerosol_start.year)+"-"+str(aerosol_stop.year)
    da.fit_normals_to_data(modslopes/ns,color=get_dataset_color("h85"),lw=1,label="H85")

    plt.hist(noiseterm/ns,20,normed=True,color=get_dataset_color("tree_noise"),alpha=.5)
    da.fit_normals_to_data(noiseterm/ns,color=get_dataset_color("tree_noise"),lw=1,label="Pre-1850 tree rings")
    percentiles=[]
    plt.axvline(signal/ns,color=get_dataset_color("tree"),lw=1,label=lab+" GDA trend")
    
    noise_percentile=stats.percentileofscore(noiseterm.tolist(),signal)
    h85_percentile=stats.percentileofscore(modslopes.tolist(),signal)
    percentiles += [noise_percentile,h85_percentile]


    daitrend = cmip5.get_linear_trends(dai_proj)
    print "DAI slope is "+str(daitrend)
    daisignal = daitrend/ns
    
    plt.axvline(daisignal,color=get_dataset_color("dai"),lw=1,label="Dai")
    print "DAI signal/noise is "+str(daisignal)

    
    
    crutrend = cmip5.get_linear_trends(cru_proj)
    print "CRU slope is "+str(crutrend)
    crusignal = crutrend/ns
    
    plt.axvline(crusignal,color=get_dataset_color("cru"),lw=1,label="CRU")
    print "CRU signal/noise is "+str(crusignal)

   
            
       
    plt.legend(loc=0,fontsize=8)
    plt.xlabel("S/N")
    plt.ylabel("Normalized Frequency")
    plt.title("(d)")#: Detection and Attribution Results",fontsize=8)
    fig=plt.gcf()
    for ax in fig.axes:
        plt.setp(ax.xaxis.get_label(),fontsize=6)
        plt.setp(ax.yaxis.get_label(),fontsize=6)
        plt.setp(ax.get_xticklabels(),fontsize=6)
        plt.setp(ax.get_yticklabels(),fontsize=6)
    ax=fig.axes[0]
    ax.set_title("(a)",fontsize=6)
    ax=fig.axes[2]
    ax.set_title("(b)",fontsize=6)
    ax=fig.axes[3]
    ax.set_title("(c)",fontsize=6)
    ax=fig.axes[4]
    ax.set_title("(d)",fontsize=6)
    leg=ax.legend(fontsize=6,ncol=1,loc=2)
    leg.set_frame_on(False)
    cax=fig.axes[1]
    ticklabels=["-0.1","","-0.05","","0","","0.05","","0.1"]
    cax.set_xticklabels(ticklabels)
    plt.setp(cax.xaxis.get_ticklabels(),fontsize=6)
    plt.setp(cax.xaxis.get_label(),fontsize=6)