Exemple #1
0
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']))
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
 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)
Exemple #9
0
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
Exemple #10
0
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
Exemple #11
0
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
Exemple #12
0
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
Exemple #13
0
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
Exemple #14
0
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
Exemple #15
0
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
Exemple #16
0
 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)