Beispiel #1
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn("coop")
    ccursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx["station"]
    lagmonths = ctx["lag"]
    months = ctx["months"]
    month = ctx["month"]
    highyears = [int(x) for x in ctx["year"].split(",")]
    h = ctx["h"]

    wantmonth = month + lagmonths
    yearoffset = 0
    if month + lagmonths < 1:
        wantmonth = 12 - (month + lagmonths)
        yearoffset = 1

    wanted = []
    deltas = []
    for m in range(month, month + months):
        if m < 13:
            wanted.append(m)
            deltas.append(0)
        else:
            wanted.append(m - 12)
            deltas.append(-1)

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    elnino = {}
    ccursor.execute("""SELECT monthdate, soi_3m, anom_34 from elnino""")
    for row in ccursor:
        if row[0].month != wantmonth:
            continue
        elnino[row[0].year + yearoffset] = dict(soi_3m=row[1], anom_34=row[2])

    ccursor.execute(
        "SELECT year, month, sum(precip), avg((high+low)/2.) "
        f"from {table} where station = %s GROUP by year, month",
        (station, ),
    )
    if ccursor.rowcount == 0:
        raise NoDataFound("No Data Found.")
    yearly = {}
    for row in ccursor:
        (_year, _month, _precip, _temp) = row
        if _month not in wanted:
            continue
        effectiveyear = _year + deltas[wanted.index(_month)]
        nino = elnino.get(effectiveyear, {}).get("soi_3m", None)
        if nino is None:
            continue
        data = yearly.setdefault(effectiveyear,
                                 dict(precip=0, temp=[], nino=nino))
        data["precip"] += _precip
        data["temp"].append(float(_temp))

    fig = plt.figure(figsize=(10, 6))
    ax = plt.axes([0.1, 0.12, 0.5, 0.75])
    msg = ("[%s] %s\n%s\n%s SOI (3 month average)") % (
        station,
        nt.sts[station]["name"],
        title(wanted),
        datetime.date(2000, wantmonth, 1).strftime("%B"),
    )
    ax.set_title(msg)

    cmap = get_cmap(ctx["cmap"])
    zdata = np.arange(-2.0, 2.1, 0.5)
    norm = mpcolors.BoundaryNorm(zdata, cmap.N)
    rows = []
    xs = []
    ys = []
    for year in yearly:
        x = yearly[year]["precip"]
        y = np.average(yearly[year]["temp"])
        xs.append(x)
        ys.append(y)
        val = yearly[year]["nino"]
        c = cmap(norm([val])[0])
        if h == "hide" and val > -0.5 and val < 0.5:
            ax.scatter(
                x,
                y,
                facecolor="#EEEEEE",
                edgecolor="#EEEEEE",
                s=30,
                zorder=2,
                marker="s",
            )
        else:
            ax.scatter(x,
                       y,
                       facecolor=c,
                       edgecolor="k",
                       s=60,
                       zorder=3,
                       marker="o")
        if year in highyears:
            ax.text(x,
                    y + 0.2,
                    "%s" % (year, ),
                    ha="center",
                    va="bottom",
                    zorder=5)
        rows.append(dict(year=year, precip=x, tmpf=y, soi3m=val))

    ax.axhline(np.average(ys), lw=2, color="k", linestyle="-.", zorder=2)
    ax.axvline(np.average(xs), lw=2, color="k", linestyle="-.", zorder=2)

    sm = plt.cm.ScalarMappable(norm, cmap)
    sm.set_array(zdata)
    cb = plt.colorbar(sm, extend="both")
    cb.set_label("<-- El Nino :: SOI :: La Nina -->")

    ax.grid(True)
    ax.set_xlim(left=-0.01)
    ax.set_xlabel("Total Precipitation [inch], Avg: %.2f" % (np.average(xs), ))
    ax.set_ylabel((r"Average Temperature $^\circ$F, "
                   "Avg: %.1f") % (np.average(ys), ))
    df = pd.DataFrame(rows)
    ax2 = plt.axes([0.67, 0.6, 0.28, 0.35])
    ax2.scatter(df["soi3m"].values, df["tmpf"].values)
    ax2.set_xlabel("<-- El Nino :: SOI :: La Nina -->")
    ax2.set_ylabel(r"Avg Temp $^\circ$F")
    slp, intercept, r_value, _, _ = stats.linregress(df["soi3m"].values,
                                                     df["tmpf"].values)
    y1 = -2.0 * slp + intercept
    y2 = 2.0 * slp + intercept
    ax2.plot([-2, 2], [y1, y2])
    ax2.text(
        0.97,
        0.9,
        "R$^2$=%.2f" % (r_value**2, ),
        ha="right",
        transform=ax2.transAxes,
        bbox=dict(color="white"),
    )
    ax2.grid(True)

    ax3 = plt.axes([0.67, 0.1, 0.28, 0.35])
    ax3.scatter(df["soi3m"].values, df["precip"].values)
    ax3.set_xlabel("<-- El Nino :: SOI :: La Nina -->")
    ax3.set_ylabel("Total Precip [inch]")
    slp, intercept, r_value, _, _ = stats.linregress(df["soi3m"].values,
                                                     df["precip"].values)
    y1 = -2.0 * slp + intercept
    y2 = 2.0 * slp + intercept
    ax3.plot([-2, 2], [y1, y2])
    ax3.text(
        0.97,
        0.9,
        "R$^2$=%.2f" % (r_value**2, ),
        ha="right",
        transform=ax3.transAxes,
        bbox=dict(color="white"),
    )
    ax3.grid(True)

    return fig, df
Beispiel #2
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn('coop')
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    delta = ctx['delta']
    year = ctx['year']
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    table = "alldata_%s" % (station[:2], )
    df = read_sql("""
        WITH days as (
            select generate_series('%s-01-01'::date, '%s-12-31'::date,
                '1 day'::interval)::date as day,
                to_char(generate_series('%s-01-01'::date, '%s-12-31'::date,
                '1 day'::interval)::date, 'mmdd') as sday
        ),
        climo as (
            SELECT sday, avg(high) as avg_high, stddev(high) as stddev_high,
            avg(low) as avg_low, stddev(low) as stddev_low from """ + table +
                  """
            WHERE station = %s GROUP by sday
        ),
        thisyear as (
            SELECT day, sday, high, low from """ + table + """
            WHERE station = %s and year = %s
        ),
        thisyear2 as (
            SELECT d.day, d.sday, t.high, t.low from days d LEFT JOIN
            thisyear t on (d.sday = t.sday)
        )
        SELECT t.day, t.sday, t.high, t.low, c.avg_high, c.avg_low,
        c.stddev_high, c.stddev_low from thisyear2 t JOIN climo c on
        (t.sday = c.sday) ORDER by t.day ASC
    """,
                  pgconn,
                  params=(year, year, year, year, station, station, year),
                  index_col='day')
    if df.empty:
        raise NoDataFound("No Data Found.")
    df.index.name = 'Date'
    df['high_sigma'] = (df['high'] - df['avg_high']) / df['stddev_high']
    df['low_sigma'] = (df['low'] - df['avg_low']) / df['stddev_low']

    (fig, ax) = plt.subplots(2, 1, sharex=True, figsize=(8, 6))

    ax[0].plot(df.index.values,
               df['avg_high'].values,
               color='r',
               linestyle='-',
               label='Climate High')
    ax[0].plot(df.index.values,
               df['avg_low'].values,
               color='b',
               label='Climate Low')
    ax[0].set_ylabel(r"Temperature $^\circ\mathrm{F}$")
    ax[0].set_title("[%s] %s Climatology & %s Observations" %
                    (station, nt.sts[station]['name'], year))

    ax[0].plot(df.index.values,
               df['high'].values,
               color='brown',
               label='%s High' % (year, ))
    ax[0].plot(df.index.values,
               df['low'].values,
               color='green',
               label='%s Low' % (year, ))

    if delta == 'abs':
        ax[1].plot(df.index.values, (df.high - df.avg_high).values,
                   color='r',
                   label='High Diff %s - Climate' % (year))
        ax[1].plot(df.index.values, (df.low - df.avg_low).values,
                   color='b',
                   label='Low Diff')
        ax[1].set_ylabel(r"Temp Difference $^\circ\mathrm{F}$")
    else:
        ax[1].plot(df.index.values,
                   df.high_sigma.values,
                   color='r',
                   label='High Diff %s - Climate' % (year))
        ax[1].plot(df.index.values,
                   df.low_sigma.values,
                   color='b',
                   label='Low Diff')
        ax[1].set_ylabel(r"Temp Difference $\sigma$")
        ymax = max([df.high_sigma.abs().max(), df.low_sigma.abs().max()]) + 1
        ax[1].set_ylim(0 - ymax, ymax)
    ax[1].legend(fontsize=10, ncol=2, loc='best')
    ax[1].grid(True)

    ax[0].legend(fontsize=10, ncol=2, loc=8)
    ax[0].grid()
    ax[0].xaxis.set_major_locator(mdates.MonthLocator(interval=1))
    ax[0].xaxis.set_major_formatter(mdates.DateFormatter('%-d\n%b'))
    ax[0].set_xlim(df.index.min() - datetime.timedelta(days=3),
                   df.index.max() + datetime.timedelta(days=3))

    return fig, df
Beispiel #3
0
def get_context(fdict):
    """ Get the context"""
    pgconn = get_dbconn('coop')
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    month = ctx['month']
    ptype = ctx['type']
    threshold = ctx['threshold']

    table = "alldata_%s" % (station[:2],)
    nt = network.Table("%sCLIMATE" % (station[:2],))

    lag = "0 days"
    if month == 'fall':
        months = [9, 10, 11]
        label = "Fall (SON)"
    elif month == 'winter':
        months = [12, 1, 2]
        lag = "31 days"
        label = "Winter (DJF)"
    elif month == 'spring':
        months = [3, 4, 5]
        label = "Spring (MAM)"
    elif month == 'summer':
        months = [6, 7, 8]
        label = "Summer (JJA)"
    else:
        months = [int(month), ]
        label = calendar.month_name[int(month)]

    df = read_sql("""
    WITH climo as (
        SELECT to_char(valid, 'mmdd') as sday,
        high, low from ncdc_climate81 WHERE station = %s),
    day2day as (
        SELECT
        extract(year from day + '""" + lag + """'::interval)::int as myyear,
        month,
        abs(high - lag(high) OVER (ORDER by day ASC)) as dhigh,
        abs(low - lag(low) OVER (ORDER by day ASC)) as dlow,
    abs((high+low)/2. - lag((high+low)/2.) OVER (ORDER by day ASC)) as dtemp
        from """ + table + """ WHERE station = %s),
    agg as (
        SELECT myyear, avg(dhigh) as dhigh, avg(dlow) as dlow,
        avg(dtemp) as dtemp from day2day WHERE month in %s GROUP by myyear),
    agg2 as (
        SELECT
        extract(year from day + '""" + lag + """'::interval)::int as myyear,
        max(o.high) as "max-high",
        min(o.high) as "min-high",
        avg(o.high) as "avg-high",
        stddev(o.high) as "std-high",
        max(o.low) as "max-low",
        min(o.low) as "min-low",
        avg(o.low) as "avg-low",
        stddev(o.low) as "std-low",
        avg((o.high + o.low)/2.) as "avg-temp",
        stddev((o.high + o.low)/2.) as "std-temp",
        max(o.precip) as "max-precip",
        sum(o.precip) as "sum-precip",
        avg(o.high) - avg(o.low) as "range-avghi-avglo",
        sum(case when o.high >= %s then 1 else 0 end) as "days-high-above",
        sum(case when o.high < %s then 1 else 0 end) as "days-high-below",
    sum(case when o.high >= c.high then 1 else 0 end) as "days-high-above-avg",
        sum(case when o.low >= %s then 1 else 0 end) as "days-lows-above",
    sum(case when o.low < c.low then 1 else 0 end) as "days-lows-below-avg",
        sum(case when o.low < %s then 1 else 0 end) as "days-lows-below"
        from """+table+""" o JOIN climo c on (o.sday = c.sday)
      where station = %s and month in %s GROUP by myyear)

    SELECT b.*, a.dhigh as "delta-high", a.dlow as "delta-low",
    a.dtemp as "delta_temp" from agg a JOIN agg2 b
    on (a.myyear = b.myyear) ORDER by b.myyear ASC
    """, pgconn, params=(nt.sts[station]['ncdc81'], station, tuple(months),
                         threshold, threshold,
                         threshold, threshold, station, tuple(months)),
                  index_col='myyear')
    if df.empty:
        raise ValueError("No data was found for query")

    # Figure out the max min values to add to the row
    df2 = df[df[ptype] == df[ptype].max()]
    if df2.empty:
        raise ValueError("No data was found for query")
    xlabel = "Year, Max: %.2f %s%s" % (df[ptype].max(), df2.index.values[0],
                                       '+' if len(df2.index) > 1 else '')
    df2 = df[df[ptype] == df[ptype].min()]
    xlabel += ", Min: %.2f %s%s" % (df[ptype].min(), df2.index.values[0],
                                    '+' if len(df2.index) > 1 else '')
    ctx['xlabel'] = xlabel
    data = df[ptype].values
    ctx['data'] = data
    ctx['avgv'] = df[ptype].mean()
    ctx['df'] = df
    # Compute 30 year trailing average
    tavg = [None]*30
    for i in range(30, len(data)):
        tavg.append(np.average(data[i-30:i]))
    ctx['tavg'] = tavg
    # End interval is inclusive
    ctx['a1981_2010'] = df.loc[1981:2010, ptype].mean()
    ctx['ptype'] = ptype
    ctx['station'] = station
    ctx['threshold'] = threshold
    ctx['month'] = month
    ctx['title'] = ("[%s] %s %s-%s"
                    ) % (station, nt.sts[station]['name'],
                         df.index.min(), df.index.max())
    ctx['subtitle'] = ("%s %s"
                       ) % (label, PDICT[ptype])
    if ptype.find("days") == 0 and ptype.find('avg') == -1:
        ctx['subtitle'] += " (%s)" % (threshold,)

    units = r"$^\circ$F"
    if ctx['ptype'].find('precip') > 0:
        units = "inches"
    elif ctx['ptype'].find('days') > 0:
        units = "days"
    ctx['ylabel'] = "%s [%s]" % (PDICT[ctx['ptype']], units)
    return ctx
Beispiel #4
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn('coop')
    ccursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    threshold = ctx['threshold']
    direction = ctx['direction']
    varname = ctx['varname']
    startyear = ctx['year']

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    sql = """select year,
     max(case when """ + varname + """ < %s and month < 7
         then extract(doy from day) else 0 end) as spring,
     max(case when """ + varname + """ < %s and month < 7
         then day else null end) as spring_date,
     min(case when """ + varname + """ < %s and month > 6
         then extract(doy from day) else 388 end) as fall,
     min(case when """ + varname + """ < %s and month > 6
         then day else null end) as fall_date
    from """ + table + """ where station = %s
    GROUP by year ORDER by year ASC"""
    if direction == 'above':
        sql = """select year,
             min(case when """ + varname + """ > %s and month < 7
                 then extract(doy from day) else 183 end) as spring,
             min(case when """ + varname + """ > %s and month < 7
                 then day else null end) as spring_date,
             max(case when """ + varname + """ > %s and month > 6
                 then extract(doy from day) else 183 end) as fall,
             max(case when """ + varname + """ > %s and month > 6
                 then day else null end) as fall_date
            from """ + table + """ where station = %s
            GROUP by year ORDER by year ASC"""

    ccursor.execute(sql, (threshold, threshold, threshold, threshold, station))
    rows = []
    for row in ccursor:
        if row['year'] < startyear:
            continue
        if row['fall'] > 366:
            continue
        if row['fall'] == 183 and row['spring'] == 183:
            continue
        rows.append(
            dict(year=row['year'],
                 spring=row['spring'],
                 fall=row['fall'],
                 spring_date=row['spring_date'],
                 fall_date=row['fall_date']))

    df = pd.DataFrame(rows)
    df['season'] = df['fall'] - df['spring']
    res = """\
# IEM Climodat https://mesonet.agron.iastate.edu/climodat/
# Report Generated: %s
# Climate Record: %s -> %s
# Site Information: [%s] %s
# Contact Information: Daryl Herzmann [email protected] 515.294.5978
# LENGTH OF SEASON FOR STATION NUMBER  %s   BASE TEMP=%s
# LAST SPRING OCCURENCE FIRST FALL OCCURENCE
   YEAR MONTH DAY DOY         MONTH DAY DOY   LENGTH OF SEASON
""" % (datetime.date.today().strftime("%d %b %Y"),
       nt.sts[station]['archive_begin'].date(), datetime.date.today(), station,
       nt.sts[station]['name'], station, threshold)
    for _, row in df.iterrows():
        if row['spring_date'] is None or row['fall_date'] is None:
            continue
        res += ("%7i%4i%6i%4i        %4i%6i%4i          %.0f\n") % (
            row['year'], row['spring_date'].month, row['spring_date'].day,
            row['spring'], row['fall_date'].month, row['fall_date'].day,
            row['fall'], row['season'])
    sts = datetime.date(2000, 1,
                        1) + datetime.timedelta(days=df['spring'].mean())
    ets = datetime.date(2000, 1,
                        1) + datetime.timedelta(days=df['fall'].mean())
    res += ("%7s%4i%6i%4i        %4i%6i%4i          %.0f\n") % (
        "MEAN", sts.month, sts.day, df['spring'].mean(), ets.month, ets.day,
        df['spring'].mean(), df['season'].mean())
    years = np.array(df['year'])
    spring = np.array(df['spring'])
    fall = np.array(df['fall'])

    s_slp, s_int, s_r, _, _ = stats.linregress(years, spring)
    f_slp, f_int, f_r, _, _ = stats.linregress(years, fall)

    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))
    ax.bar(years, fall - spring, bottom=spring, ec='tan', fc='tan', zorder=1)
    for _v in [fall, spring]:
        avgv = int(np.average(_v))
        ts = datetime.date(2000, 1, 1) + datetime.timedelta(days=(avgv - 1))
        ax.text(years[-1] + 3,
                avgv,
                ts.strftime("Avg:\n%-d %b"),
                ha='left',
                va='center')
        ax.axhline(avgv, color='k')
    days = np.average(fall - spring)
    ax.text(1.02,
            0.5,
            "<- %.1f days ->" % (days, ),
            transform=ax.transAxes,
            rotation=-90)
    ax.plot(years,
            years * s_slp + s_int,
            lw=3,
            zorder=2,
            label=r"%.2f $\frac{days}{100y}$ R$^2$=%.2f" %
            (s_slp * 100., s_r**2))
    ax.plot(years,
            years * f_slp + f_int,
            lw=3,
            zorder=2,
            label=r"%.2f $\frac{days}{100y}$ R$^2$=%.2f" %
            (f_slp * 100., f_r**2))
    ax.grid(True)
    title = PDICT.get(direction, '').replace('Temperature',
                                             PDICT2.get(varname))
    ax.set_title(("[%s] %s\n"
                  r"%s %s$^\circ$F") %
                 (station, nt.sts[station]['name'], title, threshold))
    ax.legend(ncol=2, fontsize=14, labelspacing=2)
    ax.set_yticks((1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 365))
    ax.set_yticklabels(calendar.month_abbr[1:])
    ax.set_ylim(min(spring) - 5, max(fall) + 30)
    ax.set_xlim(min(years) - 1, max(years) + 1)
    return fig, df, res
Beispiel #5
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn("coop")
    cursor = pgconn.cursor()

    ctx = get_autoplot_context(fdict, get_description())
    station = ctx["station"]
    days = ctx["days"]
    days2 = ctx["days2"]
    date1 = ctx["date1"]
    date2 = ctx["date2"]

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))

    interval = datetime.timedelta(days=days2)

    lbls = []
    lbls2 = []
    psigma = []
    tsigma = []
    aligns = []
    align = ["top", "bottom"]

    now = date1
    while now <= date2:
        sdays = []
        for i in range(0, 0 - days, -1):
            sdays.append((now + datetime.timedelta(days=i)).strftime("%m%d"))
        cursor.execute("""
        SELECT avg(p), stddev(p), avg(t), stddev(t),
        max(case when year = %s then p else -999 end),
        max(case when year = %s then t else -999 end) from
        (SELECT year, sum(precip) as p, avg((high+low)/2.) as t
        from %s
        WHERE station = '%s' and sday in %s GROUP by year) as foo
        """ % (now.year, now.year, table, station, str(tuple(sdays))))
        row = cursor.fetchone()
        if row[0] is None:
            raise NoDataFound("No Data Found.")
        psigma.append((row[4] - row[0]) / row[1])
        tsigma.append((row[5] - row[2]) / row[3])
        lbls.append(now.strftime("%-m/%-d"))
        lbls2.append(now.strftime("%Y-%m-%d"))
        aligns.append(align[now.month % 2])

        now += interval
    df = pd.DataFrame(
        dict(
            psigma=pd.Series(psigma),
            tsigma=pd.Series(tsigma),
            sdate=pd.Series(lbls2),
        ))
    tsigma = np.array(tsigma, "f")
    psigma = np.array(psigma, "f")
    ax.quiver(
        tsigma[:-1],
        psigma[:-1],
        tsigma[1:] - tsigma[:-1],
        psigma[1:] - psigma[:-1],
        scale_units="xy",
        angles="xy",
        scale=1,
        zorder=1,
        color="tan",
    )
    for lbl, t, p, a in zip(lbls, tsigma, psigma, aligns):
        # Manual move label some for readiability
        if lbl == "7/15":
            t = float(t) + 0.1
            p = float(p) + -0.2
        ax.text(t, p, lbl, va=a, zorder=2)

    tmax = max([abs(np.min(tsigma)), abs(np.max(tsigma))]) + 0.5
    ax.set_xlim(0 - tmax, tmax)
    pmax = max([abs(np.min(psigma)), abs(np.max(psigma))]) + 0.5
    ax.set_ylim(0 - pmax, pmax)
    ax.set_ylabel(r"Precipitation Departure $\sigma$")
    ax.set_xlabel(r"Temperature Departure $\sigma$")
    ax.set_title(("%s - %s [%s] %s\n"
                  "%s Day Trailing Departures plotted every %s days") % (
                      date1.strftime("%d %b %Y"),
                      date2.strftime("%d %b %Y"),
                      station,
                      nt.sts[station]["name"],
                      days,
                      days2,
                  ))
    ax.grid(True)
    ax.set_position([0.1, 0.1, 0.7, 0.8])
    y = 0.96
    pos = [1.01, 1.15, 1.22]
    ax.text(pos[0], y + 0.04, "Date", transform=ax.transAxes, fontsize=10)
    ax.text(
        pos[1],
        y + 0.04,
        r"T $\sigma$",
        transform=ax.transAxes,
        fontsize=10,
        ha="right",
    )
    ax.text(
        pos[2],
        y + 0.04,
        r"P $\sigma$",
        transform=ax.transAxes,
        fontsize=10,
        ha="right",
    )
    for lbl, t, p, a in zip(lbls, tsigma, psigma, aligns):
        ax.text(pos[0], y, "%s" % (lbl, ), transform=ax.transAxes, fontsize=10)
        ax.text(
            pos[1],
            y,
            "%.1f" % (t, ),
            transform=ax.transAxes,
            fontsize=10,
            color=get_color(t, "t"),
            ha="right",
        )
        ax.text(
            pos[2],
            y,
            "%.1f" % (p, ),
            transform=ax.transAxes,
            fontsize=10,
            color=get_color(p, "p"),
            ha="right",
        )
        y -= 0.04
    return fig, df
Beispiel #6
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    pgconn = psycopg2.connect(database='coop', host='iemdb', user='******')

    station = fdict.get('station', 'IA0000')
    ptype = fdict.get('type', 'max-high')
    threshold = int(fdict.get('threshold', -99))

    table = "alldata_%s" % (station[:2],)
    nt = network.Table("%sCLIMATE" % (station[:2],))

    df = read_sql("""
    SELECT year,
    max(high) as "max-high",
    min(high) as "min-high",
    avg(high) as "avg-high",
    max(low) as "max-low",
    min(low) as "min-low",
    avg(low) as "avg-low",
    max(precip) as "max-precip",
    sum(precip) as "sum-precip",
    sum(case when high >= %s then 1 else 0 end) as "days-high-above",
    sum(case when low >= %s then 1 else 0 end) as "days-lows-above",
    sum(case when low < %s then 1 else 0 end) as "days-lows-below",
    avg(precip) as "avg-precip",
    avg(case when precip >= 0.01 then precip else null end) as "avg-precip2",
    sum(case when precip >= %s then 1 else 0 end) as "days-precip"
  from """+table+"""
  where station = %s
  GROUP by year ORDER by year ASC
    """, pgconn, params=(threshold, threshold, threshold, threshold, station),
                  index_col='year')

    (fig, ax) = plt.subplots(1, 1)
    avgv = df[ptype].mean()
    data = df[ptype].values
    years = df.index.values

    # Compute 30 year trailing average
    tavg = [None]*30
    for i in range(30, len(data)):
        tavg.append(np.average(data[i-30:i]))

    a1981_2010 = df.loc[1981:2011, ptype].mean()

    colorabove = 'tomato'
    colorbelow = 'dodgerblue'
    precision = "%.1f"
    if ptype in ['max-precip', 'sum-precip', 'avg-precip', 'avg-precip2',
                 'days-precip']:
        colorabove = 'dodgerblue'
        colorbelow = 'tomato'
        precision = "%.2f"
    bars = ax.bar(np.array(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)
    lbl = "Avg: "+precision % (avgv,)
    ax.axhline(avgv, lw=2, color='k', zorder=2, label=lbl)
    lbl = "1981-2010: "+precision % (a1981_2010,)
    ax.axhline(a1981_2010, lw=2, color='brown', zorder=2, label=lbl)
    ax.plot(years, tavg, lw=1.5, color='g', zorder=4, label='Trailing 30yr')
    ax.plot(years, tavg, lw=3, color='yellow', zorder=3)
    ax.set_xlim(years[0] - 1, years[-1] + 1)
    if ptype.find('precip') == -1 and ptype.find('days') == -1:
        ax.set_ylim(min(data) - 5, max(data) + 5)

    ax.set_xlabel("Year")
    units = "$^\circ$F"
    if ptype.find('days') > 0:
        units = "days"
    elif ptype.find('precip') > 0:
        units = "inches"
    ax.set_ylabel("%s [%s]" % (PDICT[ptype], units))
    ax.grid(True)
    ax.legend(ncol=3, loc='best', fontsize=10)
    msg = ("[%s] %s %s-%s %s"
           ) % (station, nt.sts[station]['name'],
                min(years), max(years), PDICT[ptype])
    if ptype.find("days") == 0:
        msg += " (%s)" % (threshold,)
    tokens = msg.split()
    sz = len(tokens) / 2
    ax.set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:]))

    return fig, df
Beispiel #7
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    pgconn = psycopg2.connect(database='coop', host='iemdb', user='******')

    station = fdict.get('station', 'IA0000')
    varname = fdict.get('var', 'high')
    month = fdict.get('month', 'all')

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    yr = "year as yr"
    if month == 'all':
        months = range(1, 13)
    elif month == 'fall':
        months = [9, 10, 11]
    elif month == 'winter':
        months = [12, 1, 2]
        yr = "extract(year from o.day - '60 days'::interval) as yr"
    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("""
      WITH avgs as (
        SELECT sday, avg(high) as avg_high,
        avg(low) as avg_low,
        avg((high+low)/2.) as avg_temp from """ + table + """ WHERE
        station = %s GROUP by sday)

      SELECT """ + yr + """,
      sum(case when o.high > a.avg_high then 1 else 0 end) as high_above,
      sum(case when o.low > a.avg_low then 1 else 0 end) as low_above,
      sum(case when (o.high+o.low)/2. > a.avg_temp then 1 else 0 end)
          as avg_above,
      count(*) as days from """ + table + """ o, avgs a WHERE o.station = %s
      and o.sday = a.sday and month in %s
      GROUP by yr ORDER by yr ASC
    """,
                  pgconn,
                  params=(station, station, tuple(months)),
                  index_col='yr')

    df['high_freq'] = df['high_above'] / df['days'].astype('f') * 100.
    df['low_freq'] = df['low_above'] / df['days'].astype('f') * 100.
    df['avg_freq'] = df['avg_above'] / df['days'].astype('f') * 100.

    (fig, ax) = plt.subplots(1, 1)
    avgv = df[varname + '_freq'].mean()

    colorabove = 'r'
    colorbelow = 'b'
    data = df[varname + '_freq'].values
    bars = ax.bar(df.index.values - 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)
    txt = ax.text(bars[10].get_x(),
                  avgv,
                  "Avg: %.1f%%" % (avgv, ),
                  color='yellow',
                  fontsize=14,
                  va='center')
    txt.set_path_effects([PathEffects.withStroke(linewidth=5, foreground="k")])
    ax.set_ylim(0, 100)
    ax.set_yticks([0, 10, 25, 50, 75, 90, 100])
    ax.set_xlabel("Year")
    ax.set_xlim(bars[0].get_x() - 1, bars[-1].get_x() + 1)
    ax.set_ylabel("Frequency [%]")
    ax.grid(True)
    msg = ("[%s] %s %s-%s Percentage of Days with %s Above Average (month=%s)"
           ) % (station, nt.sts[station]['name'], df.index.values.min(),
                df.index.values.max(), PDICT[varname], month.upper())
    tokens = msg.split()
    sz = len(tokens) / 2
    ax.set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:]))

    return fig, df
Beispiel #8
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    pgconn = get_dbconn('coop')
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    season = ctx['season']
    direction = ctx['dir']
    varname = ctx['var']
    threshold = ctx['threshold']
    startyear = ctx['year']

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    b = "%s %s %s" % (varname, ">=" if direction == 'above' else '<',
                      threshold)

    df = read_sql("""
      SELECT extract(year from day + '%s month'::interval) as yr,
      sum(case when month in (12, 1, 2) and """ + b + """
      then 1 else 0 end) as winter,
      sum(case when month in (3, 4, 5) and """ + b + """
      then 1 else 0 end) as spring,
      sum(case when month in (6, 7, 8) and """ + b + """
      then 1 else 0 end) as summer,
      sum(case when month in (9, 10, 11) and """ + b + """
      then 1 else 0 end) as fall,
      sum(case when """ + b + """ then 1 else 0 end) as all
      from """ + table + """ WHERE station = %s and year >= %s
      GROUP by yr ORDER by yr ASC
    """,
                  pgconn,
                  params=(1 if season != 'all' else 0, station, startyear),
                  index_col='yr')
    if df.empty:
        raise ValueError("No data found for query")

    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))
    avgv = df[season].mean()

    colorabove = 'r'
    colorbelow = 'b'
    if direction == 'below':
        colorabove = 'b'
        colorbelow = 'r'
    bars = ax.bar(df.index.values,
                  df[season],
                  fc=colorabove,
                  ec=colorabove,
                  align='center')
    for i, bar in enumerate(bars):
        if df[season].values[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(
        df.index.values, df[season])
    ax.plot(df.index.values,
            h_slope * df.index.values + intercept,
            '--',
            lw=2,
            color='k',
            label='Trend')
    ax.text(0.01,
            0.99,
            "Avg: %.1f, slope: %.2f days/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(df.index.min() - 1, df.index.max() + 1)
    ax.set_ylim(0, max([df[season].max() + df[season].max() / 7., 3]))
    ax.set_ylabel("Number of Days")
    ax.grid(True)
    msg = ("[%s] %s %.0f-%.0f Number of Days [%s] "
           "with %s %s %g%s") % (station, nt.sts[station]['name'],
                                 df.index.min(), df.index.max(),
                                 PDICT2[season], PDICT3[varname],
                                 PDICT[direction], threshold, "$^\circ$F"
                                 if varname != 'precip' else 'inch')
    tokens = msg.split()
    sz = len(tokens) / 2
    ax.set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:]))
    ax.legend(ncol=1)

    return fig, df
Beispiel #9
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    import matplotlib.colors as mpcolors
    COOP = psycopg2.connect(database='coop', host='iemdb', user='******')
    ccursor = COOP.cursor(cursor_factory=psycopg2.extras.DictCursor)
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    lagmonths = ctx['lag']
    months = ctx['months']
    month = ctx['month']
    highyears = [int(x) for x in ctx['year'].split(",")]
    h = ctx['h']

    wantmonth = month + lagmonths
    yearoffset = 0
    if month + lagmonths < 1:
        wantmonth = 12 - (month + lagmonths)
        yearoffset = 1

    wanted = []
    deltas = []
    for m in range(month, month + months):
        if m < 13:
            wanted.append(m)
            deltas.append(0)
        else:
            wanted.append(m - 12)
            deltas.append(-1)

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    elnino = {}
    ccursor.execute("""SELECT monthdate, soi_3m, anom_34 from elnino""")
    for row in ccursor:
        if row[0].month != wantmonth:
            continue
        elnino[row[0].year + yearoffset] = dict(soi_3m=row[1], anom_34=row[2])

    ccursor.execute(
        """
        SELECT year, month, sum(precip), avg((high+low)/2.)
        from """ + table + """
        where station = %s GROUP by year, month
    """, (station, ))
    yearly = {}
    for row in ccursor:
        (_year, _month, _precip, _temp) = row
        if _month not in wanted:
            continue
        effectiveyear = _year + deltas[wanted.index(_month)]
        nino = elnino.get(effectiveyear, {}).get('soi_3m', None)
        if nino is None:
            continue
        data = yearly.setdefault(effectiveyear,
                                 dict(precip=0, temp=[], nino=nino))
        data['precip'] += _precip
        data['temp'].append(float(_temp))

    fig = plt.figure(figsize=(10, 6))
    ax = plt.axes([0.1, 0.12, 0.5, 0.75])
    msg = ("[%s] %s\n%s\n%s SOI (3 month average)") % (
        station, nt.sts[station]['name'], title(wanted),
        datetime.date(2000, wantmonth, 1).strftime("%B"))
    ax.set_title(msg)

    cmap = plt.get_cmap("RdYlGn")
    zdata = np.arange(-2.0, 2.1, 0.5)
    norm = mpcolors.BoundaryNorm(zdata, cmap.N)
    rows = []
    xs = []
    ys = []
    for year in yearly:
        x = yearly[year]['precip']
        y = np.average(yearly[year]['temp'])
        xs.append(x)
        ys.append(y)
        val = yearly[year]['nino']
        c = cmap(norm([val])[0])
        if h == 'hide' and val > -0.5 and val < 0.5:
            ax.scatter(x,
                       y,
                       facecolor='#EEEEEE',
                       edgecolor='#EEEEEE',
                       s=30,
                       zorder=2,
                       marker='s')
        else:
            ax.scatter(x,
                       y,
                       facecolor=c,
                       edgecolor='k',
                       s=60,
                       zorder=3,
                       marker='o')
        if year in highyears:
            ax.text(x,
                    y + 0.2,
                    "%s" % (year, ),
                    ha='center',
                    va='bottom',
                    zorder=5)
        rows.append(dict(year=year, precip=x, tmpf=y, soi3m=val))

    ax.axhline(np.average(ys), lw=2, color='k', linestyle='-.', zorder=2)
    ax.axvline(np.average(xs), lw=2, color='k', linestyle='-.', zorder=2)

    sm = plt.cm.ScalarMappable(norm, cmap)
    sm.set_array(zdata)
    cb = plt.colorbar(sm, extend='both')
    cb.set_label("<-- El Nino :: SOI :: La Nina -->")

    ax.grid(True)
    ax.set_xlim(left=-0.01)
    ax.set_xlabel("Total Precipitation [inch], Avg: %.2f" % (np.average(xs), ))
    ax.set_ylabel("Average Temperature $^\circ$F, Avg: %.1f" %
                  (np.average(ys), ))
    df = pd.DataFrame(rows)
    ax2 = plt.axes([0.67, 0.6, 0.28, 0.35])
    ax2.scatter(df['soi3m'].values, df['tmpf'].values)
    ax2.set_xlabel("<-- El Nino :: SOI :: La Nina -->")
    ax2.set_ylabel("Avg Temp $^\circ$F")
    slp, intercept, r_value, _, _ = stats.linregress(df['soi3m'].values,
                                                     df['tmpf'].values)
    y1 = -2.0 * slp + intercept
    y2 = 2.0 * slp + intercept
    ax2.plot([-2, 2], [y1, y2])
    ax2.text(0.97,
             0.9,
             "R$^2$=%.2f" % (r_value**2, ),
             ha='right',
             transform=ax2.transAxes,
             bbox=dict(color='white'))
    ax2.grid(True)

    ax3 = plt.axes([0.67, 0.1, 0.28, 0.35])
    ax3.scatter(df['soi3m'].values, df['precip'].values)
    ax3.set_xlabel("<-- El Nino :: SOI :: La Nina -->")
    ax3.set_ylabel("Total Precip [inch]")
    slp, intercept, r_value, _, _ = stats.linregress(df['soi3m'].values,
                                                     df['precip'].values)
    y1 = -2.0 * slp + intercept
    y2 = 2.0 * slp + intercept
    ax3.plot([-2, 2], [y1, y2])
    ax3.text(0.97,
             0.9,
             "R$^2$=%.2f" % (r_value**2, ),
             ha='right',
             transform=ax3.transAxes,
             bbox=dict(color='white'))
    ax3.grid(True)

    return fig, df
Beispiel #10
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    from matplotlib.patches import Circle
    pgconn = get_dbconn('coop')
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    month = ctx['month']
    year = ctx['year']
    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    df = read_sql("""
        SELECT year, sum(precip) as total_precip,
        sum(gdd50(high::numeric,low::numeric)) as gdd50 from """ + table + """
        WHERE station = %s and month = %s GROUP by year
    """,
                  pgconn,
                  params=(station, month),
                  index_col='year')
    if df.empty:
        raise ValueError("ERROR: No Data Found")

    gstats = df.gdd50.describe()
    pstats = df.total_precip.describe()

    df['precip_sigma'] = (df.total_precip - pstats['mean']) / pstats['std']
    df['gdd50_sigma'] = (df.gdd50 - gstats['mean']) / gstats['std']
    df['distance'] = (df.precip_sigma**2 + df.gdd50_sigma**2)**0.5

    h_slope, intercept, r_value, _, _ = stats.linregress(
        df['gdd50_sigma'], df['precip_sigma'])

    y1 = -4.0 * h_slope + intercept
    y2 = 4.0 * h_slope + intercept
    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))
    ax.set_position([0.1, 0.12, 0.8, 0.78])

    ax.scatter(df['gdd50_sigma'], df['precip_sigma'], label=None)
    ax.plot([-4, 4], [y1, y2],
            label="Slope=%.2f R$^2$=%.2f" % (h_slope, r_value**2))
    xmax = df.gdd50_sigma.abs().max() + 0.25
    ymax = df.precip_sigma.abs().max() + 0.25
    ax.set_xlim(0 - xmax, xmax)
    ax.set_ylim(0 - ymax, ymax)
    events = df.query("distance > 2.5 or year == %.0f" % (year, ))
    for _year, row in events.iterrows():
        ax.text(row['gdd50_sigma'],
                row['precip_sigma'],
                ' %.0f' % (_year, ),
                va='center')

    if year in df.index:
        c = Circle((0, 0), radius=df.loc[year].distance, facecolor='none')
        ax.add_patch(c)
    ax.set_xlabel(r"Growing Degree Day Departure ($\sigma$)")
    ax.set_ylabel(r"Precipitation Departure ($\sigma$)")
    ax.grid(True)
    ax.set_title(
        ("%s %s [%s]\n"
         "Growing Degree Day (base=50) + Precipitation Departure") %
        (calendar.month_name[month], nt.sts[station]['name'], station))
    ax.legend(loc='upper right',
              bbox_to_anchor=(1.05, -0.04),
              ncol=2,
              fontsize=10)

    return fig, df
Beispiel #11
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn("coop", user="******")
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx["station"]
    thisyear = datetime.datetime.now().year
    year = ctx["year"]
    base = ctx["base"]
    ceiling = ctx["ceiling"]
    varname = ctx["var"]

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))
    ab = nt.sts[station]["archive_begin"]
    if ab is None:
        raise NoDataFound("Unknown Station Metadata.")
    syear = max(ab.year, 1893)

    glabel = "%s%s%s" % (varname, base, ceiling)
    gfunc = "gddxx(%s, %s, high, low)" % (base, ceiling)
    title = "base=%s/ceil=%s" % (base, ceiling)
    if varname in ["hdd", "cdd"]:
        gfunc = "%s(high, low, %s)" % (varname, base)
        title = "base=%s" % (base, )
    elif varname == "sdd":
        gfunc = "case when high > %s then high - %s else 0 end" % (
            ceiling,
            ceiling,
        )
        title = "base=%s" % (ceiling, )

    df = read_sql(
        """
        SELECT year, sday,
        """ + gfunc + """ as """ + glabel + """
        from """ + table + """ WHERE station = %s and year > 1892
        and sday != '0229'
    """,
        pgconn,
        params=(station, ),
    )
    if df.empty:
        raise NoDataFound("No data Found.")

    # Do some magic!
    df2 = (df[[
        "sday", glabel
    ]].groupby("sday").describe(percentiles=[0.05, 0.25, 0.75, 0.95]))
    df2 = df2.unstack(level=-1)
    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))
    ax.plot(
        np.arange(1, 366),
        df2[(glabel, "mean")],
        color="r",
        zorder=2,
        lw=2.0,
        label="Average",
    )
    _data = df[df["year"] == year][[glabel, "sday"]]
    _data.sort_values(by="sday", inplace=True)
    ax.scatter(
        np.arange(1, _data[glabel].shape[0] + 1),
        _data[glabel],
        color="b",
        zorder=2,
        label="%s" % (year, ),
    )
    ax.bar(
        np.arange(1, 366),
        df2[(glabel, "95%")] - df2[(glabel, "5%")],
        bottom=df2[(glabel, "5%")],
        ec="tan",
        fc="tan",
        zorder=1,
        label="5-95 Percentile",
    )
    ax.bar(
        np.arange(1, 366),
        df2[(glabel, "75%")] - df2[(glabel, "25%")],
        bottom=df2[(glabel, "25%")],
        ec="lightblue",
        fc="lightblue",
        zorder=1,
        label="25-75 Percentile",
    )
    ax.set_xlim(0, 367)
    if varname == "gdd":
        ax.set_ylim(-0.25, 40)
    ax.grid(True)
    ax.set_title("%s-%s %s [%s]\n%s %s (%s)" % (
        syear,
        thisyear,
        nt.sts[station]["name"],
        station,
        year,
        PDICT[varname],
        title,
    ))
    ax.set_ylabel(r"Daily Accumulation $^{\circ}\mathrm{F}$")
    ax.set_xticks((1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335))
    ax.legend(ncol=2)
    ax.set_xticklabels(calendar.month_abbr[1:])

    # collapse the multiindex for columns
    df = pd.DataFrame(df2)
    return fig, df
Beispiel #12
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    pgconn = get_dbconn('coop')
    ccursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    binsize = ctx['binsize']
    month = ctx['month']
    table = "alldata_%s" % (station[:2],)
    nt = network.Table("%sCLIMATE" % (station[:2],))
    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]
    ccursor.execute("""
    SELECT high, low from """+table+"""
      WHERE station = %s and year > 1892 and high >= low
      and month in %s
    """, (station, tuple(months)))
    highs = []
    lows = []
    for row in ccursor:
        highs.append(row[0])
        lows.append(row[1])

    bins = np.arange(-20, 121, binsize)

    H, xedges, yedges = np.histogram2d(lows, highs, bins)
    rows = []
    for i, x in enumerate(xedges[:-1]):
        for j, y in enumerate(yedges[:-1]):
            rows.append(dict(high=y, low=x, count=H[i, j]))
    df = pd.DataFrame(rows)
    years = float(
        datetime.datetime.now().year - nt.sts[station]['archive_begin'].year
        )
    H = np.ma.array(H / years)
    H.mask = np.where(H < (1./years), True, False)
    ar = np.argwhere(H.max() == H)

    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))
    res = ax.pcolormesh(xedges, yedges, H.transpose())
    fig.colorbar(res, label="Days per Year")
    ax.grid(True)
    ax.set_title(("%s [%s]\n"
                  "Daily High vs Low Temp Histogram (month=%s)"
                  ) % (nt.sts[station]['name'], station, month.upper()))
    ax.set_ylabel(r"High Temperature $^{\circ}\mathrm{F}$")
    ax.set_xlabel(r"Low Temperature $^{\circ}\mathrm{F}$")

    x = ar[0][0]
    y = ar[0][1]
    ax.text(0.65, 0.15, ("Largest Frequency: %.1f days\n"
                         "High: %.0f-%.0f Low: %.0f-%.0f"
                         ) % (H[x, y], yedges[y], yedges[y+1],
                              xedges[x], xedges[x+1]),
            ha='center', va='center', transform=ax.transAxes,
            bbox=dict(color='white'))
    ax.axhline(32, linestyle='-', lw=1, color='k')
    ax.text(120, 32, r"32$^\circ$F", va='center', ha='right', color='white',
            bbox=dict(color='k'), fontsize=8)
    ax.axvline(32, linestyle='-', lw=1, color='k')
    ax.text(32, 120, r"32$^\circ$F", va='top', ha='center', color='white',
            bbox=dict(facecolor='k', edgecolor='none'), fontsize=8)

    return fig, df
Beispiel #13
0
def main():
    """Go Main Go"""
    nt = network.Table("AWOS")
    qdict = loadqc()
    pgconn = get_dbconn("iem", user="******")
    icursor = pgconn.cursor()

    # We run at 12z
    now12z = datetime.datetime.utcnow()
    now12z = now12z.replace(hour=12,
                            minute=0,
                            second=0,
                            microsecond=0,
                            tzinfo=pytz.utc)
    today6z = now12z.replace(hour=6)
    today0z = now12z.replace(hour=0)
    yesterday6z = today6z - datetime.timedelta(days=1)
    yesterday12z = now12z - datetime.timedelta(days=1)

    fmt = "%-6s:%-19s: %3s / %3s / %5s / %4s / %2s\n"

    shef_fn = "/tmp/awos_rtp.shef"
    out = open(shef_fn, "w")
    out.write(
        ("\n"
         "\n"
         "\n"
         ".BR DMX %s Z DH06/TAIRVX/DH12/TAIRVP/PPDRVZ/SFDRVZ/SDIRVZ\n"
         ": IOWA AWOS RTP FIRST GUESS PROCESSED BY THE IEM\n"
         ":   06Z to 06Z HIGH TEMPERATURE FOR %s\n"
         ":   00Z TO 12Z TODAY LOW TEMPERATURE\n"
         ":   12Z YESTERDAY TO 12Z TODAY RAINFALL\n"
         ":   ...BASED ON REPORTED OBS...\n") %
        (now12z.strftime("%m%d"), yesterday6z.strftime("%d %b %Y").upper()))

    # 6z to 6z high temperature
    highs = {}
    sql = """SELECT id,
        round(max(tmpf)::numeric,0) as max_tmpf,
        count(tmpf) as obs FROM current_log c, stations t
        WHERE t.iemid = c.iemid and t.network = 'AWOS' and valid >= %s
        and valid < %s
        and tmpf > -99 GROUP by id """
    args = (yesterday6z, today6z)
    icursor.execute(sql, args)
    for row in icursor:
        if qdict.get(row[0], {}).get("tmpf"):
            continue
        highs[row[0]] = row[1]

    # 12z to 12z precip
    pcpn = {}
    sql = """
        select id, sum(precip) from
        (select id, extract(hour from valid) as hour,
        max(phour) as precip from current_log c, stations t
        WHERE t.network = 'AWOS' and t.iemid = c.iemid
        and valid  >= %s and valid < %s
        GROUP by id, hour) as foo
        GROUP by id
    """
    args = (yesterday12z, now12z)
    icursor.execute(sql, args)
    for row in icursor:
        if qdict.get(row[0], {}).get("precip") or row[1] is None:
            continue
        pcpn[row[0]] = "%5.2f" % (row[1], )

    # 0z to 12z low temperature
    lows = {}
    sql = """
        SELECT id, round(min(tmpf)::numeric,0) as min_tmpf,
        count(tmpf) as obs FROM
        current_log c JOIN stations t on (t.iemid = c.iemid)
        WHERE t.network = 'AWOS' and valid >= %s
        and valid < %s  and tmpf > -99 GROUP by id
    """
    args = (today0z, now12z)
    icursor.execute(sql, args)
    for row in icursor:
        if qdict.get(row[0], {}).get("tmpf"):
            continue
        lows[row[0]] = row[1]

    ids = list(nt.sts.keys())
    ids.sort()
    for myid in ids:
        out.write(fmt % (
            myid,
            nt.sts[myid]["name"],
            highs.get(myid, "M"),
            lows.get(myid, "M"),
            pcpn.get(myid, "M"),
            "M",
            "M",
        ))

    out.write(".END\n")
    out.close()

    cmd = ("/home/ldm/bin/pqinsert -p 'plot ac %s0000 awos_rtp.shef "
           "awos_rtp.shef shef' %s") % (now12z.strftime("%Y%m%d"), shef_fn)
    subprocess.call(cmd, shell=True)
    os.unlink(shef_fn)
Beispiel #14
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn("coop")
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx["station"]
    binsize = ctx["binsize"]
    month = ctx["month"]
    year = ctx.get("year")
    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))
    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]
    ddf = read_sql(
        f"SELECT high, low, year, month from {table} WHERE station = %s "
        "and year > 1892 and high >= low and month in %s",
        pgconn,
        params=(station, tuple(months)),
        index_col=None,
    )
    if ddf.empty:
        raise NoDataFound("No Data Found.")

    bins = np.arange(-40, 121, binsize)

    hist, xedges, yedges = np.histogram2d(ddf["low"], ddf["high"], bins)
    rows = []
    for i, xedge in enumerate(xedges[:-1]):
        for j, yedge in enumerate(yedges[:-1]):
            rows.append(dict(high=yedge, low=xedge, count=hist[i, j]))
    df = pd.DataFrame(rows)
    ab = nt.sts[station]["archive_begin"]
    if ab is None:
        raise NoDataFound("Unknown station metadata.")
    years = float(datetime.datetime.now().year - ab.year)
    hist = np.ma.array(hist / years)
    hist.mask = np.where(hist < (1.0 / years), True, False)
    ar = np.argwhere(hist.max() == hist)

    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))
    res = ax.pcolormesh(xedges, yedges, hist.T)
    fig.colorbar(res, label="Days per Year")
    ax.grid(True)
    ax.set_title(("%s [%s]\n"
                  "Daily High vs Low Temp Histogram (month=%s)") %
                 (nt.sts[station]["name"], station, month.upper()))
    ax.set_ylabel(r"High Temperature $^{\circ}\mathrm{F}$")
    ax.set_xlabel(r"Low Temperature $^{\circ}\mathrm{F}$")

    xmax = ar[0][0]
    ymax = ar[0][1]
    ax.text(
        0.65,
        0.15,
        ("Largest Frequency: %.1f days\n"
         "High: %.0f-%.0f Low: %.0f-%.0f") % (
             hist[xmax, ymax],
             yedges[ymax],
             yedges[ymax + 1],
             xedges[xmax],
             xedges[xmax + 1],
         ),
        ha="center",
        va="center",
        transform=ax.transAxes,
        bbox=dict(color="white"),
    )
    ax.axhline(32, linestyle="-", lw=1, color="k")
    ax.text(
        120,
        32,
        r"32$^\circ$F",
        va="center",
        ha="right",
        color="white",
        bbox=dict(color="k"),
        fontsize=8,
    )
    ax.axvline(32, linestyle="-", lw=1, color="k")
    ax.text(
        32,
        117,
        r"32$^\circ$F",
        va="top",
        ha="center",
        color="white",
        bbox=dict(facecolor="k", edgecolor="none"),
        fontsize=8,
    )
    if year:
        label = str(year)
        if month == "winter":
            ddf["year"] = (ddf[((ddf["month"] == 1) |
                                (ddf["month"] == 2))]["year"] - 1)
            label = "Dec %s - Feb %s" % (year, year + 1)
        ddf2 = ddf[ddf["year"] == year]
        ax.scatter(
            ddf2["low"],
            ddf2["high"],
            marker="x",
            label=label,
            edgecolor="white",
            facecolor="red",
        )
        ax.legend()

    return fig, df
Beispiel #15
0
def main():
    """Go Main Go."""
    nt = network.Table("AWOS")
    qdict = loadqc()
    pgconn = get_dbconn("iem", user="******")
    icursor = pgconn.cursor()

    utc = datetime.datetime.utcnow()
    ets = utc.replace(
        tzinfo=pytz.utc, hour=0, minute=0, second=0, microsecond=0
    )
    sts12z = ets + datetime.timedelta(hours=-12)
    sts6z = ets + datetime.timedelta(hours=-18)
    sts24h = ets + datetime.timedelta(days=-1)

    fmt = "%-6s:%-19s: %3s / %3s / %5s / %4s / %2s\n"

    out = open("/tmp/awos_rtp.shef", "w")
    out.write(
        """


.BR DMX %s Z DH00/TAIRVS/TAIRVI/PPDRVZ/SFDRVZ/SDIRVZ
: IOWA AWOS RTP FIRST GUESS PROCESSED BY THE IEM
:   06Z TO 00Z HIGH TEMPERATURE FOR %s
:   06Z TO 00Z LOW TEMPERATURE FOR %s
:   00Z YESTERDAY TO 00Z TODAY RAINFALL
:   ...BASED ON REPORTED OBS...
"""
        % (
            ets.strftime("%m%d"),
            sts12z.strftime("%d %b %Y").upper(),
            sts12z.strftime("%d %b %Y").upper(),
        )
    )

    # We get 18 hour highs
    highs = {}
    sql = """SELECT t.id as station,
        round(max(tmpf)::numeric,0) as max_tmpf,
        count(tmpf) as obs FROM current_log c, stations t
        WHERE t.iemid = c.iemid and t.network = 'AWOS' and valid > %s
            and valid < %s
        and tmpf > -99 GROUP by t.id """
    args = (sts6z, ets)
    icursor.execute(sql, args)
    for row in icursor:
        if qdict.get(row[0], {}).get("tmpf"):
            continue
        highs[row[0]] = row[1]

    # 00 UTC to 00 UTC Preciptation
    pcpn = {}
    icursor.execute(
        """
        select id as station, sum(precip) from
        (select t.id, extract(hour from valid) as hour,
        max(phour) as precip from current_log c, stations t
        WHERE t.network = 'AWOS' and t.iemid = c.iemid
        and valid  >= %s and valid < %s
        GROUP by t.id, hour) as foo
        GROUP by id""",
        (sts24h, ets),
    )
    for row in icursor:
        if qdict.get(row[0], {}).get("precip") or row[1] is None:
            continue
        pcpn[row[0]] = "%5.2f" % (row[1],)

    lows = {}
    icursor.execute(
        """SELECT t.id as station,
        round(min(tmpf)::numeric,0) as min_tmpf,
        count(tmpf) as obs FROM current_log c, stations t
        WHERE t.iemid = c.iemid and t.network = 'AWOS' and valid > %s and
        valid < %s and tmpf > -99 GROUP by t,id""",
        (sts6z, ets),
    )

    for row in icursor:
        if qdict.get(row[0], {}).get("tmpf"):
            continue
        lows[row[0]] = row[1]

    ids = list(nt.sts.keys())
    ids.sort()
    for sid in ids:
        myP = pcpn.get(sid, "M")
        myH = highs.get(sid, "M")
        myL = lows.get(sid, "M")

        out.write(fmt % (sid, nt.sts[sid]["name"], myH, myL, myP, "M", "M"))

    out.write(".END\n")
    out.close()

    cmd = (
        "pqinsert -p 'plot ac %s0000 awos_rtp_00z.shef "
        "awos_rtp_00z.shef shef' /tmp/awos_rtp.shef"
    ) % (ets.strftime("%Y%m%d"),)
    subprocess.call(cmd, shell=True)
Beispiel #16
0
Datei: p3.py Projekt: nbackas/iem
def get_context(fdict):
    """ Get the context"""
    ctx = dict()
    pgconn = psycopg2.connect(database='coop', host='iemdb', user='******')

    station = fdict.get('station', 'IA0000')
    month = fdict.get('month', 7)
    ptype = fdict.get('type', 'max-high')
    threshold = int(fdict.get('threshold', -99))

    table = "alldata_%s" % (station[:2],)
    nt = network.Table("%sCLIMATE" % (station[:2],))

    l = "0 days"
    if month == 'fall':
        months = [9, 10, 11]
        label = "Fall (SON)"
    elif month == 'winter':
        months = [12, 1, 2]
        l = "31 days"
        label = "Winter (DJF)"
    elif month == 'spring':
        months = [3, 4, 5]
        label = "Spring (MAM)"
    elif month == 'summer':
        months = [6, 7, 8]
        label = "Summer (JJA)"
    else:
        months = [int(month), ]
        label = calendar.month_name[int(month)]

    df = read_sql("""
    WITH climo as (SELECT to_char(valid, 'mmdd') as sday,
    high, low from ncdc_climate81 WHERE
    station = %s)

    SELECT extract(year from day + '"""+l+"""'::interval)::int as myyear,
    max(o.high) as "max-high",
    min(o.high) as "min-high",
    avg(o.high) as "avg-high",
    max(o.low) as "max-low",
    min(o.low) as "min-low",
    avg(o.low) as "avg-low",
    max(o.precip) as "max-precip",
    sum(o.precip) as "sum-precip",
    sum(case when o.high >= %s then 1 else 0 end) as "days-high-above",
    sum(case when o.high < %s then 1 else 0 end) as "days-high-below",
    sum(case when o.high >= c.high then 1 else 0 end) as "days-high-above-avg",
    sum(case when o.low >= %s then 1 else 0 end) as "days-lows-above",
    sum(case when o.low < c.low then 1 else 0 end) as "days-lows-below-avg",
    sum(case when o.low < %s then 1 else 0 end) as "days-lows-below"
  from """+table+""" o JOIN climo c on (o.sday = c.sday)
  where station = %s and month in %s
  GROUP by myyear ORDER by myyear ASC
    """, pgconn, params=(nt.sts[station]['ncdc81'], threshold, threshold,
                         threshold, threshold, station, tuple(months)),
                  index_col='myyear')

    data = df[ptype].values
    ctx['data'] = data
    ctx['avgv'] = df[ptype].mean()
    ctx['df'] = df
    # Compute 30 year trailing average
    tavg = [None]*30
    for i in range(30, len(data)):
        tavg.append(np.average(data[i-30:i]))
    ctx['tavg'] = tavg
    # End interval is inclusive
    ctx['a1981_2010'] = df.loc[1981:2010, ptype].mean()
    ctx['ptype'] = ptype
    ctx['station'] = station
    ctx['threshold'] = threshold
    ctx['month'] = month
    ctx['title'] = ("[%s] %s %s-%s"
                    ) % (station, nt.sts[station]['name'],
                         df.index.min(), df.index.max())
    ctx['subtitle'] = ("%s %s"
                       ) % (label, PDICT[ptype])
    if ptype.find("days") == 0 and ptype.find('avg') == -1:
        ctx['subtitle'] += " (%s)" % (threshold,)

    units = "$^\circ$F"
    if ctx['ptype'].find('precip') > 0:
        units = "inches"
    elif ctx['ptype'].find('days') > 0:
        units = "days"
    ctx['ylabel'] = "%s [%s]" % (PDICT[ctx['ptype']], units)
    return ctx
Beispiel #17
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    import matplotlib.colors as mpcolors
    pgconn = get_dbconn('coop')
    ccursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor)

    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    year = ctx['year']
    gdd1 = ctx['gdd1']
    gdd2 = ctx['gdd2']
    table = "alldata_%s" % (station[:2],)
    nt = network.Table("%sCLIMATE" % (station[:2],))

    ccursor.execute("""
    SELECT day, gdd50(high,low) as gdd
    from """+table+""" WHERE year = %s and station = %s
    ORDER by day ASC
    """, (year, station))
    days = []
    gdds = []
    for row in ccursor:
        gdds.append(float(row['gdd']))
        days.append(row['day'])

    yticks = []
    yticklabels = []
    jan1 = datetime.datetime(year, 1, 1)
    for i in range(110, 330):
        ts = jan1 + datetime.timedelta(days=i)
        if ts.day == 1 or ts.day % 12 == 1:
            yticks.append(i)
            yticklabels.append(ts.strftime("%-d %b"))

    gdds = np.array(gdds)
    sts = datetime.datetime(year, 4, 1)
    ets = datetime.datetime(year, 6, 1)
    now = sts
    sz = len(gdds)

    days2 = []
    starts = []
    heights = []
    success = []
    rows = []
    while now < ets:
        idx = int(now.strftime("%j")) - 1
        running = 0
        while idx < sz and running < gdd1:
            running += gdds[idx]
            idx += 1
        idx0 = idx
        while idx < sz and running < gdd2:
            running += gdds[idx]
            idx += 1
        success.append(running >= gdd2)
        idx1 = idx
        days2.append(now)
        starts.append(idx0)
        heights.append(idx1 - idx0)
        rows.append(dict(plant_date=now, start_doy=idx0, end_doy=idx1,
                         success=success[-1]))
        now += datetime.timedelta(days=1)

    if True not in success:
        raise ValueError("No data, pick lower GDD values")
    df = pd.DataFrame(rows)
    heights = np.array(heights)
    success = np.array(success)
    starts = np.array(starts)

    cmap = plt.get_cmap('jet')
    bmin = min(heights[success]) - 1
    bmax = max(heights[success]) + 1
    bins = np.arange(bmin, bmax+1.1)
    norm = mpcolors.BoundaryNorm(bins, cmap.N)

    ax = plt.axes([0.125, 0.125, 0.75, 0.75])
    bars = ax.bar(days2, heights, bottom=starts, fc='#EEEEEE')
    for i, mybar in enumerate(bars):
        if success[i]:
            mybar.set_facecolor(cmap(norm([heights[i]])[0]))
    ax.grid(True)
    ax.set_yticks(yticks)
    ax.set_yticklabels(yticklabels)

    ax.set_ylim(min(starts)-7, max(starts+heights)+7)

    ax.xaxis.set_major_formatter(mdates.DateFormatter('%-d\n%b'))
    ax.set_xlabel("Planting Date")
    ax.set_title(("%s [%s] %s GDD [base=50,ceil=86]\n"
                  "Period between GDD %s and %s, gray bars incomplete"
                  ) % (nt.sts[station]['name'], station, year, gdd1, gdd2))

    ax2 = plt.axes([0.92, 0.1, 0.07, 0.8], frameon=False,
                   yticks=[], xticks=[])
    ax2.set_xlabel("Days")
    for i, mybin in enumerate(bins):
        ax2.text(0.52, i, "%g" % (mybin,), ha='left', va='center',
                          color='k')
        # txt.set_path_effects([PathEffects.withStroke(linewidth=2,
        #                                             foreground="k")])
    ax2.barh(np.arange(len(bins[:-1])), [0.5]*len(bins[:-1]), height=1,
             color=cmap(norm(bins[:-1])),
             ec='None')
    ax2.set_xlim(0, 1)

    return plt.gcf(), df
Beispiel #18
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn("coop")
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx["station"]
    varname = ctx["var"]
    month = ctx["month"]

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    yr = "year as yr"
    if month == "all":
        months = range(1, 13)
    elif month == "fall":
        months = [9, 10, 11]
    elif month == "winter":
        months = [12, 1, 2]
        yr = "extract(year from o.day - '60 days'::interval) as yr"
    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(
        """
      WITH avgs as (
        SELECT sday, avg(high) as avg_high,
        avg(low) as avg_low,
        avg((high+low)/2.) as avg_temp from """ + table + """ WHERE
        station = %s GROUP by sday)

      SELECT """ + yr + """,
      sum(case when o.high > a.avg_high then 1 else 0 end) as high_above,
      sum(case when o.low > a.avg_low then 1 else 0 end) as low_above,
      sum(case when (o.high+o.low)/2. > a.avg_temp then 1 else 0 end)
          as avg_above,
      count(*) as days from """ + table + """ o, avgs a WHERE o.station = %s
      and o.sday = a.sday and month in %s
      GROUP by yr ORDER by yr ASC
    """,
        pgconn,
        params=(station, station, tuple(months)),
        index_col="yr",
    )
    if df.empty:
        raise NoDataFound("No Data Found.")

    df["high_freq"] = df["high_above"] / df["days"].astype("f") * 100.0
    df["low_freq"] = df["low_above"] / df["days"].astype("f") * 100.0
    df["avg_freq"] = df["avg_above"] / df["days"].astype("f") * 100.0

    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))
    avgv = df[varname + "_freq"].mean()

    colorabove = "r"
    colorbelow = "b"
    data = df[varname + "_freq"].values
    bars = ax.bar(df.index.values,
                  data,
                  fc=colorabove,
                  ec=colorabove,
                  align="center")
    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)
    txt = ax.text(
        bars[10].get_x(),
        avgv,
        "Avg: %.1f%%" % (avgv, ),
        color="yellow",
        fontsize=14,
        va="center",
    )
    txt.set_path_effects([PathEffects.withStroke(linewidth=5, foreground="k")])
    ax.set_ylim(0, 100)
    ax.set_yticks([0, 10, 25, 50, 75, 90, 100])
    ax.set_xlabel("Year")
    ax.set_xlim(bars[0].get_x() - 1, bars[-1].get_x() + 1)
    ax.set_ylabel("Frequency [%]")
    ax.grid(True)
    msg = ("[%s] %s %s-%s Percentage of Days with %s Above Average (month=%s)"
           ) % (
               station,
               nt.sts[station]["name"],
               df.index.values.min(),
               df.index.values.max(),
               PDICT[varname],
               month.upper(),
           )
    tokens = msg.split()
    sz = int(len(tokens) / 2)
    ax.set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:]))

    return fig, df
Beispiel #19
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    pgconn = get_dbconn('coop')
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    days = ctx['days']
    sts = datetime.date(2012, ctx['month'], ctx['day'])
    ets = sts + datetime.timedelta(days=(days - 1))
    varname = ctx['varname']
    year = ctx['year']
    threshold = ctx['thres']
    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))
    sdays = []
    for i in range(days):
        ts = sts + datetime.timedelta(days=i)
        sdays.append(ts.strftime("%m%d"))

    doff = (days + 1) if ets.year != sts.year else 0
    df = read_sql("""
    SELECT extract(year from day - '""" + str(doff) +
                  """ days'::interval) as yr,
    avg((high+low)/2.) as avg_temp, avg(high) as avg_high_temp,
    avg(low) as avg_low_temp,
    sum(precip) as precip,
    min(low) as min_low,
    max(high) as max_high,
    sum(case when high >= %s then 1 else 0 end) as "days-high-above",
    sum(case when high < %s then 1 else 0 end) as "days-high-below",
    sum(case when low >= %s then 1 else 0 end) as "days-lows-above",
    sum(case when low < %s then 1 else 0 end) as "days-lows-below"
    from """ + table + """
    WHERE station = %s and sday in %s
    GROUP by yr ORDER by yr ASC
    """,
                  pgconn,
                  params=(threshold, threshold, threshold, threshold, station,
                          tuple(sdays)))

    (fig, ax) = plt.subplots(2, 1, figsize=(8, 6))

    bars = ax[0].bar(df['yr'], df[varname], facecolor='r', edgecolor='r')
    thisvalue = "M"
    for bar, x, y in zip(bars, df['yr'], df[varname]):
        if x == year:
            bar.set_facecolor('g')
            bar.set_edgecolor('g')
            thisvalue = y
    ax[0].set_xlabel("Year, %s = %s" % (year, nice(thisvalue)))
    ax[0].axhline(df[varname].mean(),
                  lw=2,
                  label='Avg: %.2f' % (df[varname].mean(), ))
    ylabel = r"Temperature $^\circ$F"
    if varname in [
            'precip',
    ]:
        ylabel = "Precipitation [inch]"
    elif varname.find('days') > -1:
        ylabel = "Days"
    ax[0].set_ylabel(ylabel)
    title = PDICT.get(varname).replace("(threshold)", str(threshold))
    ax[0].set_title(("[%s] %s\n%s from %s through %s") %
                    (station, nt.sts[station]['name'], title,
                     sts.strftime("%d %b"), ets.strftime("%d %b")),
                    fontsize=12)
    ax[0].grid(True)
    ax[0].legend(ncol=2, fontsize=10)
    ax[0].set_xlim(df['yr'].min() - 1, df['yr'].max() + 1)
    rng = df[varname].max() - df[varname].min()
    if varname == 'precip' or varname.startswith('days'):
        ax[0].set_ylim(-0.1, df[varname].max() + rng * .3)
    else:
        ax[0].set_ylim(df[varname].min() - rng * .3,
                       df[varname].max() + rng * .3)
    box = ax[0].get_position()
    ax[0].set_position([box.x0, box.y0 + 0.02, box.width, box.height * 0.98])

    # Plot 2: CDF
    X2 = np.sort(df[varname])
    ptile = np.percentile(df[varname], [0, 5, 50, 95, 100])
    N = len(df[varname])
    F2 = np.array(range(N)) / float(N) * 100.
    ax[1].plot(X2, 100. - F2)
    ax[1].set_xlabel(ylabel)
    ax[1].set_ylabel("Observed Frequency [%]")
    ax[1].grid(True)
    ax[1].set_yticks([0, 5, 10, 25, 50, 75, 90, 95, 100])
    mysort = df.sort_values(by=varname, ascending=True)
    info = ("Min: %.2f %.0f\n95th: %.2f\nMean: %.2f\nSTD: %.2f\n5th: %.2f\n"
            "Max: %.2f %.0f") % (df[varname].min(), df['yr'][mysort.index[0]],
                                 ptile[1], np.average(df[varname]),
                                 np.std(df[varname]), ptile[3],
                                 df[varname].max(), df['yr'][mysort.index[-1]])
    ax[1].text(0.8,
               0.95,
               info,
               transform=ax[1].transAxes,
               va='top',
               bbox=dict(facecolor='white', edgecolor='k'))
    return fig, df
Beispiel #20
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn("coop")
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx["station"]
    varname = ctx["var"]
    if PDICT.get(varname) is None:
        return

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    df = read_sql(
        """
    with data as (
        select extract(doy from day) as doy,
        day, """ + varname + """ as v from """ + table + """ WHERE
        station = %s),
    doyagg as (
        SELECT doy, stddev(v) from data GROUP by doy),
    deltas as (
        SELECT doy, (v - lag(v) OVER (ORDER by day ASC)) as d from data),
    deltaagg as (
        SELECT doy, stddev(d) from deltas GROUP by doy)

    SELECT d.doy, d.stddev as d2d_stddev,
    y.stddev as doy_stddev from deltaagg d JOIN doyagg y ON
    (y.doy = d.doy) WHERE d.doy < 366 ORDER by d.doy ASC
    """,
        pgconn,
        params=(station, ),
        index_col="doy",
    )

    fig, ax = plt.subplots(2, 1, sharex=True, figsize=(8, 6))
    ax[0].plot(df.index.values,
               df["doy_stddev"],
               lw=2,
               color="r",
               label="Single Day")
    ax[0].plot(df.index.values,
               df["d2d_stddev"],
               lw=2,
               color="b",
               label="Day to Day")
    ax[0].legend(loc="best", fontsize=10, ncol=2)

    ax[0].set_ylabel(r"Temperature Std. Deviation $^\circ$F")
    ax[0].grid(True)

    msg = ("[%s] %s Daily %s Standard Deviations") % (
        station,
        nt.sts[station]["name"],
        PDICT.get(varname),
    )
    tokens = msg.split()
    sz = int(len(tokens) / 2)
    ax[0].set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:]))

    ax[1].plot(df.index.values,
               df["doy_stddev"] / df["d2d_stddev"],
               lw=2,
               color="g")
    ax[1].set_ylabel("Ratio SingleDay/Day2Day")
    ax[1].grid(True)
    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].set_xlim(0, 366)
    return fig, df
Beispiel #21
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    pgconn = psycopg2.connect(database='coop', host='iemdb', user='******')

    station = fdict.get('station', 'IA0000')
    delta = fdict.get('delta', 'abs')
    year = int(fdict.get('year', datetime.date.today().year))
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    table = "alldata_%s" % (station[:2], )
    df = read_sql("""
        WITH days as (
            select generate_series('%s-01-01'::date, '%s-12-31'::date,
                '1 day'::interval)::date as day,
                to_char(generate_series('%s-01-01'::date, '%s-12-31'::date,
                '1 day'::interval)::date, 'mmdd') as sday
        ),
        climo as (
            SELECT sday, avg(high) as avg_high, stddev(high) as stddev_high,
            avg(low) as avg_low, stddev(low) as stddev_low from """ + table +
                  """
            WHERE station = %s GROUP by sday
        ),
        thisyear as (
            SELECT day, sday, high, low from """ + table + """
            WHERE station = %s and year = %s
        ),
        thisyear2 as (
            SELECT d.day, d.sday, t.high, t.low from days d LEFT JOIN
            thisyear t on (d.sday = t.sday)
        )
        SELECT t.day, t.sday, t.high, t.low, c.avg_high, c.avg_low,
        c.stddev_high, c.stddev_low from thisyear2 t JOIN climo c on
        (t.sday = c.sday) ORDER by t.day ASC
    """,
                  pgconn,
                  params=(year, year, year, year, station, station, year),
                  index_col='day')
    df.index.name = 'Date'
    df['high_sigma'] = (df['high'] - df['avg_high']) / df['stddev_high']
    df['low_sigma'] = (df['low'] - df['avg_low']) / df['stddev_low']

    (fig, ax) = plt.subplots(2, 1, sharex=True)

    ax[0].plot(df.index,
               df.avg_high,
               color='r',
               linestyle='-',
               label='Climate High')
    ax[0].plot(df.index, df.avg_low, color='b', label='Climate Low')
    ax[0].set_ylabel(r"Temperature $^\circ\mathrm{F}$")
    ax[0].set_title("[%s] %s Climatology & %s Observations" %
                    (station, nt.sts[station]['name'], year))

    ax[0].plot(df.index, df.high, color='brown', label='%s High' % (year, ))
    ax[0].plot(df.index, df.low, color='green', label='%s Low' % (year, ))

    if delta == 'abs':
        ax[1].plot(df.index,
                   df.high - df.avg_high,
                   color='r',
                   label='High Diff %s - Climate' % (year))
        ax[1].plot(df.index, df.low - df.avg_low, color='b', label='Low Diff')
        ax[1].set_ylabel(r"Temp Difference $^\circ\mathrm{F}$")
    else:
        ax[1].plot(df.index,
                   df.high_sigma,
                   color='r',
                   label='High Diff %s - Climate' % (year))
        ax[1].plot(df.index, df.low_sigma, color='b', label='Low Diff')
        ax[1].set_ylabel(r"Temp Difference $\sigma$")
        ymax = max([df.high_sigma.abs().max(), df.low_sigma.abs().max()]) + 1
        ax[1].set_ylim(0 - ymax, ymax)
    ax[1].legend(fontsize=10, ncol=2, loc='best')
    ax[1].grid(True)

    ax[0].legend(fontsize=10, ncol=2, loc=8)
    ax[0].grid()
    ax[0].xaxis.set_major_locator(mdates.MonthLocator(interval=1))
    ax[0].xaxis.set_major_formatter(mdates.DateFormatter('%-d\n%b'))

    return fig, df
Beispiel #22
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn("coop")
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx["station"]
    month = ctx["month"]
    year = ctx["year"]
    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    df = read_sql(
        """
        SELECT year, sum(precip) as total_precip,
        sum(gddxx(%s, %s, high::numeric,low::numeric)) as gdd from
        """ + table + """
        WHERE station = %s and month = %s GROUP by year
    """,
        pgconn,
        params=(ctx["gddbase"], ctx["gddceil"], station, month),
        index_col="year",
    )
    if len(df.index) < 3:
        raise NoDataFound("ERROR: No Data Found")

    gstats = df.gdd.describe()
    pstats = df.total_precip.describe()

    df["precip_sigma"] = (df.total_precip - pstats["mean"]) / pstats["std"]
    df["gdd_sigma"] = (df.gdd - gstats["mean"]) / gstats["std"]
    df["distance"] = (df.precip_sigma**2 + df.gdd_sigma**2)**0.5

    h_slope, intercept, r_value, _, _ = stats.linregress(
        df["gdd_sigma"], df["precip_sigma"])

    y1 = -4.0 * h_slope + intercept
    y2 = 4.0 * h_slope + intercept
    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))
    ax.set_position([0.1, 0.12, 0.8, 0.78])

    ax.scatter(df["gdd_sigma"], df["precip_sigma"], label=None)
    ax.plot(
        [-4, 4],
        [y1, y2],
        label="Slope=%.2f R$^2$=%.2f" % (h_slope, r_value**2),
    )
    xmax = df.gdd_sigma.abs().max() + 0.25
    ymax = df.precip_sigma.abs().max() + 0.25
    ax.set_xlim(0 - xmax, xmax)
    ax.set_ylim(0 - ymax, ymax)
    events = df.query("distance > 2.5 or year == %.0f" % (year, ))
    for _year, row in events.iterrows():
        ax.text(
            row["gdd_sigma"],
            row["precip_sigma"],
            " %.0f" % (_year, ),
            va="center",
        )

    if year in df.index:
        c = Circle((0, 0), radius=df.loc[year].distance, facecolor="none")
        ax.add_patch(c)
    ax.set_xlabel(("Growing Degree Day (base=%s, ceil=%s) "
                   r"Departure ($\sigma$)") % (ctx["gddbase"], ctx["gddceil"]))
    ax.set_ylabel(r"Precipitation Departure ($\sigma$)")
    ax.grid(True)
    ax.set_title(("%s %s [%s]\n"
                  "Growing Degree Day (base=%s, ceil=%s) "
                  "+ Precipitation Departure") % (
                      calendar.month_name[month],
                      nt.sts[station]["name"],
                      station,
                      ctx["gddbase"],
                      ctx["gddceil"],
                  ))
    ax.legend(loc="lower right",
              bbox_to_anchor=(1.05, 0.01),
              ncol=2,
              fontsize=10)

    return fig, df
Beispiel #23
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn('coop')
    ccursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor)
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    season = ctx['season']
    _ = PDICT2[season]
    startyear = ctx['year']

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    ccursor.execute(
        """
      SELECT extract(year from day + '%s month'::interval) as yr,
      sum(case when month in (12, 1, 2)
      then precip else 0 end) as winter,
      sum(case when month in (3, 4, 5)
      then precip else 0 end) as spring,
      sum(case when month in (6, 7, 8)
      then precip else 0 end) as summer,
      sum(case when month in (9, 10, 11)
      then precip else 0 end) as fall,
      sum(precip) as all
      from """ + table + """ WHERE station = %s GROUP by yr ORDER by yr ASC
    """, (1 if season != 'all' else 0, station))

    today = datetime.datetime.now()
    thisyear = today.year
    if season == 'spring' and today.month > 5:
        thisyear += 1
    rows = []
    for row in ccursor:
        if row['yr'] < startyear:
            continue
        rows.append(dict(year=int(row['yr']), data=float(row[season])))
    df = pd.DataFrame(rows)

    data = np.array(df['data'])
    years = np.array(df['year'])

    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))
    avgv = np.average(data)

    colorabove = 'seagreen'
    colorbelow = 'lightsalmon'
    bars = ax.bar(years, data, fc=colorabove, ec=colorabove, align='center')
    for i, mybar in enumerate(bars):
        if data[i] < avgv:
            mybar.set_facecolor(colorbelow)
            mybar.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: %.2f, slope: %.2f inch/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(0, max(data) + max(data) / 10.)
    ax.set_ylabel("Precipitation [inches]")
    ax.grid(True)
    msg = ("[%s] %s %.0f-%.0f Precipitation [%s] ") % (
        station, nt.sts[station]['name'], min(years), max(years),
        PDICT2[season])
    tokens = msg.split()
    sz = int(len(tokens) / 2)
    ax.set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:]))
    ax.legend(ncol=2, fontsize=10)

    return fig, df
Beispiel #24
0
"""
 Generate a RTP product for the weather bureau as my database as more AWOS
 obs than what they get
"""

import datetime
import pytz
import os
import subprocess
from pyiem.tracker import loadqc
from pyiem import network

nt = network.Table("AWOS")
qdict = loadqc()
import psycopg2
IEM = psycopg2.connect(database='iem', host='iemdb', user='******')
icursor = IEM.cursor()

# We run at 12z
now12z = datetime.datetime.utcnow()
now12z = now12z.replace(hour=12,
                        minute=0,
                        second=0,
                        microsecond=0,
                        tzinfo=pytz.timezone("UTC"))
today6z = now12z.replace(hour=6)
today0z = now12z.replace(hour=0)
yesterday6z = today6z - datetime.timedelta(days=1)
yesterday12z = now12z - datetime.timedelta(days=1)

fmt = "%-6s:%-19s: %3s / %3s / %5s / %4s / %2s\n"
Beispiel #25
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn('coop')
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']

    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))
    today = datetime.datetime.now()
    thisyear = today.year

    df = read_sql("""
    with data as (
        select year, month, extract(doy from day) as doy,
        generate_series(32, high) as t from """ + table + """
        where station = %s and year < %s),
    agger as (
        SELECT year, t, min(doy), max(doy) from data GROUP by year, t)

    SELECT t as tmpf, avg(min) as min_jday,
    avg(max) as max_jday from agger GROUP by t ORDER by t ASC
    """,
                  pgconn,
                  params=(station, thisyear),
                  index_col='tmpf')
    if df.empty:
        raise NoDataFound("No Data Found.")

    fig = plt.figure(figsize=(8, 6))
    ax = plt.axes([0.1, 0.1, 0.7, 0.8])
    ax2 = plt.axes([0.81, 0.1, 0.15, 0.8])
    height = df['min_jday'][:] + 365. - df['max_jday']
    ax2.plot(height, df.index.values)
    ax2.set_xticks([30, 90, 180, 365])
    plt.setp(ax2.get_yticklabels(), visible=False)
    ax2.set_ylim(32, df.index.values.max() + 5)
    ax2.grid(True)
    ax2.text(0.96,
             0.02,
             "Days",
             transform=ax2.transAxes,
             bbox=dict(color='white'),
             ha='right')
    ax.text(0.96,
            0.02,
            "Period",
            transform=ax.transAxes,
            bbox=dict(color='white'),
            ha='right')
    ax.set_ylim(32, df.index.values.max() + 5)

    ax.barh(df.index.values - 0.5,
            height,
            left=df['max_jday'].values,
            ec='tan',
            fc='tan',
            height=1.1)
    days = np.array([1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335])
    days = np.concatenate([days, days + 365])
    ax.set_xticks(days)
    months = calendar.month_abbr[1:] + calendar.month_abbr[1:]
    ax.set_xticklabels(months)

    ax.set_ylabel("High Temperature $^\circ$F")
    ax.set_xlim(min(df['max_jday']) - 1, max(df['max_jday'] + height) + 1)
    ax.grid(True)

    msg = ("[%s] %s Period Between Average Last and "
           "First High Temperature of Year") % (station,
                                                nt.sts[station]['name'])
    tokens = msg.split()
    sz = int(len(tokens) / 2)
    ax.set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:]))

    return fig, df
Beispiel #26
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    from matplotlib.patches import Circle
    pgconn = psycopg2.connect(database='coop', host='iemdb', user='******')

    station = fdict.get('station', 'IA0000')
    month = int(fdict.get('month', 7))
    year = int(fdict.get('year', datetime.datetime.now().year))
    table = "alldata_%s" % (station[:2],)
    nt = network.Table("%sCLIMATE" % (station[:2],))

    df = read_sql("""
        SELECT year, sum(precip) as total_precip,
        sum(gdd50(high::numeric,low::numeric)) as gdd50 from """+table+"""
        WHERE station = %s and month = %s GROUP by year
    """, pgconn, params=(station, month), index_col='year')
    if len(df.index) == 0:
        return "ERROR: No Data Found"

    gstats = df.gdd50.describe()
    pstats = df.total_precip.describe()

    df['precip_sigma'] = (df.total_precip - pstats['mean']) / pstats['std']
    df['gdd50_sigma'] = (df.gdd50 - gstats['mean']) / gstats['std']
    df['distance'] = (df.precip_sigma ** 2 + df.gdd50_sigma ** 2) ** 0.5

    h_slope, intercept, r_value, _, _ = stats.linregress(df['gdd50_sigma'],
                                                         df['precip_sigma'])

    y1 = -4.0 * h_slope + intercept
    y2 = 4.0 * h_slope + intercept
    ax = plt.axes([0.1, 0.12, 0.8, 0.78])

    ax.scatter(df['gdd50_sigma'], df['precip_sigma'], label=None)
    ax.plot([-4, 4], [y1, y2], label="Slope=%.2f\nR$^2$=%.2f" % (h_slope,
                                                                 r_value ** 2))
    xmax = df.gdd50_sigma.abs().max() + 0.25
    ymax = df.precip_sigma.abs().max() + 0.25
    ax.set_xlim(0 - xmax, xmax)
    ax.set_ylim(0 - ymax, ymax)
    events = df.query("distance > 2.5 or year == %.0f" % (year, ))
    for _year, row in events.iterrows():
        ax.text(row['gdd50_sigma'], row['precip_sigma'],
                ' %.0f' % (_year,), va='center')

    if year in df.index:
        c = Circle((0, 0), radius=df.loc[year].distance, facecolor='none')
        ax.add_patch(c)
    ax.set_xlabel("Growing Degree Day Departure ($\sigma$)")
    ax.set_ylabel("Precipitation Departure ($\sigma$)")
    ax.grid(True)
    ax.set_title(("%s %s [%s]\n"
                  "Growing Degree Day (base=50) + Precipitation Departure"
                  ) % (
        calendar.month_name[month], nt.sts[station]['name'], station))
    ax.legend(loc='upper right', bbox_to_anchor=(0.99, -0.04),
              ncol=2, fontsize=10)

    return plt.gcf(), df
Beispiel #27
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn('coop')

    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    season = ctx['season']
    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    df = read_sql("""
    WITH obs as (
        SELECT day, year, month, high, low,
        case when month > 6 then 'fall' else 'spring' end as season
        from """ + table + """ WHERE station = %s),
    data as (
        SELECT year, day, season,
        max(high) OVER (PARTITION by year, season ORDER by day ASC
                        ROWS BETWEEN 183 PRECEDING and CURRENT ROW) as mh,
        min(low) OVER (PARTITION by year, season ORDER by day ASC
                       ROWS BETWEEN 183 PRECEDING and CURRENT ROW) as ml
        from obs),
    lows as (
        SELECT year, day, ml as level, season,
        rank() OVER (PARTITION by year, ml ORDER by day ASC) from data
        WHERE season = 'fall'),
    highs as (
        SELECT year, day, mh as level, season,
        rank() OVER (PARTITION by year, mh ORDER by day ASC) from data
        WHERE season = 'spring')

    (SELECT year, day, extract(doy from day) as doy,
     level, season from lows WHERE rank = 1) UNION
    (SELECT year, day, extract(doy from day) as doy,
     level, season from highs WHERE rank = 1)
    """,
                  pgconn,
                  params=[station])
    df2 = df[df['season'] == season]
    (fig, ax) = plt.subplots(3, 1, figsize=(7, 10))
    dyear = df2.groupby(['year']).count()
    ax[0].bar(dyear.index, dyear['level'], facecolor='tan', edgecolor='tan')
    ax[0].axhline(dyear['level'].mean(), lw=2)
    ax[0].set_ylabel("Yearly Events Avg: %.1f" % (dyear['level'].mean(), ))
    ax[0].set_xlim(dyear.index.min() - 1, dyear.index.max() + 1)
    title = "%s Steps %s" % (PDICT[season],
                             "Down" if season == 'fall' else 'Up')
    ax[0].set_title("%s [%s]\n%s in Temperature" %
                    (nt.sts[station]['name'], station, title))
    ax[0].grid(True)

    ax[1].hist(np.array(df2['level'], 'f'),
               bins=np.arange(df2['level'].min(), df2['level'].max() + 1, 2),
               normed=True,
               facecolor='tan')
    ax[1].set_ylabel("Probability Density")
    ax[1].axvline(32, lw=2)
    ax[1].grid(True)
    ax[1].set_xlabel(r"Temperature $^\circ$F, 32 degrees highlighted")

    ax[2].hist(np.array(df2['doy'], 'f'),
               bins=np.arange(df2['doy'].min(), df2['doy'].max() + 1, 3),
               normed=True,
               facecolor='tan')
    ax[2].set_xticks(
        (1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 365))
    ax[2].set_xticklabels(calendar.month_abbr[1:])
    ax[2].set_xlim(df2['doy'].min() - 3, df2['doy'].max() + 3)

    ax[2].set_ylabel("Probability Density")
    ax[2].grid(True)
    ax[2].set_xlabel("Day of Year, 3 Day Bins")

    return fig, df
Beispiel #28
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    pgconn = get_dbconn('coop')
    ctx = get_autoplot_context(fdict, get_description())

    station = ctx['station']
    varname = ctx['var']
    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))

    tokens = varname.split("_")
    orderer = "(high - low)"
    if tokens[1] != 'range':
        orderer = tokens[1]

    if tokens[0] == 'min':
        orderer += " ASC"
    else:
        orderer += " DESC"
    df = read_sql("""
    WITH ranks as (
        SELECT month, day, high, low, precip, snow,
        rank() OVER (PARTITION by month ORDER by """ + orderer +
                  """ NULLS LAST)
        from """ + table + """ WHERE station = %s)

    select month, to_char(day, 'Mon dd, YYYY') as dd, high, low, precip, snow,
    (high - low) as range from ranks
    WHERE rank = 1 ORDER by month ASC, day DESC
    """,
                  pgconn,
                  params=(station, ),
                  index_col='month')
    labels = []
    ranges = []
    months = []
    for i, row in df.iterrows():
        if i in months:
            if labels[-1].endswith("*"):
                continue
            labels[-1] += " *"
            continue
        months.append(i)
        if tokens[1] == 'range':
            labels.append("%s (%s/%s) - %s" %
                          (row[tokens[1]], row['high'], row['low'], row['dd']))
        else:
            labels.append("%s - %s" % (row[tokens[1]], row['dd']))
        ranges.append(row[tokens[1]])

    (fig, ax) = plt.subplots(1, 1, figsize=(8, 6))

    ax.barh(np.arange(1, 13), ranges, align='center')
    ax.set_yticklabels(calendar.month_name)
    ax.set_yticks(range(0, 13))
    ax.set_ylim(0, 13)
    ax.set_xlabel(("Date most recently set/tied shown, "
                   "* indicates ties are present"))
    fig.text(0.5,
             0.99,
             "%s [%s]\n%s by Month" %
             (nt.sts[station]['name'], station, PDICT[varname]),
             transform=ax.transAxes,
             ha='center',
             fontsize=14,
             va='top')

    box = ax.get_position()
    ax.set_position([box.x0, box.y0, box.width * 0.7, box.height])
    ax.grid(True)

    ax2 = ax.twinx()
    ax2.set_yticks(range(1, 13))
    ax2.set_yticklabels(labels)
    ax2.set_position([box.x0, box.y0, box.width * 0.7, box.height])
    ax2.set_ylim(0, 13)

    return fig, df
Beispiel #29
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    pgconn = get_dbconn('coop')
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    threshold = ctx['thres']
    use_trace = (ctx['trace'] == 'yes')
    table = "alldata_%s" % (station[:2],)
    nt = network.Table("%sCLIMATE" % (station[:2],))

    df = read_sql("""
    with data as (
      select sday, day, precip from """ + table + """
      where station = %s),

    rains as (
      SELECT day from """ + table + """ WHERE station = %s and precip >= %s),

    rains2 as (
      SELECT day from """ + table + """ WHERE station = %s and precip >= %s),

    agg as (
      SELECT d.sday, d.day, d.precip, r.day as rday
      from data d LEFT JOIN rains r ON (d.day = r.day)),

    agg2 as (
      SELECT d.sday, d.day, d.precip, d.rday, r.day as rday2 from
      agg d LEFT JOIN rains2 r ON (d.day = r.day)),

    agg3 as (
      SELECT sday, precip, day - max(rday) OVER (ORDER by day ASC) as diff,
      day - max(rday2) OVER (ORDER by day ASC) as diff2 from agg2)

    SELECT sday, max(precip) as maxp, max(diff) as d1, max(diff2) as d2
    from agg3 WHERE sday != '0229'
    GROUP by sday ORDER by sday ASC
    """, pgconn, params=(station, station,
                         0.0001 if use_trace else 0.01, station, threshold),
                  index_col='sday')

    (fig, ax) = plt.subplots(2, 1, sharex=True)

    ax[0].plot(np.arange(1, 366), df['d1'], c='r', label='No Rain')
    ax[0].plot(np.arange(1, 366), df['d2'], c='b',
               label='Below %.2fin' % (threshold,))
    ax[0].set_ylabel("Consec Days below threshold")
    ax[0].grid(True)
    ax[0].legend(ncol=2, loc=(0.5, -0.13), fontsize=10)
    ax[0].set_title("%s [%s] Precipitation Metrics" % (nt.sts[station]['name'],
                                                       station))
    ax[0].text(0.05, -0.09,
               "Trace Reports %s" % ('Included' if use_trace else 'Excluded',),
               transform=ax[0].transAxes, ha='left')

    ax[1].bar(np.arange(1, 366), df['maxp'], edgecolor='b', facecolor='b')
    ax[1].set_ylabel("Max 24 Hour Precip [inch]")
    ax[1].set_xlim(0.5, 366.5)
    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, df
Beispiel #30
0
def plotter(fdict):
    """ Go """
    import matplotlib
    matplotlib.use('agg')
    import matplotlib.pyplot as plt
    pgconn = psycopg2.connect(database='coop', host='iemdb', user='******')

    today = datetime.date.today()
    ctx = util.get_autoplot_context(fdict, get_description())
    station = ctx['station']
    threshold = ctx['threshold']
    month1 = ctx['month1']
    varname1 = ctx['var1']
    num1 = min([12, ctx['num1']])
    month2 = ctx['month2']
    varname2 = ctx['var2']
    num2 = min([12, ctx['num2']])
    months1, offsets1 = compute_months_and_offsets(month1, num1)
    months2, offsets2 = compute_months_and_offsets(month2, num2)
    table = "alldata_%s" % (station[:2], )
    nt = network.Table("%sCLIMATE" % (station[:2], ))
    # Compute the monthly totals
    df = read_sql("""
    SELECT year, month, avg((high+low)/2.) as avg_temp,
    sum(precip) as total_precip, max(high) as max_high,
    sum(case when high >= %s then 1 else 0 end) as days_high_aoa,
    sum(gddxx(50, 86, high, low)) as gdd50
    from """ + table + """
    WHERE station = %s and day < %s GROUP by year, month
    """,
                  pgconn,
                  params=(threshold, station, today.replace(day=1)),
                  index_col='year')

    xdf = combine(df, months1, offsets1)
    ydf = combine(df, months2, offsets2)

    resdf = pd.DataFrame({
        "%s_1" % (varname1, ): xdf[varname1],
        "%s_2" % (varname2, ): ydf[varname2]
    })
    resdf.dropna(inplace=True)
    (fig, ax) = plt.subplots(1, 1)
    ax.scatter(resdf[varname1 + "_1"],
               resdf[varname2 + "_2"],
               marker='s',
               facecolor='b',
               edgecolor='b',
               label=None,
               zorder=3)
    ax.set_title(
        ("%s-%s %s [%s]\n"
         "Comparison of Monthly Periods, Quadrant Frequency Labelled") %
        (resdf.index.min(), resdf.index.max(), nt.sts[station]['name'],
         station))
    ax.grid(True)

    h_slope, intercept, r_value, _, _ = stats.linregress(
        resdf[varname1 + "_1"], resdf[varname2 + "_2"])
    y = h_slope * np.arange(resdf[varname1 + "_1"].min(),
                            resdf[varname1 + "_1"].max()) + intercept
    ax.plot(np.arange(resdf[varname1 + "_1"].min(),
                      resdf[varname1 + "_1"].max()),
            y,
            lw=2,
            color='r',
            label="Slope=%.2f R$^2$=%.2f" % (h_slope, r_value**2))
    ax.legend(fontsize=10)
    xmonths = ", ".join([calendar.month_abbr[x] for x in months1])
    ymonths = ", ".join([calendar.month_abbr[x] for x in months2])
    t1 = "" if varname1 not in [
        'days_high_aoa',
    ] else " %.0f" % (threshold, )
    t2 = "" if varname2 not in [
        'days_high_aoa',
    ] else " %.0f" % (threshold, )
    x = resdf["%s_1" % (varname1, )].mean()
    y = resdf["%s_2" % (varname2, )].mean()
    ax.set_xlabel("%s\n%s%s [%s], Avg: %.1f" %
                  (xmonths, PDICT[varname1], t1, UNITS[varname1], x),
                  fontsize=12)
    ax.set_ylabel("%s\n%s%s [%s], Avg: %.1f" %
                  (ymonths, PDICT[varname2], t2, UNITS[varname2], y),
                  fontsize=12)

    box = ax.get_position()
    ax.set_position(
        [box.x0, box.y0 + box.height * 0.05, box.width, box.height * 0.95])
    ax.axhline(y, linestyle='--', color='g')
    ax.axvline(x, linestyle='--', color='g')
    ur = len(resdf[(resdf["%s_1" % (varname1, )] >= x)
                   & (resdf["%s_2" % (varname2, )] >= y)].index)
    ax.text(0.95,
            0.75,
            "%s (%.1f%%)" % (ur, ur / float(len(resdf.index)) * 100.),
            color='tan',
            fontsize=24,
            transform=ax.transAxes,
            ha='right',
            zorder=2)
    lr = len(resdf[(resdf["%s_1" % (varname1, )] >= x)
                   & (resdf["%s_2" % (varname2, )] < y)].index)
    ax.text(0.95,
            0.25,
            "%s (%.1f%%)" % (lr, lr / float(len(resdf.index)) * 100.),
            color='tan',
            fontsize=24,
            transform=ax.transAxes,
            ha='right',
            zorder=2)
    ll = len(resdf[(resdf["%s_1" % (varname1, )] < x)
                   & (resdf["%s_2" % (varname2, )] < y)].index)
    ax.text(0.05,
            0.25,
            "%s (%.1f%%)" % (ll, ll / float(len(resdf.index)) * 100.),
            color='tan',
            fontsize=24,
            transform=ax.transAxes,
            ha='left',
            zorder=2)
    ul = len(resdf[(resdf["%s_1" % (varname1, )] < x)
                   & (resdf["%s_2" % (varname2, )] >= y)].index)
    ax.text(0.05,
            0.75,
            "%s (%.1f%%)" % (ul, ul / float(len(resdf.index)) * 100.),
            color='tan',
            fontsize=24,
            transform=ax.transAxes,
            ha='left',
            zorder=2)
    return fig, resdf