Ejemplo n.º 1
0
def compare_pre_post_1100_noise(X,L=31,latbounds=None):
    time1=('1100-1-1','1399-12-31')
    c1=cm.Purples(.8)
    time2=('1400-1-1','2005-12-31')
    if latbounds is not None:
        obs=X.obs(latitude=latbounds)
        mma = MV.average(X.model(latitude=latbounds),axis=0)
        mma = mask_data(mma,obs[0].mask)
        solver = Eof(mma)
        obs = mask_data(obs,solver.eofs()[0].mask)
        truncnoise=solver.projectField(obs)[:,0]*da.get_orientation(solver)
        noisy1=truncnoise(time=time1)
        noisy2=truncnoise(time=time2)
    else:
        noisy1=X.noise(time=time1)
        noisy2=X.noise(time=time2)
    c2=cm.viridis(.1)
    plt.subplot(121)
    Plotting.Plotting.time_plot(noisy1,c=c1)
    Plotting.Plotting.time_plot(noisy2,c=c2)
    plt.ylabel("Projection")
    plt.title("(a): Noise time series")
    plt.subplot(122)
   
    plt.hist(b.bootstrap_slopes(noisy1,L),color=c1,normed=True,alpha=.5)
    da.fit_normals_to_data(b.bootstrap_slopes(noisy1,L),c=c1,label="1100-1400")
    plt.hist(b.bootstrap_slopes(noisy2,L),color=c2,normed=True,alpha=.5)
    da.fit_normals_to_data(b.bootstrap_slopes(noisy2,L),c=c2,label="1400-2005")
    plt.legend()
    plt.title("(b): 31-year trend distributions")
    return np.std(b.bootstrap_slopes(noisy1,L)),np.std(b.bootstrap_slopes(noisy2,L))
Ejemplo n.º 2
0
    def histograms(self, start_time, stop_time, depth, overlapping=True):

        L = stop_time.year - start_time.year + 1
        modslopes, noiseterm = self.sn_at_time(start_time,
                                               L,
                                               depth,
                                               overlapping=overlapping)
        ns = np.std(noiseterm)

        plt.hist(modslopes / ns,
                 20,
                 normed=True,
                 color=cm.Oranges(.8),
                 alpha=.5)
        lab = str(start_time.year) + "-" + str(stop_time.year)
        da.fit_normals_to_data(modslopes / ns,
                               color=cm.Oranges(.9),
                               lw=3,
                               label=lab + " Model projections")

        plt.hist(noiseterm / ns,
                 20,
                 normed=True,
                 color=cm.Purples(.8),
                 alpha=.5)
        da.fit_normals_to_data(noiseterm / ns,
                               color=cm.Purples(.9),
                               lw=3,
                               label="Noise")
        plt.xlabel("S/N")
        plt.ylabel("Normalized Frequency")
Ejemplo n.º 3
0
    def DA_histogram(self,
                     experiment,
                     direction,
                     start=None,
                     stop=None,
                     datasets=None):
        fingerprint = getattr(self, experiment)

        if start is None:
            start = cmip5.start_time(self.gpcp.reshaped["east"])
            start = cdtime.comptime(start.year, start.month, 1)
        if stop is None:
            stop = cmip5.stop_time(self.gpcp.reshaped["east"])
            stop = cdtime.comptime(stop.year, stop.month, 30)

        #get the h85 projections over the same time period
        H85m = self.model_projections(experiment,
                                      direction)(time=(start, stop))
        H85 = cmip5.cdms_clone(np.ma.mask_rows(H85m), H85m)
        H85_trends = cmip5.get_linear_trends(H85)
        #get the piControl projection time series
        noise = self.noise_projections(experiment, direction)
        L = stop.year - start.year + 1
        noise_trends = da.get_slopes(noise, L)

        #plot
        plt.hist(H85_trends.compressed(),
                 25,
                 color=da_colors("h85"),
                 alpha=.5,
                 normed=True)
        plt.hist(noise_trends,
                 25,
                 color=da_colors("piC"),
                 alpha=.5,
                 normed=True)
        da.fit_normals_to_data(H85_trends,
                               color=da_colors("h85"),
                               lw=3,
                               label="H85")
        da.fit_normals_to_data(noise_trends,
                               color=da_colors("piC"),
                               lw=3,
                               label="piControl")
        # plt.axvline(obs_trend,label=obs.dataset,color=da_colors(obs.dataset))

        #Project the observations
        if datasets is None:
            datasets = ["gpcp", "cmap", "precl"]
        if type(datasets) != type([]):
            datasets = [datasets]
        for dataset in datasets:

            obs_proj = self.obs_projections(experiment, dataset,
                                            direction)(time=(start, stop))
            obs_trend = cmip5.get_linear_trends(obs_proj)
            plt.axvline(obs_trend, label=dataset, color=da_colors(dataset))
            print dataset + "S/N is: " + str(obs_trend / np.std(noise_trends))
Ejemplo n.º 4
0
def noisefigure(data,L=50,starttime="1400-8-1",showhist=True):
    for thing in sorted(["MXDA","OWDA","NADA","MADA","ANZDA"])+["ALL"]:
        
        X=getattr(data,thing)
        noiseterm = b.bootstrap_slopes(X.noise(time=(starttime,"2018-12-31")),L)
        if showhist:
            plt.hist(noiseterm,color=colorregions(X.name),normed=True,alpha=.4,histtype="bar",edgecolor="w")
        da.fit_normals_to_data(noiseterm,color=colorregions(X.name),label=X.name,lw=3)
        plt.xlabel(str(L)+"-year slope (PDSI/decade)")
        plt.ylabel("Normalized frequency")
Ejemplo n.º 5
0
def DA_histogram(fingerprint,
                 obslist,
                 h85,
                 piC,
                 direction,
                 start=None,
                 stop=None):
    if type(obslist) == type([]):
        obs = obslist[0]
    else:
        obs = obslist
    if start is None:
        start = cmip5.start_time(obs.reshaped["east"])
        start = cdtime.comptime(start.year, start.month, 1)
    if stop is None:
        stop = cmip5.stop_time(obs.reshaped["east"])
        stop = cdtime.comptime(stop.year, stop.month, 30)
    #project the observations onto the fingerprint
    obs_proj = obs_projections(fingerprint, obs, direction)(time=(start, stop))
    obs_trend = cmip5.get_linear_trends(obs_proj)
    #get the h85 projections over the same time period
    H85m = model_projections(fingerprint, h85, direction)(time=(start, stop))
    H85 = cmip5.cdms_clone(np.ma.mask_rows(H85m), H85m)
    H85_trends = cmip5.get_linear_trends(H85)
    #get the piControl projection time series
    noise = noise_projections(fingerprint, piC, direction)
    L = len(obs_proj)
    noise_trends = da.get_slopes(noise, L)

    #plot
    plt.hist(H85_trends.compressed(),
             25,
             color=da_colors("h85"),
             alpha=.5,
             normed=True)
    plt.hist(noise_trends, 25, color=da_colors("piC"), alpha=.5, normed=True)
    da.fit_normals_to_data(H85_trends,
                           color=da_colors("h85"),
                           lw=3,
                           label="H85")
    da.fit_normals_to_data(noise_trends,
                           color=da_colors("piC"),
                           lw=3,
                           label="piControl")
    plt.axvline(obs_trend, label=obs.dataset, color=da_colors(obs.dataset))
    if type(obslist) == type([]):
        for obs in obslist[1:]:

            obs_proj = obs_projections(fingerprint, obs,
                                       direction)(time=(start, stop))
            obs_trend = cmip5.get_linear_trends(obs_proj)
            plt.axvline(obs_trend,
                        label=obs.dataset,
                        color=da_colors(obs.dataset))
    return H85, noise, obs_proj
Ejemplo n.º 6
0
    def obs_SN(self, start_time, stop_time, depth, overlapping=True):
        self.project_soilmoisture("MERRA2")
        self.project_soilmoisture("GLEAM")
        L = stop_time.year - start_time.year + 1
        modslopes, noiseterm = self.sn_at_time(start_time,
                                               L,
                                               depth,
                                               overlapping=overlapping)
        ns = np.std(noiseterm)

        plt.hist(modslopes / ns,
                 20,
                 normed=True,
                 color=cm.Oranges(.8),
                 alpha=.5)
        lab = str(start_time.year) + "-" + str(stop_time.year)
        da.fit_normals_to_data(modslopes / ns,
                               color=cm.Oranges(.9),
                               lw=3,
                               label=lab +
                               " trends in H85 projections onto fingerprint")

        plt.hist(noiseterm / ns,
                 20,
                 normed=True,
                 color=cm.Purples(.8),
                 alpha=.5)
        da.fit_normals_to_data(
            noiseterm / ns,
            color=cm.Purples(.9),
            lw=3,
            label=str(L) +
            "-year trends in piControl projection onto fingerprint")
        plt.xlabel("S/N")
        plt.ylabel("Normalized Frequency")

        merra = self.OBS_PROJECTIONS["MERRA2"][depth](time=(start_time,
                                                            stop_time))
        gleam = self.OBS_PROJECTIONS["GLEAM"][depth](time=(start_time,
                                                           stop_time))
        merrasig = cmip5.get_linear_trends(merra) / ns
        plt.axvline(merrasig, label="MERRA2", c="b", lw=3)
        gleamsig = cmip5.get_linear_trends(gleam) / ns
        plt.axvline(gleamsig, label="GLEAM", c="r", lw=3)
        plt.legend()
Ejemplo n.º 7
0
    def obs_SN(self,start_time,stop_time=None,overlapping=True,include_dai=False):
        if stop_time is None:
            stop_time=cmip5.stop_time(self.projection)
        target_obs = self.projection(time=(start_time,stop_time))
        L=len(target_obs)
        modslopes,noiseterm = self.sn_at_time(start_time,L,overlapping=True)
        ns=np.std(noiseterm)
        signal = float(cmip5.get_linear_trends(target_obs))/ns
        plt.hist(modslopes/ns,20,normed=True,color=cm.Oranges(.8),alpha=.5)
        lab = str(start_time.year)+"-"+str(stop_time.year)
        da.fit_normals_to_data(modslopes/ns,color=cm.Oranges(.9),label=lab+" Model projections")

        plt.hist(noiseterm/ns,20,normed=True,color=cm.Greens(.8),alpha=.5)
        da.fit_normals_to_data(noiseterm/ns,color=cm.Greens(.9),label="Pre-1850 tree-ring reconstructions")
        plt.axvline(signal,color=cm.Blues(.8),lw=3,label=lab+" Tree-ring reconstructions")
        print signal
        if include_dai:
            dai_proj = self.project_dai_on_solver(start=start_time)
            daitrend = cmip5.get_linear_trends(dai_proj(time=(start_time,stop_time)))
            
            
            
        plt.legend(loc=0)
Ejemplo n.º 8
0
    def obs_SN(self,
               start_time,
               stop_time=None,
               overlapping=True,
               include_trees=True,
               include_dai=False,
               include_cru=False,
               include_piControl=False,
               noisestart=None,
               solver=None,
               plot=True):
        to_return = {}
        if stop_time is None:
            stop_time = cmip5.stop_time(self.get_tree_ring_projection())
        target_obs = self.get_tree_ring_projection(solver=solver)(
            time=(start_time, stop_time))
        L = len(target_obs)
        modslopes, noiseterm = self.sn_at_time(start_time,
                                               L,
                                               overlapping=True,
                                               noisestart=noisestart,
                                               solver=solver)
        ns = np.std(noiseterm)
        signal = float(cmip5.get_linear_trends(target_obs))
        if plot:
            plt.hist(modslopes / ns,
                     20,
                     normed=True,
                     color=get_dataset_color("h85"),
                     alpha=.5)
            lab = str(start_time.year) + "-" + str(stop_time.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")

        if include_trees:
            percentiles = []
            if plot:
                plt.axvline(signal / ns,
                            color=get_dataset_color("tree"),
                            lw=1,
                            label=lab + " GDA trend")
            print signal / ns
            noise_percentile = stats.percentileofscore(noiseterm.tolist(),
                                                       signal)
            h85_percentile = stats.percentileofscore(modslopes.tolist(),
                                                     signal)
            percentiles += [noise_percentile, h85_percentile]
            to_return["trees"] = [signal / ns] + percentiles
        if include_dai:
            daipercentiles = []
            dai_proj = self.project_dai_on_solver(start=start_time,
                                                  solver=solver)
            daitrend = float(
                cmip5.get_linear_trends(dai_proj(time=(start_time,
                                                       stop_time))))
            daisignal = daitrend / ns
            noise_percentile = stats.percentileofscore(noiseterm.tolist(),
                                                       daitrend)
            h85_percentile = stats.percentileofscore(modslopes.tolist(),
                                                     daitrend)
            daipercentiles += [noise_percentile, h85_percentile]
            if plot:
                plt.axvline(daisignal,
                            color=get_dataset_color("dai"),
                            lw=1,
                            label="Dai")
            print "DAI signal/noise is " + str(daisignal)
            to_return["dai"] = [daitrend / ns] + daipercentiles

        if include_cru:
            crupercentiles = []
            cru_proj = self.project_cru_on_solver(start=start_time,
                                                  solver=solver)
            crutrend = float(
                cmip5.get_linear_trends(cru_proj(time=(start_time,
                                                       stop_time))))
            noise_percentile = stats.percentileofscore(noiseterm.tolist(),
                                                       crutrend)
            h85_percentile = stats.percentileofscore(modslopes.tolist(),
                                                     crutrend)
            crupercentiles += [noise_percentile, h85_percentile]
            crusignal = crutrend / ns
            if plot:
                plt.axvline(crusignal,
                            color=get_dataset_color("cru"),
                            lw=1,
                            label="CRU")
            print "CRU signal/noise is " + str(crusignal)
            to_return["cru"] = [crutrend / ns] + crupercentiles
        if include_piControl:
            p = self.project_piControl_on_solver(solver=solver)
            noiseterm_mod = bootstrap_slopes(p, L)
            if plot:
                plt.hist(noiseterm_mod / ns,
                         20,
                         normed=True,
                         color=get_dataset_color("picontrol"),
                         alpha=.5)
                da.fit_normals_to_data(noiseterm_mod / ns,
                                       color=get_dataset_color("picontrol"),
                                       lw=1,
                                       label="PiControl")
            print "relative to model noise:"
            print float(signal) / np.std(noiseterm_mod)
        # percentiles+=[stats.percentileofscore(noiseterm_mod.tolist(),signal)]

        if plot:
            plt.legend(loc=0)
            plt.xlabel("S/N")
            plt.ylabel("Normalized Frequency")
        return to_return
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
def average_histogram(obslist,
                      h85,
                      piC,
                      direction,
                      start=None,
                      stop=None,
                      months="JJ"):
    if months is "JJ":
        mmean = lambda x: MV.average(x[:, 5:7], axis=1)
        bigmmean = lambda X: MV.average(X[:, :, 5:7], axis=2)
    elif months is "SO":
        mmean = lambda x: MV.average(x[:, 8:10], axis=1)
        bigmmean = lambda X: MV.average(X[:, :, 8:10], axis=2)
    elif months is "JJA":
        mmean = lambda x: MV.average(x[:, 5:8], axis=1)
        bigmmean = lambda X: MV.average(X[:, :, 5:8], axis=2)
    elif months is "Jun":
        mmean = lambda x: x[:, 5]
        bigmmean = lambda X: MV.average(X[:, :, 5])
    if type(obslist) == type([]):
        obs = obslist[0]
    else:
        obs = obslist
    if start is None:
        start = cmip5.start_time(obs.reshaped["east"])
        start = cdtime.comptime(start.year, start.month, 1)
    if stop is None:
        stop = cmip5.stop_time(obs.reshaped["west"])
        stop = cdtime.comptime(stop.year, stop.month, 30)
    #calculate the trend in the observations

    obs_avg = mmean(obs.reshaped[direction](time=(start, stop)))

    obs_trend = cmip5.get_linear_trends(obs_avg)
    #get the h85 trends over the same time period
    H85m = bigmmean(h85.reshaped[direction])(time=(start, stop))
    H85 = cmip5.cdms_clone(np.ma.mask_rows(H85m), H85m)
    H85_trends = cmip5.get_linear_trends(H85)
    #get the piControl projection time series
    noise = mmean(piC.reshaped[direction])
    L = len(obs_avg)
    noise_trends = da.get_slopes(noise, L)

    #plot
    plt.hist(H85_trends.compressed(),
             25,
             color=da_colors("h85"),
             alpha=.5,
             normed=True)
    plt.hist(noise_trends, 25, color=da_colors("piC"), alpha=.5, normed=True)
    da.fit_normals_to_data(H85_trends,
                           color=da_colors("h85"),
                           lw=3,
                           label="H85")
    da.fit_normals_to_data(noise_trends,
                           color=da_colors("piC"),
                           lw=3,
                           label="piControl")
    plt.axvline(obs_trend, label=obs.dataset, color=da_colors(obs.dataset))
    if type(obslist) == type([]):
        for obs in obslist[1:]:
            obs_avg = mmean(obs.reshaped[direction](time=(start, stop)))

            obs_trend = cmip5.get_linear_trends(obs_avg)

            plt.axvline(obs_trend,
                        label=obs.dataset,
                        color=da_colors(obs.dataset))
    plt.xlabel("S/N")
    plt.ylabel("Frequency")
    plt.legend(loc=0)
Ejemplo n.º 11
0
    def average_histogram(self,
                          direction,
                          start=None,
                          stop=None,
                          months="JJ",
                          datasets=None):
        if months is "JJ":
            mmean = lambda x: MV.average(x[:, 5:7], axis=1)
            bigmmean = lambda X: MV.average(X[:, :, 5:7], axis=2)

        elif months is "SO":
            mmean = lambda x: MV.average(x[:, 8:10], axis=1)
            bigmmean = lambda X: MV.average(X[:, :, 8:10], axis=2)
        elif months is "JJA":
            mmean = lambda x: MV.average(x[:, 5:8], axis=1)
            bigmmean = lambda X: MV.average(X[:, :, 5:8], axis=2)
        elif months is "JAS":
            mmean = lambda x: MV.average(x[:, 6:9], axis=1)
            bigmmean = lambda X: MV.average(X[:, :, 6:9], axis=2)
        elif months is "Jun":
            mmean = lambda x: x[:, 5]
            bigmmean = lambda X: MV.average(X[:, :, 5])
        elif months is "YEAR":
            mmean = lambda x: MV.average(x, axis=1)
            bigmmean = lambda X: MV.average(X, axis=2)
        if start is None:
            start = cmip5.start_time(self.gpcp.reshaped["east"])
            start = cdtime.comptime(start.year, start.month, 1)
        if stop is None:
            stop = cmip5.stop_time(self.gpcp.reshaped["east"])
            stop = cdtime.comptime(stop.year, stop.month, 30)

        #get the h85 trends over the same time period
        H85m = bigmmean(self.h85.reshaped[direction])(time=(start, stop))
        H85 = cmip5.cdms_clone(np.ma.mask_rows(H85m), H85m)
        H85_trends = cmip5.get_linear_trends(H85)
        #get the piControl projection time series
        noise = mmean(self.piC.reshaped[direction])
        L = stop.year - start.year + 1
        noise_trends = da.get_slopes(noise, L)

        #plot
        plt.hist(H85_trends.compressed(),
                 25,
                 color=da_colors("h85"),
                 alpha=.5,
                 normed=True)
        plt.hist(noise_trends,
                 25,
                 color=da_colors("piC"),
                 alpha=.5,
                 normed=True)
        da.fit_normals_to_data(H85_trends,
                               color=da_colors("h85"),
                               lw=3,
                               label="H85")
        da.fit_normals_to_data(noise_trends,
                               color=da_colors("piC"),
                               lw=3,
                               label="piControl")

        #calculate the trend in the observations
        if datasets is None:
            datasets = ["gpcp", "cmap", "precl"]
        if type(datasets) != type([]):
            datasets = [datasets]
        for dataset in datasets:
            X = self.OBS[string.upper(dataset)]
            obs_avg = mmean(X.reshaped[direction](time=(start, stop)))

            obs_trend = cmip5.get_linear_trends(obs_avg)

            plt.axvline(obs_trend, label=dataset, color=da_colors(dataset))
        plt.xlabel("S/N")
        plt.ylabel("Frequency")
        plt.legend(loc=0)