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