# Set time period --- start_year = 1980 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()
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