def main(): """Go Main Go""" pgconn = get_dbconn('scan') for station in ['S2004', 'S2196', 'S2002', 'S2072', 'S2068', 'S2031', 'S2001', 'S2047']: df = read_sql(""" select extract(year from valid + '2 months'::interval) as wy, tmpf, dwpf from alldata where station = %s and tmpf is not null and dwpf is not null """, pgconn, params=(station, ), index_col=None) df['mixingratio'] = meteorology.mixing_ratio( temperature(df['dwpf'].values, 'F')).value('KG/KG') df['vapor_pressure'] = mcalc.vapor_pressure( 1000. * units.mbar, df['mixingratio'].values * units('kg/kg')).to(units('kPa')) df['saturation_mixingratio'] = ( meteorology.mixing_ratio( temperature(df['tmpf'].values, 'F')).value('KG/KG')) df['saturation_vapor_pressure'] = mcalc.vapor_pressure( 1000. * units.mbar, df['saturation_mixingratio'].values * units('kg/kg')).to(units('kPa')) df['vpd'] = df['saturation_vapor_pressure'] - df['vapor_pressure'] means = df.groupby('wy').mean() counts = df.groupby('wy').count() for yr, row in means.iterrows(): print(("%s,%s,%.0f,%.3f" ) % (yr, station, counts.at[yr, 'vpd'], row['vpd']))
def run_calcs(df): """Do our maths""" df['mixingratio'] = meteorology.mixing_ratio( temperature(df['dwpf'].values, 'F')).value('KG/KG') df['vapor_pressure'] = mcalc.vapor_pressure( 1000. * units.mbar, df['mixingratio'].values * units('kg/kg')).to(units('kPa')) df['saturation_mixingratio'] = (meteorology.mixing_ratio( temperature(df['tmpf'].values, 'F')).value('KG/KG')) df['saturation_vapor_pressure'] = mcalc.vapor_pressure( 1000. * units.mbar, 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'] = meteorology.dewpoint_from_pq( pressure(1000, 'MB'), mixingratio(df['mixingratio'].values, 'KG/KG')).value('F') return df
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') station = fdict.get('zstation', 'AMW') network = fdict.get('network', 'IA_ASOS') nt = NetworkTable(network) year = int(fdict.get('year', 2015)) df = read_sql(""" SELECT extract(year from valid) as year, extract(doy from valid) as doy, dwpf from alldata where station = %s and dwpf > -50 and dwpf < 90 and tmpf > -50 and tmpf < 120 and valid > '1950-01-01' """, pgconn, params=(station,), index_col=None) df['mixing_ratio'] = mixing_ratio( temperature(df['dwpf'].values, 'F')).value('KG/KG') df2 = df[['doy', 'mixing_ratio']].groupby('doy').describe() df2 = df2.unstack(level=-1) dyear = df[df['year'] == year] df3 = dyear[['doy', 'mixing_ratio']].groupby('doy').describe() df3 = df3.unstack(level=-1) df3['diff'] = df3[('mixing_ratio', 'mean')] - df2[('mixing_ratio', 'mean')] (fig, ax) = plt.subplots(2, 1) ax[0].fill_between(df2.index.values, df2[('mixing_ratio', 'min')] * 1000., df2[('mixing_ratio', 'max')] * 1000., color='gray') ax[0].plot(df2.index.values, df2[('mixing_ratio', 'mean')] * 1000., label="Climatology") ax[0].plot(df3.index.values, df3[('mixing_ratio', 'mean')] * 1000., color='r', label="%s" % (year, )) ax[0].set_title(("%s [%s]\nDaily Mean Surface Water Vapor Mixing Ratio" ) % (station, nt.sts[station]['name'])) ax[0].set_ylabel("Mixing Ratio ($g/kg$)") ax[0].set_xlim(0, 366) # ax[0].set_ylim(0, 26.) 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) rects = ax[1].bar(df3.index.values, df3['diff'] * 1000.0, edgecolor='b') for rect in rects: if rect.get_y() < 0.: rect.set_facecolor('r') rect.set_edgecolor('r') else: rect.set_facecolor('b') ax[1].set_ylabel("%.0f Departure ($g/kg$)" % (year, )) 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 """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] network = ctx['network'] nt = NetworkTable(network) year = ctx['year'] varname = ctx['var'] _ = PDICT[varname] df = read_sql(""" SELECT extract(year from valid) as year, 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) df['relh'] = relh(temperature(df['tmpf'].values, 'F'), temperature(df['dwpf'].values, 'F')).value('%') df['tmpc'] = temperature(df['tmpf'].values, 'F').value('C') df['svp'] = 0.611 * np.exp(17.502 * df['tmpc'].values / (240.97 + df['tmpc'].values)) df['vpd'] = (1. - (df['relh'] / 100.)) * df['svp'] df['mixing_ratio'] = mixing_ratio( temperature(df['dwpf'].values, 'F')).value('KG/KG') 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) units = '$g/kg$' if varname == 'mixing_ratio' else 'hPa' ax[1].set_ylabel("%.0f Departure (%s)" % (year, units)) 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 """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') cursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor) 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] cursor.execute(""" SELECT tmpf::int as t, dwpf from alldata where station = %s and tmpf is not null and dwpf is not null and dwpf <= tmpf and tmpf >= 0 and tmpf <= 140 and extract(month from valid) in %s """, (station, tuple(months))) sums = np.zeros((140,), 'f') counts = np.zeros((140,), 'f') for row in cursor: r = mixing_ratio(temperature(row[1], 'F')).value('KG/KG') sums[row[0]] += r counts[row[0]] += 1 rows = [] for i in range(140): if counts[i] < 3: continue r = sums[i] / float(counts[i]) d = dewpoint_from_pq(pressure(1000, 'MB'), mixingratio(r, 'KG/KG') ).value('F') rh = relh(temperature(i, 'F'), temperature(d, 'F')).value('%') rows.append(dict(tmpf=i, dwpf=d, rh=rh)) df = pd.DataFrame(rows) tmpf = df['tmpf'] dwpf = df['dwpf'] rh = df['rh'] (fig, ax) = plt.subplots(1, 1, figsize=(8, 6)) ax.bar(tmpf-0.5, dwpf, 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(tmpf, rh, 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, max(tmpf)+2) ax.set_xlim(0, max(tmpf)+2) ax.set_xlabel("Air Temperature $^\circ$F") return fig, df
def test_mixingratio(): """Test the mixing ratio calculation""" r = meteorology.mixing_ratio(datatypes.temperature(70, "F")) assert abs(r.value("KG/KG") - 0.016) < 0.001
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') cursor = pgconn.cursor() station = fdict.get('station', 'DSM') network = fdict.get('network', 'IA_ASOS') season = fdict.get('season', 'winter') _ = MDICT[season] startyear = int(fdict.get('year', 1893)) nt = NetworkTable(network) today = datetime.datetime.now() lastyear = today.year if season == 'all': months = range(1, 13) elif season == 'spring': months = [3, 4, 5] if today.month > 5: lastyear += 1 elif season == 'fall': months = [9, 10, 11] if today.month > 11: lastyear += 1 elif season == 'summer': months = [6, 7, 8] if today.month > 8: lastyear += 1 elif season == 'winter': months = [12, 1, 2] if today.month > 2: lastyear += 1 else: ts = datetime.datetime.strptime("2000-" + season + "-01", '%Y-%b-%d') # make sure it is length two for the trick below in SQL months = [ts.month, 999] lastyear += 1 cursor.execute( """ SELECT valid, dwpf from alldata where station = %s and dwpf > -90 and dwpf < 100 and extract(month from valid) in %s """, (station, tuple(months))) rows = [] for row in cursor: if (row[0].month not in months or row[0].year < startyear or row[0].year >= lastyear): continue yr = (row[0] + datetime.timedelta(days=31)).year r = meteorology.mixing_ratio(temperature(row[1], 'F')).value('KG/KG') rows.append(dict(year=yr, r=r)) df = pd.DataFrame(rows) group = df.groupby('year') df = group.aggregate(np.average) def to_dwpf(val): return meteorology.dewpoint_from_pq(pressure(1000, 'MB'), mixingratio(val, 'KG/KG')).value('F') df['r'] = df['r'].apply(to_dwpf) data = np.array(df['r']) years = np.array(df.index.astype('i')) (fig, ax) = plt.subplots(1, 1) avgv = np.average(data) colorabove = 'seagreen' colorbelow = 'lightsalmon' bars = ax.bar(years - 0.4, data, fc=colorabove, ec=colorabove) for i, bar in enumerate(bars): if data[i] < avgv: bar.set_facecolor(colorbelow) bar.set_edgecolor(colorbelow) ax.axhline(avgv, lw=2, color='k', zorder=2, label='Average') h_slope, intercept, r_value, _, _ = stats.linregress(years, data) ax.plot(years, h_slope * np.array(years) + intercept, '--', lw=2, color='k', label='Trend') ax.text(0.01, 0.99, "Avg: %.1f, slope: %.2f F/century, R$^2$=%.2f" % (avgv, h_slope * 100., r_value**2), transform=ax.transAxes, va='top', bbox=dict(color='white')) ax.set_xlabel("Year") ax.set_xlim(min(years) - 1, max(years) + 1) ax.set_ylim(min(data) - 5, max(data) + max(data) / 10.) ax.set_ylabel("Average Dew Point [F]") ax.grid(True) msg = ("[%s] %s %.0f-%.0f Average Dew Point [%s] ") % ( station, nt.sts[station]['name'], min(years), max(years), MDICT[season]) tokens = msg.split() sz = len(tokens) / 2 ax.set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:])) ax.legend(ncol=1) return fig, df
def test_mixingratio(self): """Test the mixing ratio calculation""" r = meteorology.mixing_ratio(datatypes.temperature(70, 'F')) self.assertAlmostEquals(r.value('KG/KG'), 0.016, 3)
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') cursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor) 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] cursor.execute( """ SELECT drct::int as t, dwpf 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 """, (station, tuple(months))) sums = np.zeros((361, ), 'f') counts = np.zeros((361, ), 'f') for row in cursor: r = mixing_ratio(temperature(row[1], 'F')).value('KG/KG') sums[row[0]] += r counts[row[0]] += 1 sums[0] = sums[360] counts[0] = counts[360] rows = [] for i in range(361): if counts[i] < 3: continue r = sums[i] / float(counts[i]) d = dewpoint_from_pq(pressure(1000, 'MB'), mixingratio(r, 'KG/KG')).value('F') rows.append(dict(drct=i, dwpf=d)) df = pd.DataFrame(rows) drct = df['drct'] dwpf = df['dwpf'] (fig, ax) = plt.subplots(1, 1) ax.bar(drct, dwpf, 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(min(dwpf) - 5, max(dwpf) + 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, df
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') station = fdict.get('zstation', 'AMW') network = fdict.get('network', 'IA_ASOS') nt = NetworkTable(network) year = int(fdict.get('year', 2015)) varname = fdict.get('var', 'mixing_ratio') _ = PDICT[varname] df = read_sql(""" SELECT extract(year from valid) as year, 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) df['relh'] = relh(temperature(df['tmpf'].values, 'F'), temperature(df['dwpf'].values, 'F')).value('%') df['tmpc'] = temperature(df['tmpf'].values, 'F').value('C') df['svp'] = 0.611 * np.exp(17.502 * df['tmpc'].values / (240.97 + df['tmpc'].values)) df['vpd'] = (1. - (df['relh'] / 100.)) * df['svp'] df['mixing_ratio'] = mixing_ratio( temperature(df['dwpf'].values, 'F')).value('KG/KG') dailymeans = df[['year', 'doy', varname]].groupby(['year', 'doy']).mean() dailymeans = dailymeans.reset_index() df2 = dailymeans[['doy', varname]].groupby('doy').describe() df2 = df2.unstack(level=-1) dyear = df[df['year'] == year] df3 = dyear[['doy', varname]].groupby('doy').describe() df3 = df3.unstack(level=-1) df3['diff'] = df3[(varname, 'mean')] - df2[(varname, 'mean')] (fig, ax) = plt.subplots(2, 1) multiplier = 1000. if varname == 'mixing_ratio' else 10. ax[0].fill_between(df2.index.values, df2[(varname, 'min')] * multiplier, df2[(varname, 'max')] * multiplier, color='gray') ax[0].plot(df2.index.values, df2[(varname, 'mean')] * multiplier, label="Climatology") ax[0].plot(df3.index.values, df3[(varname, 'mean')] * 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.index.values, df3['diff'] * multiplier, facecolor=cabove, edgecolor=cabove) for rect in rects: if rect.get_y() < 0.: rect.set_facecolor(cbelow) rect.set_edgecolor(cbelow) units = '$g/kg$' if varname == 'mixing_ratio' else 'hPa' ax[1].set_ylabel("%.0f Departure (%s)" % (year, units)) 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 """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') cursor = pgconn.cursor() station = fdict.get('station', 'DSM') network = fdict.get('network', 'IA_ASOS') season = fdict.get('season', 'winter') _ = MDICT[season] startyear = int(fdict.get('year', 1893)) nt = NetworkTable(network) today = datetime.datetime.now() lastyear = today.year if season == 'all': months = range(1, 13) elif season == 'spring': months = [3, 4, 5] if today.month > 5: lastyear += 1 elif season == 'fall': months = [9, 10, 11] if today.month > 11: lastyear += 1 elif season == 'summer': months = [6, 7, 8] if today.month > 8: lastyear += 1 elif season == 'winter': months = [12, 1, 2] if today.month > 2: lastyear += 1 else: ts = datetime.datetime.strptime("2000-"+season+"-01", '%Y-%b-%d') # make sure it is length two for the trick below in SQL months = [ts.month, 999] lastyear += 1 cursor.execute(""" SELECT valid, dwpf from alldata where station = %s and dwpf > -90 and dwpf < 100 and extract(month from valid) in %s """, (station, tuple(months))) rows = [] for row in cursor: if (row[0].month not in months or row[0].year < startyear or row[0].year >= lastyear): continue yr = (row[0] + datetime.timedelta(days=31)).year r = meteorology.mixing_ratio(temperature(row[1], 'F')).value('KG/KG') rows.append(dict(year=yr, r=r)) df = pd.DataFrame(rows) group = df.groupby('year') df = group.aggregate(np.average) def to_dwpf(val): return meteorology.dewpoint_from_pq(pressure(1000, 'MB'), mixingratio(val, 'KG/KG') ).value('F') df['r'] = df['r'].apply(to_dwpf) data = np.array(df['r']) years = np.array(df.index.astype('i')) (fig, ax) = plt.subplots(1, 1) avgv = np.average(data) colorabove = 'seagreen' colorbelow = 'lightsalmon' bars = ax.bar(years - 0.4, data, fc=colorabove, ec=colorabove) for i, bar in enumerate(bars): if data[i] < avgv: bar.set_facecolor(colorbelow) bar.set_edgecolor(colorbelow) ax.axhline(avgv, lw=2, color='k', zorder=2, label='Average') h_slope, intercept, r_value, _, _ = stats.linregress(years, data) ax.plot(years, h_slope * np.array(years) + intercept, '--', lw=2, color='k', label='Trend') ax.text(0.01, 0.99, "Avg: %.1f, slope: %.2f F/century, R$^2$=%.2f" % ( avgv, h_slope * 100., r_value ** 2), transform=ax.transAxes, va='top', bbox=dict(color='white')) ax.set_xlabel("Year") ax.set_xlim(min(years)-1, max(years)+1) ax.set_ylim(min(data)-5, max(data) + max(data)/10.) ax.set_ylabel("Average Dew Point [F]") ax.grid(True) msg = ("[%s] %s %.0f-%.0f Average Dew Point [%s] " ) % (station, nt.sts[station]['name'], min(years), max(years), MDICT[season]) tokens = msg.split() sz = len(tokens) / 2 ax.set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:])) ax.legend(ncol=1) return fig, df
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt ASOS = psycopg2.connect(database='asos', host='iemdb', user='******') cursor = ASOS.cursor(cursor_factory=psycopg2.extras.DictCursor) station = fdict.get('zstation', 'AMW') network = fdict.get('network', 'IA_ASOS') month = fdict.get('month', 'all') 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] cursor.execute(""" SELECT drct::int as t, dwpf 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 """, (station, tuple(months))) sums = np.zeros((361,), 'f') counts = np.zeros((361,), 'f') for row in cursor: r = mixing_ratio(temperature(row[1], 'F')).value('KG/KG') sums[row[0]] += r counts[row[0]] += 1 sums[0] = sums[360] counts[0] = counts[360] rows = [] for i in range(361): if counts[i] < 3: continue r = sums[i] / float(counts[i]) d = dewpoint_from_pq(pressure(1000, 'MB'), mixingratio(r, 'KG/KG') ).value('F') rows.append(dict(drct=i, dwpf=d)) df = pd.DataFrame(rows) drct = df['drct'] dwpf = df['dwpf'] (fig, ax) = plt.subplots(1, 1) ax.bar(drct-5, dwpf, ec='green', fc='green', width=10) 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(min(dwpf)-5, max(dwpf)+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, df
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') cursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor) station = fdict.get('zstation', 'AMW') network = fdict.get('network', 'IA_ASOS') month = fdict.get('month', 'all') 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] cursor.execute(""" SELECT tmpf::int as t, dwpf from alldata where station = %s and tmpf is not null and dwpf is not null and dwpf <= tmpf and tmpf >= 0 and tmpf <= 140 and extract(month from valid) in %s """, (station, tuple(months))) sums = np.zeros((140,), 'f') counts = np.zeros((140,), 'f') for row in cursor: r = mixing_ratio(temperature(row[1], 'F')).value('KG/KG') sums[row[0]] += r counts[row[0]] += 1 rows = [] for i in range(140): if counts[i] < 3: continue r = sums[i] / float(counts[i]) d = dewpoint_from_pq(pressure(1000, 'MB'), mixingratio(r, 'KG/KG') ).value('F') rh = relh(temperature(i, 'F'), temperature(d, 'F')).value('%') rows.append(dict(tmpf=i, dwpf=d, rh=rh)) df = pd.DataFrame(rows) tmpf = df['tmpf'] dwpf = df['dwpf'] rh = df['rh'] (fig, ax) = plt.subplots(1, 1) ax.bar(tmpf-0.5, dwpf, 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(tmpf, rh, 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, max(tmpf)+2) ax.set_xlim(0, max(tmpf)+2) ax.set_xlabel("Air Temperature $^\circ$F") return fig, df
def test_mixingratio(): """Test the mixing ratio calculation""" r = meteorology.mixing_ratio(datatypes.temperature(70, 'F')) assert abs(r.value('KG/KG') - 0.016) < 0.001
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') station = fdict.get('zstation', 'AMW') network = fdict.get('network', 'IA_ASOS') nt = NetworkTable(network) year = int(fdict.get('year', 2015)) df = read_sql(""" SELECT extract(year from valid) as year, extract(doy from valid) as doy, dwpf from alldata where station = %s and dwpf > -50 and dwpf < 90 and tmpf > -50 and tmpf < 120 and valid > '1950-01-01' """, pgconn, params=(station, ), index_col=None) df['mixing_ratio'] = mixing_ratio(temperature(df['dwpf'].values, 'F')).value('KG/KG') df2 = df[['doy', 'mixing_ratio']].groupby('doy').describe() df2 = df2.unstack(level=-1) dyear = df[df['year'] == year] df3 = dyear[['doy', 'mixing_ratio']].groupby('doy').describe() df3 = df3.unstack(level=-1) df3['diff'] = df3[('mixing_ratio', 'mean')] - df2[('mixing_ratio', 'mean')] (fig, ax) = plt.subplots(2, 1) ax[0].fill_between(df2.index.values, df2[('mixing_ratio', 'min')] * 1000., df2[('mixing_ratio', 'max')] * 1000., color='gray') ax[0].plot(df2.index.values, df2[('mixing_ratio', 'mean')] * 1000., label="Climatology") ax[0].plot(df3.index.values, df3[('mixing_ratio', 'mean')] * 1000., color='r', label="%s" % (year, )) ax[0].set_title(("%s [%s]\nDaily Mean Surface Water Vapor Mixing Ratio") % (station, nt.sts[station]['name'])) ax[0].set_ylabel("Mixing Ratio ($g/kg$)") ax[0].set_xlim(0, 366) # ax[0].set_ylim(0, 26.) 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) rects = ax[1].bar(df3.index.values, df3['diff'] * 1000.0, edgecolor='b') for rect in rects: if rect.get_y() < 0.: rect.set_facecolor('r') rect.set_edgecolor('r') else: rect.set_facecolor('b') ax[1].set_ylabel("%.0f Departure ($g/kg$)" % (year, )) 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