def run_calcs(df, ctx): """Do our maths.""" # Convert sea level pressure to station pressure df["pressure"] = mcalc.add_height_to_pressure( df["slp"].values * units("millibars"), ctx["_nt"].sts[ctx["station"]]["elevation"] * units("m"), ).to(units("millibar")) # Compute the mixing ratio df["mixingratio"] = mcalc.mixing_ratio_from_relative_humidity( df["relh"].values * units("percent"), df["tmpf"].values * units("degF"), df["pressure"].values * units("millibars"), ) # Compute the saturation mixing ratio df["saturation_mixingratio"] = mcalc.saturation_mixing_ratio( df["pressure"].values * units("millibars"), df["tmpf"].values * units("degF"), ) df["vapor_pressure"] = mcalc.vapor_pressure( df["pressure"].values * units("millibars"), df["mixingratio"].values * units("kg/kg"), ).to(units("kPa")) df["saturation_vapor_pressure"] = mcalc.vapor_pressure( df["pressure"].values * units("millibars"), df["saturation_mixingratio"].values * units("kg/kg"), ).to(units("kPa")) df["vpd"] = df["saturation_vapor_pressure"] - df["vapor_pressure"] # remove any NaN rows df = df.dropna() group = df.groupby("year") df = group.aggregate(np.average) df["dwpf"] = (mcalc.dewpoint(df["vapor_pressure"].values * units("kPa")).to(units("degF")).m) return df
def run_calcs(df, ctx): """Do our maths.""" # Convert sea level pressure to station pressure df['pressure'] = mcalc.add_height_to_pressure( df['slp'].values * units('millibars'), ctx['nt'].sts[ctx['station']]['elevation'] * units('m')).to( units('millibar')) # Compute the mixing ratio df['mixingratio'] = mcalc.mixing_ratio_from_relative_humidity( df['relh'].values * units('percent'), df['tmpf'].values * units('degF'), df['pressure'].values * units('millibars')) # Compute the saturation mixing ratio df['saturation_mixingratio'] = mcalc.saturation_mixing_ratio( df['pressure'].values * units('millibars'), df['tmpf'].values * units('degF')) df['vapor_pressure'] = mcalc.vapor_pressure( df['pressure'].values * units('millibars'), df['mixingratio'].values * units('kg/kg')).to(units('kPa')) df['saturation_vapor_pressure'] = mcalc.vapor_pressure( df['pressure'].values * units('millibars'), df['saturation_mixingratio'].values * units('kg/kg')).to(units('kPa')) df['vpd'] = df['saturation_vapor_pressure'] - df['vapor_pressure'] group = df.groupby('year') df = group.aggregate(np.average) df['dwpf'] = mcalc.dewpoint(df['vapor_pressure'].values * units('kPa')).to( units('degF')).m return df
def test_add_height_to_pressure(array_type): """Test the pressure at height above pressure calculation.""" mask = [False, True, False] pressure_in = array_type([1000., 900., 800.], 'hPa', mask=mask) height = array_type([877.17421094, 500., 300.], 'meter', mask=mask) pressure_out = add_height_to_pressure(pressure_in, height) truth = array_type([900., 846.725, 770.666], 'hPa', mask=mask) assert_array_almost_equal(pressure_out, truth, 2)
def test_add_height_to_pressure(): """Test the pressure at height above pressure calculation.""" pressure = add_height_to_pressure(1000 * units.hPa, 877.17421094 * units.meter) assert_almost_equal(pressure, 900 * units.hPa, 5)
def plotter(fdict): """ Go """ pgconn = get_dbconn("asos") ctx = get_autoplot_context(fdict, get_description()) station = ctx["zstation"] month = ctx["month"] if month == "all": months = range(1, 13) elif month == "fall": months = [9, 10, 11] elif month == "winter": months = [12, 1, 2] elif month == "spring": months = [3, 4, 5] elif month == "summer": months = [6, 7, 8] else: ts = datetime.datetime.strptime("2000-" + month + "-01", "%Y-%b-%d") # make sure it is length two for the trick below in SQL months = [ts.month, 999] df = read_sql( """ SELECT drct::int as t, dwpf, tmpf, relh, coalesce(mslp, alti * 33.8639, 1013.25) as slp from alldata where station = %s and drct is not null and dwpf is not null and dwpf <= tmpf and sknt > 3 and drct::int %% 10 = 0 and extract(month from valid) in %s and report_type = 2 """, pgconn, params=(station, tuple(months)), ) if df.empty: raise NoDataFound("No Data Found.") # Convert sea level pressure to station pressure df["pressure"] = mcalc.add_height_to_pressure( df["slp"].values * units("millibars"), ctx["_nt"].sts[station]["elevation"] * units("m"), ).to(units("millibar")) # compute mixing ratio df["mixingratio"] = mcalc.mixing_ratio_from_relative_humidity( df["relh"].values * units("percent"), df["tmpf"].values * units("degF"), df["pressure"].values * units("millibars"), ) # compute pressure df["vapor_pressure"] = mcalc.vapor_pressure( df["pressure"].values * units("millibars"), df["mixingratio"].values * units("kg/kg"), ).to(units("kPa")) means = df.groupby("t").mean().copy() # compute dewpoint now means["dwpf"] = (mcalc.dewpoint(means["vapor_pressure"].values * units("kPa")).to(units("degF")).m) (fig, ax) = plt.subplots(1, 1) ax.bar( means.index.values, means["dwpf"].values, ec="green", fc="green", width=10, align="center", ) ax.grid(True, zorder=11) ab = ctx["_nt"].sts[station]["archive_begin"] if ab is None: raise NoDataFound("Unknown station metadata.") ax.set_title( ("%s [%s]\nAverage Dew Point by Wind Direction (month=%s) " "(%s-%s)\n" "(must have 3+ hourly obs > 3 knots at given direction)") % ( ctx["_nt"].sts[station]["name"], station, month.upper(), max([1973, ab.year]), datetime.datetime.now().year, ), size=10, ) ax.set_ylabel("Dew Point [F]") ax.set_ylim(means["dwpf"].min() - 5, means["dwpf"].max() + 5) ax.set_xlim(-5, 365) ax.set_xticks([0, 45, 90, 135, 180, 225, 270, 315, 360]) ax.set_xticklabels(["N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"]) ax.set_xlabel("Wind Direction") return fig, means["dwpf"]
def plotter(fdict): """ Go """ pgconn = get_dbconn('asos') ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] network = ctx['network'] nt = NetworkTable(network) year = ctx['year'] varname = ctx['var'] df = read_sql(""" SELECT extract(year from valid) as year, coalesce(mslp, alti * 33.8639, 1013.25) as slp, extract(doy from valid) as doy, tmpf, dwpf from alldata where station = %s and dwpf > -50 and dwpf < 90 and tmpf > -50 and tmpf < 120 and valid > '1950-01-01' and report_type = 2 """, pgconn, params=(station, ), index_col=None) # compute RH df['relh'] = mcalc.relative_humidity_from_dewpoint( df['tmpf'].values * units('degF'), df['dwpf'].values * units('degF')) # saturation vapor pressure # Convert sea level pressure to station pressure df['pressure'] = mcalc.add_height_to_pressure( df['slp'].values * units('millibars'), nt.sts[station]['elevation'] * units('m')).to(units('millibar')) # Compute the relative humidity df['relh'] = mcalc.relative_humidity_from_dewpoint( df['tmpf'].values * units('degF'), df['dwpf'].values * units('degF')) # Compute the mixing ratio df['mixing_ratio'] = mcalc.mixing_ratio_from_relative_humidity( df['relh'].values, df['tmpf'].values * units('degF'), df['pressure'].values * units('millibars')) # Compute the saturation mixing ratio df['saturation_mixingratio'] = mcalc.saturation_mixing_ratio( df['pressure'].values * units('millibars'), df['tmpf'].values * units('degF')) df['vapor_pressure'] = mcalc.vapor_pressure( df['pressure'].values * units('millibars'), df['mixing_ratio'].values * units('kg/kg')).to(units('kPa')) df['saturation_vapor_pressure'] = mcalc.vapor_pressure( df['pressure'].values * units('millibars'), df['saturation_mixingratio'].values * units('kg/kg')).to(units('kPa')) df['vpd'] = df['saturation_vapor_pressure'] - df['vapor_pressure'] dailymeans = df[['year', 'doy', varname]].groupby(['year', 'doy']).mean() dailymeans = dailymeans.reset_index() df2 = dailymeans[['doy', varname]].groupby('doy').describe() dyear = df[df['year'] == year] df3 = dyear[['doy', varname]].groupby('doy').describe() df3[(varname, 'diff')] = df3[(varname, 'mean')] - df2[(varname, 'mean')] (fig, ax) = plt.subplots(2, 1, figsize=(8, 6)) multiplier = 1000. if varname == 'mixing_ratio' else 10. ax[0].fill_between(df2[(varname, 'min')].index.values, df2[(varname, 'min')].values * multiplier, df2[(varname, 'max')].values * multiplier, color='gray') ax[0].plot(df2[(varname, 'mean')].index.values, df2[(varname, 'mean')].values * multiplier, label="Climatology") ax[0].plot(df3[(varname, 'mean')].index.values, df3[(varname, 'mean')].values * multiplier, color='r', label="%s" % (year, )) ax[0].set_title(("%s [%s]\nDaily Mean Surface %s") % (station, nt.sts[station]['name'], PDICT[varname])) lbl = ("Mixing Ratio ($g/kg$)" if varname == 'mixing_ratio' else PDICT[varname]) ax[0].set_ylabel(lbl) ax[0].set_xlim(0, 366) ax[0].set_ylim(bottom=0) ax[0].set_xticks( (1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 365)) ax[0].set_xticklabels(calendar.month_abbr[1:]) ax[0].grid(True) ax[0].legend(loc=2, fontsize=10) cabove = 'b' if varname == 'mixing_ratio' else 'r' cbelow = 'r' if cabove == 'b' else 'b' rects = ax[1].bar(df3[(varname, 'diff')].index.values, df3[(varname, 'diff')].values * multiplier, facecolor=cabove, edgecolor=cabove) for rect in rects: if rect.get_height() < 0.: rect.set_facecolor(cbelow) rect.set_edgecolor(cbelow) plunits = '$g/kg$' if varname == 'mixing_ratio' else 'hPa' ax[1].set_ylabel("%.0f Departure (%s)" % (year, plunits)) ax[1].set_xlim(0, 366) ax[1].set_xticks( (1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 365)) ax[1].set_xticklabels(calendar.month_abbr[1:]) ax[1].grid(True) return fig, df3
def plotter(fdict): """ Go """ pgconn = get_dbconn("asos") ctx = get_autoplot_context(fdict, get_description()) station = ctx["zstation"] year = ctx["year"] varname = ctx["var"] df = read_sql( """ SELECT extract(year from valid) as year, coalesce(mslp, alti * 33.8639, 1013.25) as slp, extract(doy from valid) as doy, tmpf, dwpf, relh from alldata where station = %s and dwpf > -50 and dwpf < 90 and tmpf > -50 and tmpf < 120 and valid > '1950-01-01' and report_type = 2 """, pgconn, params=(station, ), index_col=None, ) if df.empty: raise NoDataFound("No Data was found.") # saturation vapor pressure # Convert sea level pressure to station pressure df["pressure"] = mcalc.add_height_to_pressure( df["slp"].values * units("millibars"), ctx["_nt"].sts[station]["elevation"] * units("m"), ).to(units("millibar")) # Compute the mixing ratio df["mixing_ratio"] = mcalc.mixing_ratio_from_relative_humidity( df["relh"].values * units("percent"), df["tmpf"].values * units("degF"), df["pressure"].values * units("millibars"), ) # Compute the saturation mixing ratio df["saturation_mixingratio"] = mcalc.saturation_mixing_ratio( df["pressure"].values * units("millibars"), df["tmpf"].values * units("degF"), ) df["vapor_pressure"] = mcalc.vapor_pressure( df["pressure"].values * units("millibars"), df["mixing_ratio"].values * units("kg/kg"), ).to(units("kPa")) df["saturation_vapor_pressure"] = mcalc.vapor_pressure( df["pressure"].values * units("millibars"), df["saturation_mixingratio"].values * units("kg/kg"), ).to(units("kPa")) df["vpd"] = df["saturation_vapor_pressure"] - df["vapor_pressure"] dailymeans = df[["year", "doy", varname]].groupby(["year", "doy"]).mean() dailymeans = dailymeans.reset_index() df2 = dailymeans[["doy", varname]].groupby("doy").describe() dyear = df[df["year"] == year] df3 = dyear[["doy", varname]].groupby("doy").describe() df3[(varname, "diff")] = df3[(varname, "mean")] - df2[(varname, "mean")] (fig, ax) = plt.subplots(2, 1, figsize=(8, 6)) multiplier = 1000.0 if varname == "mixing_ratio" else 10.0 ax[0].fill_between( df2[(varname, "min")].index.values, df2[(varname, "min")].values * multiplier, df2[(varname, "max")].values * multiplier, color="gray", ) ax[0].plot( df2[(varname, "mean")].index.values, df2[(varname, "mean")].values * multiplier, label="Climatology", ) ax[0].plot( df3[(varname, "mean")].index.values, df3[(varname, "mean")].values * multiplier, color="r", label="%s" % (year, ), ) ax[0].set_title(("%s [%s]\nDaily Mean Surface %s") % (station, ctx["_nt"].sts[station]["name"], PDICT[varname])) lbl = ("Mixing Ratio ($g/kg$)" if varname == "mixing_ratio" else PDICT[varname]) ax[0].set_ylabel(lbl) ax[0].set_xlim(0, 366) ax[0].set_ylim(bottom=0) ax[0].set_xticks((1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335)) ax[0].set_xticklabels(calendar.month_abbr[1:]) ax[0].grid(True) ax[0].legend(loc=2, fontsize=10) cabove = "b" if varname == "mixing_ratio" else "r" cbelow = "r" if cabove == "b" else "b" rects = ax[1].bar( df3[(varname, "diff")].index.values, df3[(varname, "diff")].values * multiplier, facecolor=cabove, edgecolor=cabove, ) for rect in rects: if rect.get_height() < 0.0: rect.set_facecolor(cbelow) rect.set_edgecolor(cbelow) plunits = "$g/kg$" if varname == "mixing_ratio" else "hPa" ax[1].set_ylabel("%.0f Departure (%s)" % (year, plunits)) ax[1].set_xlim(0, 366) ax[1].set_xticks((1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335)) ax[1].set_xticklabels(calendar.month_abbr[1:]) ax[1].grid(True) return fig, df3
def plotter(fdict): """ Go """ pgconn = get_dbconn('asos') ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] h1 = int(ctx['h1']) h2 = int(ctx['h2']) varname = ctx['v'] tzname = ctx['_nt'].sts[station]['tzname'] df = read_sql(""" WITH data as ( SELECT valid at time zone %s + '10 minutes'::interval as localvalid, date_trunc( 'hour', valid at time zone %s + '10 minutes'::interval) as v, tmpf, dwpf, sknt, drct, alti, relh, random() as r, coalesce(mslp, alti * 33.8639, 1013.25) as slp from alldata where station = %s and report_type = 2 and extract(hour from valid at time zone %s + '10 minutes'::interval) in (%s, %s)), agg as ( select *, extract(hour from v) as hour, rank() OVER (PARTITION by v ORDER by localvalid ASC, r ASC) from data ) SELECT *, date( case when hour = %s then date(v - '1 day'::interval) else date(v) end) from agg WHERE rank = 1 """, pgconn, params=(tzname, tzname, station, tzname, h1, h2, h2 if h2 < h1 else -1), index_col=None) if df.empty: raise NoDataFound("No data was found.") if varname == 'q': df['pressure'] = mcalc.add_height_to_pressure( df['slp'].values * units('millibars'), ctx['_nt'].sts[station]['elevation'] * units('m')).to( units('millibar')) # compute mixing ratio df['q'] = mcalc.mixing_ratio_from_relative_humidity( df['relh'].values * units('percent'), df['tmpf'].values * units('degF'), df['pressure'].values * units('millibars')) * 1000. # pivot df = df.pivot(index='date', columns='hour', values=varname).reset_index() df = df.dropna() df['doy'] = pd.to_numeric(pd.to_datetime(df['date']).dt.strftime("%j")) df['year'] = pd.to_datetime(df['date']).dt.year df['week'] = (df['doy'] / 7).astype(int) df['delta'] = df[h2] - df[h1] (fig, ax) = plt.subplots(1, 1) if ctx['opt'] == 'no': ax.set_xlabel("Plotted lines are smoothed over %.0f days" % (ctx['smooth'], )) ax.set_ylabel( "%s %s Difference" % (PDICT[varname], "Accumulated Sum" if ctx['opt'] == 'yes' else '')) if ctx['opt'] == 'no': # Histogram H, xedges, yedges = np.histogram2d(df['doy'].values, df['delta'].values, bins=(50, 50)) ax.pcolormesh(xedges, yedges, H.transpose(), cmap=plt.get_cmap(ctx['cmap']), alpha=0.5) # Plot an average line gdf = df.groupby('doy').mean().rolling(ctx['smooth'], min_periods=1, center=True).mean() y = gdf['delta'] if ctx['opt'] == 'no' else gdf['delta'].cumsum() ax.plot(gdf.index.values, y, label='Average', zorder=6, lw=2, color='k', linestyle='-.') # Plot selected year for i in range(1, 5): year = ctx.get("y%s" % (i, )) if year is None: continue df2 = df[df['year'] == year] if not df2.empty: gdf = df2.groupby('doy').mean().rolling(ctx['smooth'], min_periods=1, center=True).mean() y = gdf['delta'] if ctx['opt'] == 'no' else gdf['delta'].cumsum() ax.plot(gdf.index.values, y, label=str(year), lw=2, zorder=10) ax.set_xticks((1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 365)) ax.set_xticklabels(calendar.month_abbr[1:]) ax.set_xlim(1, 366) ax.grid(True) ax.legend(loc='best', ncol=5) sts = datetime.datetime(2000, 6, 1, h1) ets = datetime.datetime(2000, 6, 1, h2) title = ("%s [%s] %s Difference (%.0f-%.0f)\n" "%s minus %s (%s) (timezone: %s)") % ( ctx['_nt'].sts[station]['name'], station, PDICT[varname], df['year'].min(), df['year'].max(), ets.strftime("%-I %p"), sts.strftime("%-I %p"), "same day" if h2 > h1 else "previous day", tzname) fitbox(fig, title, 0.05, 0.95, 0.91, 0.99, ha='center') return fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn('asos') ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] network = ctx['network'] month = ctx['month'] nt = NetworkTable(network) if month == 'all': months = range(1, 13) elif month == 'fall': months = [9, 10, 11] elif month == 'winter': months = [12, 1, 2] elif month == 'spring': months = [3, 4, 5] elif month == 'summer': months = [6, 7, 8] else: ts = datetime.datetime.strptime("2000-" + month + "-01", '%Y-%b-%d') # make sure it is length two for the trick below in SQL months = [ts.month, 999] df = read_sql(""" SELECT drct::int as t, dwpf, tmpf, relh, coalesce(mslp, alti * 33.8639, 1013.25) as slp from alldata where station = %s and drct is not null and dwpf is not null and dwpf <= tmpf and sknt > 3 and drct::int %% 10 = 0 and extract(month from valid) in %s and report_type = 2 """, pgconn, params=(station, tuple(months))) # Convert sea level pressure to station pressure df['pressure'] = mcalc.add_height_to_pressure( df['slp'].values * units('millibars'), nt.sts[station]['elevation'] * units('m')).to(units('millibar')) # compute mixing ratio df['mixingratio'] = mcalc.mixing_ratio_from_relative_humidity( df['relh'].values * units('percent'), df['tmpf'].values * units('degF'), df['pressure'].values * units('millibars')) # compute pressure df['vapor_pressure'] = mcalc.vapor_pressure( df['pressure'].values * units('millibars'), df['mixingratio'].values * units('kg/kg')).to(units('kPa')) means = df.groupby('t').mean().copy() # compute dewpoint now means['dwpf'] = mcalc.dewpoint(means['vapor_pressure'].values * units('kPa')).to(units('degF')).m (fig, ax) = plt.subplots(1, 1) ax.bar(means.index.values, means['dwpf'].values, ec='green', fc='green', width=10, align='center') ax.grid(True, zorder=11) ax.set_title(("%s [%s]\nAverage Dew Point by Wind Direction (month=%s) " "(%s-%s)\n" "(must have 3+ hourly obs > 3 knots at given direction)") % (nt.sts[station]['name'], station, month.upper(), max([1973, nt.sts[station]['archive_begin'].year ]), datetime.datetime.now().year), size=10) ax.set_ylabel("Dew Point [F]") ax.set_ylim(means['dwpf'].min() - 5, means['dwpf'].max() + 5) ax.set_xlim(-5, 365) ax.set_xticks([0, 45, 90, 135, 180, 225, 270, 315, 360]) ax.set_xticklabels(['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N']) ax.set_xlabel("Wind Direction") return fig, means['dwpf']
def plotter(fdict): """ Go """ pgconn = get_dbconn("asos") ctx = get_autoplot_context(fdict, get_description()) station = ctx["zstation"] h1 = int(ctx["h1"]) h2 = int(ctx["h2"]) varname = ctx["v"] tzname = ctx["_nt"].sts[station]["tzname"] df = read_sql( """ WITH data as ( SELECT valid at time zone %s + '10 minutes'::interval as localvalid, date_trunc( 'hour', valid at time zone %s + '10 minutes'::interval) as v, tmpf, dwpf, sknt, drct, alti, relh, random() as r, coalesce(mslp, alti * 33.8639, 1013.25) as slp from alldata where station = %s and report_type = 2 and extract(hour from valid at time zone %s + '10 minutes'::interval) in (%s, %s)), agg as ( select *, extract(hour from v) as hour, rank() OVER (PARTITION by v ORDER by localvalid ASC, r ASC) from data ) SELECT *, date( case when hour = %s then date(v - '1 day'::interval) else date(v) end) from agg WHERE rank = 1 """, pgconn, params=( tzname, tzname, station, tzname, h1, h2, h2 if h2 < h1 else -1, ), index_col=None, ) if df.empty: raise NoDataFound("No data was found.") if varname == "q": df["pressure"] = mcalc.add_height_to_pressure( df["slp"].values * units("millibars"), ctx["_nt"].sts[station]["elevation"] * units("m"), ).to(units("millibar")) # compute mixing ratio df["q"] = (mcalc.mixing_ratio_from_relative_humidity( df["relh"].values * units("percent"), df["tmpf"].values * units("degF"), df["pressure"].values * units("millibars"), ) * 1000.0) # pivot df = df.pivot(index="date", columns="hour", values=varname).reset_index() df = df.dropna() df["doy"] = pd.to_numeric(pd.to_datetime(df["date"]).dt.strftime("%j")) df["year"] = pd.to_datetime(df["date"]).dt.year df["week"] = (df["doy"] / 7).astype(int) df["delta"] = df[h2] - df[h1] (fig, ax) = plt.subplots(1, 1) if ctx["opt"] == "no": ax.set_xlabel("Plotted lines are smoothed over %.0f days" % (ctx["smooth"], )) ax.set_ylabel( "%s %s Difference" % (PDICT[varname], "Accumulated Sum" if ctx["opt"] == "yes" else "")) if ctx["opt"] == "no": # Histogram H, xedges, yedges = np.histogram2d(df["doy"].values, df["delta"].values, bins=(50, 50)) ax.pcolormesh( xedges, yedges, H.transpose(), cmap=get_cmap(ctx["cmap"]), alpha=0.5, ) # Plot an average line gdf = (df.groupby("doy").mean().rolling(ctx["smooth"], min_periods=1, center=True).mean()) y = gdf["delta"] if ctx["opt"] == "no" else gdf["delta"].cumsum() ax.plot( gdf.index.values, y, label="Average", zorder=6, lw=2, color="k", linestyle="-.", ) # Plot selected year for i in range(1, 5): year = ctx.get("y%s" % (i, )) if year is None: continue df2 = df[df["year"] == year] if not df2.empty: gdf = (df2.groupby("doy").mean().rolling(ctx["smooth"], min_periods=1, center=True).mean()) y = gdf["delta"] if ctx["opt"] == "no" else gdf["delta"].cumsum() ax.plot(gdf.index.values, y, label=str(year), lw=2, zorder=10) ax.set_xticks((1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335)) ax.set_xticklabels(calendar.month_abbr[1:]) ax.set_xlim(1, 366) ax.grid(True) ax.legend(loc="best", ncol=5) sts = datetime.datetime(2000, 6, 1, h1) ets = datetime.datetime(2000, 6, 1, h2) title = ("%s [%s] %s Difference (%.0f-%.0f)\n" "%s minus %s (%s) (timezone: %s)") % ( ctx["_nt"].sts[station]["name"], station, PDICT[varname], df["year"].min(), df["year"].max(), ets.strftime("%-I %p"), sts.strftime("%-I %p"), "same day" if h2 > h1 else "previous day", tzname, ) fitbox(fig, title, 0.05, 0.95, 0.91, 0.99, ha="center") return fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn("asos") ctx = get_autoplot_context(fdict, get_description()) station = ctx["zstation"] month = ctx["month"] if month == "all": months = range(1, 13) elif month == "fall": months = [9, 10, 11] elif month == "winter": months = [12, 1, 2] elif month == "spring": months = [3, 4, 5] elif month == "summer": months = [6, 7, 8] else: ts = datetime.datetime.strptime("2000-" + month + "-01", "%Y-%b-%d") # make sure it is length two for the trick below in SQL months = [ts.month, 999] df = read_sql( """ SELECT tmpf::int as tmpf, dwpf, relh, coalesce(mslp, alti * 33.8639, 1013.25) as slp from alldata where station = %s and drct is not null and dwpf is not null and dwpf <= tmpf and sknt > 3 and drct::int %% 10 = 0 and extract(month from valid) in %s and report_type = 2 """, pgconn, params=(station, tuple(months)), ) if df.empty: raise NoDataFound("No Data Found.") # Convert sea level pressure to station pressure df["pressure"] = mcalc.add_height_to_pressure( df["slp"].values * units("millibars"), ctx["_nt"].sts[station]["elevation"] * units("m"), ).to(units("millibar")) # compute mixing ratio df["mixingratio"] = mcalc.mixing_ratio_from_relative_humidity( df["relh"].values * units("percent"), df["tmpf"].values * units("degF"), df["pressure"].values * units("millibars"), ) # compute pressure df["vapor_pressure"] = mcalc.vapor_pressure( df["pressure"].values * units("millibars"), df["mixingratio"].values * units("kg/kg"), ).to(units("kPa")) means = df.groupby("tmpf").mean().copy() # compute dewpoint now means["dwpf"] = ( mcalc.dewpoint(means["vapor_pressure"].values * units("kPa")) .to(units("degF")) .m ) means.reset_index(inplace=True) # compute RH again means["relh"] = ( mcalc.relative_humidity_from_dewpoint( means["tmpf"].values * units("degF"), means["dwpf"].values * units("degF"), ) * 100.0 ) (fig, ax) = plt.subplots(1, 1, figsize=(8, 6)) ax.bar( means["tmpf"].values - 0.5, means["dwpf"].values - 0.5, ec="green", fc="green", width=1, ) ax.grid(True, zorder=11) ab = ctx["_nt"].sts[station]["archive_begin"] if ab is None: raise NoDataFound("Unknown station metadata.") ax.set_title( ( "%s [%s]\nAverage Dew Point by Air Temperature (month=%s) " "(%s-%s)\n" "(must have 3+ hourly observations at the given temperature)" ) % ( ctx["_nt"].sts[station]["name"], station, month.upper(), ab.year, datetime.datetime.now().year, ), size=10, ) ax.plot([0, 140], [0, 140], color="b") ax.set_ylabel("Dew Point [F]") y2 = ax.twinx() y2.plot(means["tmpf"].values, means["relh"].values, color="k") y2.set_ylabel("Relative Humidity [%] (black line)") y2.set_yticks([0, 5, 10, 25, 50, 75, 90, 95, 100]) y2.set_ylim(0, 100) ax.set_ylim(0, means["tmpf"].max() + 2) ax.set_xlim(0, means["tmpf"].max() + 2) ax.set_xlabel(r"Air Temperature $^\circ$F") return fig, means[["tmpf", "dwpf", "relh"]]
def plotter(fdict): """ Go """ pgconn = get_dbconn('asos') ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] network = ctx['network'] month = ctx['month'] nt = NetworkTable(network) if month == 'all': months = range(1, 13) elif month == 'fall': months = [9, 10, 11] elif month == 'winter': months = [12, 1, 2] elif month == 'spring': months = [3, 4, 5] elif month == 'summer': months = [6, 7, 8] else: ts = datetime.datetime.strptime("2000-"+month+"-01", '%Y-%b-%d') # make sure it is length two for the trick below in SQL months = [ts.month, 999] df = read_sql(""" SELECT tmpf::int as tmpf, dwpf, coalesce(mslp, alti * 33.8639, 1013.25) as slp from alldata where station = %s and drct is not null and dwpf is not null and dwpf <= tmpf and sknt > 3 and drct::int %% 10 = 0 and extract(month from valid) in %s and report_type = 2 """, pgconn, params=(station, tuple(months))) # Convert sea level pressure to station pressure df['pressure'] = mcalc.add_height_to_pressure( df['slp'].values * units('millibars'), nt.sts[station]['elevation'] * units('m') ).to(units('millibar')) # compute RH df['relh'] = mcalc.relative_humidity_from_dewpoint( df['tmpf'].values * units('degF'), df['dwpf'].values * units('degF') ) # compute mixing ratio df['mixingratio'] = mcalc.mixing_ratio_from_relative_humidity( df['relh'].values, df['tmpf'].values * units('degF'), df['pressure'].values * units('millibars') ) # compute pressure df['vapor_pressure'] = mcalc.vapor_pressure( df['pressure'].values * units('millibars'), df['mixingratio'].values * units('kg/kg') ).to(units('kPa')) means = df.groupby('tmpf').mean().copy() # compute dewpoint now means['dwpf'] = mcalc.dewpoint( means['vapor_pressure'].values * units('kPa') ).to(units('degF')).m means.reset_index(inplace=True) # compute RH again means['relh'] = mcalc.relative_humidity_from_dewpoint( means['tmpf'].values * units('degF'), means['dwpf'].values * units('degF') ) * 100. (fig, ax) = plt.subplots(1, 1, figsize=(8, 6)) ax.bar( means['tmpf'].values - 0.5, means['dwpf'].values - 0.5, ec='green', fc='green', width=1 ) ax.grid(True, zorder=11) ax.set_title(("%s [%s]\nAverage Dew Point by Air Temperature (month=%s) " "(%s-%s)\n" "(must have 3+ hourly observations at the given temperature)" ) % (nt.sts[station]['name'], station, month.upper(), nt.sts[station]['archive_begin'].year, datetime.datetime.now().year), size=10) ax.plot([0, 140], [0, 140], color='b') ax.set_ylabel("Dew Point [F]") y2 = ax.twinx() y2.plot(means['tmpf'].values, means['relh'].values, color='k') y2.set_ylabel("Relative Humidity [%] (black line)") y2.set_yticks([0, 5, 10, 25, 50, 75, 90, 95, 100]) y2.set_ylim(0, 100) ax.set_ylim(0, means['tmpf'].max() + 2) ax.set_xlim(0, means['tmpf'].max() + 2) ax.set_xlabel(r"Air Temperature $^\circ$F") return fig, means[['tmpf', 'dwpf', 'relh']]