def timeseries_add_breaks(data, var, p=None, ax=None, color='k'): """ Add Breakpoint lines to plot Parameters ---------- data var p ax color Returns ------- """ import matplotlib.pyplot as plt funcid='TB' if not isinstance(var, str): raise ValueError("Variable is a string") pressure_levels, dates, plevs, test, label = timeseries_preprocessor(data, [var, '%s_breaks' % var, '%s_snht' % var], p=p, funcid=funcid) # # Plot summed SNHT # if pressure_levels: breaks = dates[(test["%s_breaks" % var] != 0).all(1)] else: breaks = dates[(test["%s_breaks" % var] != 0)] # if ax is None: ax = plt.gca() [ax.axvline(x=ib, color=color) for ib in breaks]
def timeseries_occurence(data, var, reference=None, levels=None, quantilen=None, limit=500, p=None, ax=None, legend=True, name=None, verbose=0, **kwargs): """ Parameters ---------- data var reference quantilen p ax legend name verbose kwargs """ import matplotlib.pyplot as plt from raso.breakpoint import quantile_count funcid = "[plot TOCC] " if not isinstance(var, str): raise ValueError("Variable is a string") pressure_levels, dates, plevs, test, label = timeseries_preprocessor(data, var, p=p, funcid=funcid) title = kwargs.pop('title', 'Radiosonde Occurence Frequency') yticklabels = kwargs.pop('yticklabels', None) xlabel = kwargs.pop('xlabel', 'Time') if ax is None: f, ax = plt.subplots(figsize=kwargs.pop('figsize', (10, 6))) if name is None: name = 'Occurence Freq. %s' % var # # Count per month # test = quantile_count(test, var, reference=reference, levels=levels, quantilen=quantilen, limit=limit) # gives a panel if pressure_levels are present # # Plot (contour or contour per level ?) # if not pressure_levels: test.plot(ax=ax, kind='area') # ax.plot(dates, test, **kwargs) ax.set_ylabel(name) ax.grid(True) ax.set_xlabel(xlabel) ax.set_title(title) else: print "not sure how to plot all this information" return test
def breakpoint_timeseries(data, var, unit='K', p=None, bins=None, departures=False, post_snht=False, raw=False, window=365, min_periods=30, figsize=(16,9), ylim=None, verbose=0, **kwargs): """ Parameters ---------- data var unit p bins departures post_snht window min_periods figsize ylim verbose Returns ------- """ import matplotlib.pyplot as plt from timeseries import timeseries_snht from raso.breakpoint.detections import _1d_detection funcid = '[BTS] ' pressure_levels, dates, plevs, test, label = timeseries_preprocessor(data, [var, "%s_dep_breaks" % var, "%s_dep_snht" % var], p=p, add_vars=["%s_mcor" % var, "%s_qcor" % var, "%s_qecor" % var, "%s_era" % var, "%s_era_adj" % var, "%s_dep" % var], funcid=funcid) if plevs is None: raise RuntimeError(funcid + " Require an availbale pressure level at least!") else: if isinstance(plevs, (int,float)): plevs = [plevs] # as list if bins is None: bins = np.arange(0, 50) varselection = [] varlabel = [] correction_present = False for jvar in label: if jvar == var: varlabel = ['U'] varselection.append(jvar) elif 'mcor' in jvar: varlabel.append('M') varselection.append(jvar) correction_present = True elif 'qcor' in jvar: varlabel.append('Q') varselection.append(jvar) correction_present = True elif 'qecor' in jvar: varlabel.append('QE') varselection.append(jvar) correction_present = True elif 'adj' in jvar: varlabel.append('EA') varselection.append(jvar) elif jvar == "%s_era" % var: varlabel.append('E') varselection.append(jvar) else: if verbose > 0: print "Not used: ", jvar if verbose > 0: print varlabel print varselection # title = kwargs.pop('title', 'Radiosonde Breakpoint Detection and Correction') xlabel = kwargs.pop('xlabel', 'Time') if pressure_levels: breaks = filter_series((test["%s_dep_breaks" % var] > 0).any(1)) else: breaks = filter_series((test["%s_dep_breaks" % var] > 0)) # nbreaks = len(breaks) # if nbreaks == 0: nbreaks = 1 nplotlevels = 4 # snht, timeseries, hist, hist if not correction_present: nplotlevels = 3 for z, ilev in enumerate(plevs): print "%d / %d : %d" % (z+1, len(plevs), ilev) if pressure_levels: plotdata = test.minor_xs(ilev) else: plotdata = test if verbose > 0: print plotdata.shape print plotdata.columns plotdata = plotdata.resample('12h').asfreq() # make sure it is the same freq # f = plt.figure(figsize=figsize) # # Figure 1 : SNHT # axs = plt.subplot2grid((nplotlevels, nbreaks), (0, 0), colspan=nbreaks) timeseries_snht(plotdata, "%s_dep" % var, ax=axs, label='U') axs.set_ylabel('SNHT') axs.set_yticklabels(axs.get_yticklabels()[::2]) if post_snht: for k, zvar in enumerate(varselection): if (zvar == '%s_era' % var) or (zvar == var): continue tmpdata = plotdata.loc[:, zvar].copy().to_frame() if verbose > 0: print "SNHT for ", zvar status = _1d_detection(tmpdata, zvar, 1460, 730, 50) # default parameters axs.plot(tmpdata.index, tmpdata['%s_snht' % zvar], label=varlabel[k], alpha=0.7, ls='--') axs.legend(loc="upper left", fontsize=plt.rcParams.get('font.size') - 2, bbox_to_anchor=(1.02, 1), bbox_transform=axs.transAxes) # plt.setp(axs.get_xticklabels(), visible=False) axt = plt.subplot2grid((nplotlevels, nbreaks), (1, 0), colspan=nbreaks, sharex=axs) # # DEPARTURES # if departures: for jvar in varselection: if jvar == "%s_era" % var: continue plotdata[jvar] = plotdata[jvar] - plotdata["%s_era" % var] # ref !! # if raw: pd_mean = plotdata else: pd_mean = plotdata.rolling(window=window, min_periods=min_periods).mean() # # Figure 2 : Values # for j, jvar in enumerate(varselection): if departures and jvar == '%s_era' % var: continue axt.plot(pd_mean.index, pd_mean[jvar], lw=2, label=varlabel[j]) axs.set_xticks(np.unique(pd_mean.index.year.astype('str'))[::2]) # ticks axs.set_title(title + " %d hPa" % int(ilev/100)) axs.grid() # overwrite axs.grid() axt.set_xticks(np.unique(pd_mean.index.year.astype('str'))[::2]) # ticks if ylim is None: ym = int(pd_mean[var].mean()) ys = 5 # int(pd_mean[var].std())*2 ylim = (ym-ys, ym+ys) axt.set_ylim(ylim) axt.set_yticks(axt.get_yticks()[::2]) if departures: axt.set_ylabel("%s [%s]" % (var.upper(),unit)) else: axt.set_ylabel("%s dep. [%s]" % (var.upper(),unit)) axt.grid() # axt.legend(loc="upper center", ncol=5, fontsize=plt.rcParams.get('font.size') - 2) # bbox_to_anchor=(1, 1)) axt.legend(loc="upper left", fontsize=plt.rcParams.get('font.size') - 2, bbox_to_anchor=(1.02, 1), bbox_transform=axt.transAxes) [axt.axvline(x=ib, color='k') for ib in breaks] [axt.text(ib, pd_mean[var].min(), "B%02d" % (nbreaks - i), color='k') for i, ib in enumerate(breaks)] # # # Figure 3: Histograms for each breakpoint # for ibreak in range(nbreaks): if ibreak == 0: ax1 = plt.subplot2grid((nplotlevels, nbreaks), (2, ibreak)) axi = ax1 else: axi = plt.subplot2grid((nplotlevels, nbreaks), (2, ibreak), sharey=ax1) # Reference if ibreak + 1 < nbreaks: iref = slice(breaks[ibreak], breaks[ibreak + 1]) else: iref = slice(breaks[ibreak], None) # Biased Sample if ibreak > 0: ibiased = slice(breaks[ibreak - 1], breaks[ibreak]) else: ibiased = slice(None, breaks[ibreak]) # axi.hist(plotdata.ix[iref, var], bins=bins, normed=1, label='BB') if "%s_era_adj" % var in varselection: axi.hist(plotdata.ix[iref, "%s_era_adj" % var], bins=bins, normed=1, label='EA', alpha=0.6) axi.hist(plotdata.ix[ibiased, var], bins=bins, normed=1, label='AB', alpha=0.6) # if ibreak == 0: axi.set_yticks(axi.get_yticks()[::2]) axi.grid() axi.set_title("B%02d" % (nbreaks - ibreak), y=0.75) if ibreak > 0: plt.setp(axi.get_yticklabels(), visible=False) # # Figure 4: Correction Histograms for each breakpoint # if correction_present: axj = plt.subplot2grid((nplotlevels, nbreaks), (3, ibreak), sharey=ax1, sharex=axi) plt.setp(axi.get_xticklabels(), visible=False) alpha=1 for j, jvar in enumerate(varselection): if 'cor' in jvar: axj.hist(plotdata.ix[ibiased, jvar], bins=bins, normed=1, label=varlabel[j], alpha=(alpha-0.1*j)) axj.grid() axj.set_xlabel('%s [%s]' % (var.upper(), unit)) if ibreak > 0: plt.setp(axj.get_yticklabels(), visible=False) axi.legend(loc='upper left', fontsize=plt.rcParams.get('font.size') - 2, bbox_to_anchor=(1.05, 1)) if correction_present: axj.legend(loc='upper left', fontsize=plt.rcParams.get('font.size') - 2, bbox_to_anchor=(1.05, 1))
def timeseries_anomaly(data, var, dvar, p=None, ax=None, levels=None, legend=True, name=None, freq=None, resample_func='mean', add_zero=False, logy=True, breakvar=None, verbose=0, **kwargs): """ Parameters ---------- data var dvar p ax levels legend name freq resample_func add_zero verbose kwargs """ import matplotlib.pyplot as plt funcid = "[plot TANO] " if not isinstance(var, str): raise ValueError("Variable is a string") if not isinstance(dvar, str): raise ValueError("Variable is a string") pressure_levels, dates, plevs, test, label = timeseries_preprocessor(data, [var, dvar], p=p, add_vars=breakvar, funcid=funcid) title = kwargs.pop('title', 'Radiosonde Anomaly Timeseries') yticklabels = kwargs.pop('yticklabels', None) xlabel = kwargs.pop('xlabel', 'Time') if ax is None: f, ax = plt.subplots(figsize=kwargs.pop('figsize', (10, 6))) if name is None: name = 'Anomaly (%s - %s)' % (dvar, var) breaks = None if breakvar in label: if pressure_levels: breaks = np.unique(dates[(test[breakvar] != 0).all(1)]) else: breaks = np.unique(dates[(test[breakvar] != 0)]) # # Resample # if freq is not None: test = (test[dvar] - test[var]).resample(freq, axis=0).apply(resample_func) dates = test.index if pressure_levels: plevs = test.columns test = test.values xlabel += " %s (%s)" % (freq, resample_func) else: test = (test[dvar] - test[var]).values # # Plot (timeseries or contour) # if not pressure_levels: ax.plot(dates, test, **kwargs) ax.set_ylabel(name) if add_zero: ax.axhline(y=0, color='k') else: # PCOLOR MESH VERSION # test = np.ma.masked_where(np.isnan(test),test) # cmap = plt.get_cmap(cmap) # norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True) # CS = ax.pcolormesh(data.major_axis.to_pydatetime(), data.minor_axis.values, # test.T,norm=norm,cmap=cmap)# ,levels=levels,extend='both') if 'cmap' not in kwargs.keys(): kwargs['cmap'] = 'RdBu_r' cs = ax.contourf(dates, plevs, test.T, levels=levels, **kwargs) if logy: ax.set_yscale('log') ax.set_yticks(plevs, minor=True) if yticklabels is not None: yticklabels = np.asarray(yticklabels) # can not calc on list ax.set_yticks(yticklabels) ax.set_yticklabels(np.int_(yticklabels / 100.)) else: ax.set_yticks(plevs[::2]) ax.set_yticklabels(np.int_(plevs[::2] / 100.)) ax.set_ylabel('p Levels') ax.invert_yaxis() if legend: cbar = plt.colorbar(cs, ax=ax, orientation="vertical", fraction=0.1) cbar.ax.set_ylabel(name) if add_zero: cszero = ax.contour(dates, plevs, test.T, (0,), colors='k') ax.grid(True) ax.set_xlabel(xlabel) if breaks is not None: [ax.axvline(x=ib, color='k') for ib in breaks] ax.set_title(title) if pressure_levels and not legend: return cs
def timeseries_var(data, var, p=None, ax=None, levels=None, legend=True, name=None, freq=None, resample_func='mean', logy=True, verbose=0, **kwargs): """ Parameters ---------- data var p ax levels legend name freq resample_func verbose kwargs """ import matplotlib.pyplot as plt funcid = "[plot TVAR]" if not isinstance(var, str): raise ValueError("Variable is a string") pressure_levels, dates, plevs, test, label = timeseries_preprocessor(data, var, p=p, add_vars='%s_breaks' % var, funcid=funcid) title = kwargs.pop('title', 'Radiosonde Timeseries') yticklabels = kwargs.pop('yticklabels', None) xlabel = kwargs.pop('xlabel', 'Time') if ax is None: f, ax = plt.subplots(figsize=kwargs.pop('figsize', (10, 6))) if name is None: name = 'Variable %s' % var breaks = None if '%s_dep_breaks' % var in label: if pressure_levels: breaks = np.unique(dates[(test["%s_breaks" % var] != 0).all(1)]) else: breaks = np.unique(dates[(test["%s_breaks" % var] != 0)]) # # Resample # if freq is not None: test = test[var].resample(freq, axis=0).apply(resample_func) dates = test.index if pressure_levels: plevs = test.columns test = test.values xlabel += " %s (%s)" % (freq, resample_func) else: test = test[var].values # # Plot (timeseries or contour) # if not pressure_levels: ax.plot(dates, test, **kwargs) ax.set_ylabel(name) else: if 'cmap' not in kwargs.keys(): kwargs['cmap'] = 'RdYlBu_r' cs = ax.contourf(dates, plevs, test.T, levels=levels, **kwargs) if logy: ax.set_yscale('log') ax.set_yticks(plevs, minor=True) if yticklabels is not None: yticklabels = np.asarray(yticklabels) # can not calc on list ax.set_yticks(yticklabels) ax.set_yticklabels(np.int_(yticklabels / 100.)) else: ax.set_yticks(plevs[::2]) ax.set_yticklabels(np.int_(plevs[::2] / 100.)) ax.set_ylabel('p Levels') ax.invert_yaxis() if legend: cbar = plt.colorbar(cs, ax=ax, orientation="vertical", fraction=0.1) cbar.ax.set_ylabel(name) ax.grid(True) ax.set_xlabel(xlabel) if breaks is not None: [ax.axvline(x=ib, color='k') for ib in breaks] ax.set_title(title) if pressure_levels and not legend: return cs
def timeseries_snht(data, var, p=None, borders=None, ax=None, legend=True, levels=None, logy=True, **kwargs): """ Creates a timeseries plot of the SNHT 1. time x pressure levels 2. time at a specified pressure level Parameters ---------- data DataFrame/Panel Radiosonde Data var str Variable name that has an snht variable as well p int/float Pressure level borders int days befre and after breakpoint to highlight ax Axes legend bool kwargs ** """ import matplotlib.gridspec as gridspec import matplotlib.pyplot as plt funcid = '[plot TSNHT] ' if not isinstance(var, str): raise ValueError("Variable is a string") pressure_levels, dates, plevs, test, label = timeseries_preprocessor(data, [var, '%s_breaks' % var, '%s_snht' % var], p=p, funcid=funcid) title = kwargs.pop('title', 'Radiosonde SNHT') yticklabels = kwargs.pop('yticklabels', None) xlabel = kwargs.pop('xlabel', 'Time') if borders is not None: title += " B(%d days)" % borders if ax is None: if pressure_levels: f = plt.figure(figsize=kwargs.pop('figsize', (10, 6))) gs = gridspec.GridSpec(2, 1, height_ratios=[1, 4]) ax = plt.subplot(gs[0]) axy = plt.subplot(gs[1], sharex=ax) else: f, ax = plt.subplots(figsize=kwargs.pop('figsize', (10, 6))) # # Plot summed SNHT # if pressure_levels: breaks = dates[(test["%s_breaks" % var] != 0).all(1)] tmp = data["%s_snht" % var].sum(1) ax.plot(dates, tmp) # Kwargs ar going to contour if 'cmap' not in kwargs.keys(): kwargs['cmap'] = 'Reds' else: breaks = dates[(test["%s_breaks" % var] != 0)] tmp = test["%s_snht" % var] ax.plot(dates, tmp, **kwargs) # Plot # ax.grid(True) [ax.axvline(x=ib, color='k') for ib in breaks] # if borders is not None: for ib in breaks: # tmp = test.ix['%s_snht' % var, (ib-pd.DateOffset(days=borders)):(ib+pd.DateOffset(days=borders)), :] x = tmp.ix[(ib-pd.DateOffset(days=borders)):(ib+pd.DateOffset(days=borders))] ax.fill_between(x.index, 0, x.values, color='m', alpha=0.6) ax.set_title(title) if not pressure_levels: ax.set_xlabel(xlabel) return ax.set_xlabel('') ax.set_ylabel(r'$\sum$ SNHT') ax.set_yticks(ax.get_yticks()[::2]) # # Plot Contour Plot # area = data['%s_snht' % var] area = np.where(area < 10, np.nan, area) cs = axy.contourf(dates, plevs, area.T, levels=levels, **kwargs) if logy: axy.set_yscale('log') axy.set_yticks(plevs, minor=True) if yticklabels is not None: yticklabels = np.asarray(yticklabels) # can not calc on list axy.set_yticks(yticklabels) axy.set_yticklabels(np.int_(yticklabels/100.)) else: axy.set_yticks(plevs[::2]) axy.set_yticklabels(np.int_(plevs[::2]/100.)) axy.set_ylabel('p Levels') axy.set_xlabel(xlabel) axy.grid(True) [axy.axvline(x=ib, color='k') for ib in breaks] axy.invert_yaxis() if legend: cbar = plt.colorbar(cs, ax=axy, orientation="horizontal", fraction=0.05) cbar.ax.set_ylabel('SNHT') else: return cs