Esempio n. 1
0
def plotter(fdict):
    """ Go """
    ctx = get_autoplot_context(fdict, get_description())
    df = get_data(ctx)

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

    ax.scatter(df['snow_doy'], df['snowfall'], facecolor=df['color'],
               edgecolor=df['color'], s=100)
    for _, row in df.iterrows():
        ax.scatter(row['snowfree_doy'], row['snowfall'], marker='x', s=100,
                   color=row['color'])
        ax.plot([row['snow_doy'], row['snowfree_doy']],
                [row['snowfall'], row['snowfall']], lw='2', color=row['color'])
    ax.set_xticks([1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335,
                   1 + 366, 32 + 366, 60 + 366, 91 + 366, 121 + 366,
                   152 + 366, 182 + 366, 213 + 366, 244 + 366, 274 + 366,
                   305 + 366, 335 + 366])
    ax.set_xticklabels(calendar.month_abbr[1:] + calendar.month_abbr[1:])
    ax.grid(True)
    ax.set_ylim(bottom=0)
    ax2 = ax.twinx()
    ptile = np.percentile(df['snow_doy'].values, np.arange(100))
    ax2.plot(ptile, np.arange(100), lw=2, color='k')
    ax2.set_ylabel(("Frequency of %s Date (CDF) [%%] (black line)"
                    ) % ('Start' if ctx['dir'] == 'first' else 'Last', ))
    ax.set_ylabel('Snowfall [inch], Avg: %.1f inch' % (df['snowfall'].mean(),))
    ax.set_title(
        ('[%s] %s %s %s Snowfall\n(color is how long snow remained)'
         ) % (ctx['station'], ctx['nt'].sts[ctx['station']]['name'],
              'Last' if ctx['dir'] == 'last' else 'First',
              ('Trace+' if ctx['threshold'] < 0.1
               else "%.2f+ Inch" % (ctx['threshold'],))))
    p0 = plt.Rectangle((0, 0), 1, 1, fc="purple")
    p1 = plt.Rectangle((0, 0), 1, 1, fc="g")
    p2 = plt.Rectangle((0, 0), 1, 1, fc="b")
    p3 = plt.Rectangle((0, 0), 1, 1, fc="r")
    ax.legend((p0, p1, p2, p3), (
        '> 31 days [%s]' % (len(df[df['color'] == 'purple'].index), ),
        '10 - 31 [%s]' % (len(df[df['color'] == 'g'].index), ),
        '3 - 10 [%s]' % (len(df[df['color'] == 'b'].index), ),
        '< 3 days [%s]' % (len(df[df['color'] == 'r'].index), )),
              ncol=4, fontsize=11, loc=(0., -0.15))
    ax.set_xlim(df['snow_doy'].min() - 5, df['snowfree_doy'].max() + 5)

    box = ax.get_position()
    ax.set_position([box.x0, box.y0 + box.height * 0.1, box.width,
                     box.height * 0.9])
    ax2.set_position([box.x0, box.y0 + box.height * 0.1, box.width,
                     box.height * 0.9])
    ax2.set_yticks([0, 5, 10, 25, 50, 75, 90, 95, 100])
    ax2.set_ylim(0, 101)
    df.set_index('year', inplace=True)
    del df['color']
    return fig, df
Esempio n. 2
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn("coop")
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx["station"]
    month1 = ctx["month1"]
    month2 = ctx["month2"]
    highlight = ctx["highlight"]
    varname = ctx["var"]
    p1 = ctx.get("p1")
    p2 = ctx.get("p2")
    days = ctx["days"]
    opt = ctx["opt"]

    table = "alldata_%s" % (station[:2], )

    m1data, y1, y2 = get_data(pgconn, table, station, month1, p1, varname,
                              days, opt)
    m2data, y3, y4 = get_data(pgconn, table, station, month2, p2, varname,
                              days, opt)

    pc1 = np.percentile(m1data, range(0, 101, 1))
    pc2 = np.percentile(m2data, range(0, 101, 1))
    df = pd.DataFrame({
        "%s_%s_%s_%s" % (MDICT[month1], varname, y1, y2):
        pd.Series(pc1),
        "%s_%s_%s_%s" % (MDICT[month2], varname, y3, y4):
        pd.Series(pc2),
        "quantile":
        pd.Series(range(0, 101, 5)),
    })
    s_slp, s_int, s_r, _, _ = stats.linregress(pc1, pc2)

    fig = plt.gcf()
    fig.set_size_inches(10.24, 7.68)
    ax = plt.axes([0.1, 0.11, 0.4, 0.76])
    ax.scatter(pc1[::5], pc2[::5], s=40, marker="s", color="b", zorder=3)
    ax.plot(
        pc1,
        pc1 * s_slp + s_int,
        lw=3,
        color="r",
        zorder=2,
        label=r"Fit R$^2$=%.2f" % (s_r**2, ),
    )
    ax.axvline(highlight, zorder=1, color="k")
    y = highlight * s_slp + s_int
    ax.axhline(y, zorder=1, color="k")
    ax.text(
        pc1[0],
        y,
        r"%.0f $^\circ$F" % (y, ),
        va="center",
        bbox=dict(color="white"),
    )
    ax.text(
        highlight,
        pc2[0],
        r"%.0f $^\circ$F" % (highlight, ),
        ha="center",
        rotation=90,
        bbox=dict(color="white"),
    )
    t2 = PDICT[varname]
    if days > 1:
        t2 = "%s %s over %s days" % (ODICT[opt], PDICT[varname], days)
    fig.suptitle(("[%s] %s\n%s (%s-%s) vs %s (%s-%s)\n%s") % (
        station,
        ctx["_nt"].sts[station]["name"],
        MDICT[month2],
        y1,
        y2,
        MDICT[month1],
        y3,
        y4,
        t2,
    ))
    ax.set_xlabel(r"%s (%s-%s) %s $^\circ$F" %
                  (MDICT[month1], y1, y2, PDICT[varname]))
    ax.set_ylabel(r"%s (%s-%s) %s $^\circ$F" %
                  (MDICT[month2], y3, y4, PDICT[varname]))
    ax.text(
        0.95,
        0.05,
        "Quantile - Quantile Plot",
        transform=ax.transAxes,
        ha="right",
    )
    ax.grid(True)
    ax.legend(loc=2)

    # Second
    ax = plt.axes([0.55, 0.18, 0.27, 0.68])
    ax.set_title("Distribution")
    v1 = ax.violinplot(m1data, positions=[0], showextrema=True, showmeans=True)
    b = v1["bodies"][0]
    m = np.mean(b.get_paths()[0].vertices[:, 0])
    b.get_paths()[0].vertices[:, 0] = np.clip(b.get_paths()[0].vertices[:, 0],
                                              -np.inf, m)
    b.set_color("r")
    for lbl in ["cmins", "cmeans", "cmaxes"]:
        v1[lbl].set_color("r")

    v1 = ax.violinplot(m2data, positions=[0], showextrema=True, showmeans=True)
    b = v1["bodies"][0]
    m = np.mean(b.get_paths()[0].vertices[:, 0])
    b.get_paths()[0].vertices[:, 0] = np.clip(b.get_paths()[0].vertices[:, 0],
                                              m, np.inf)
    b.set_color("b")
    for lbl in ["cmins", "cmeans", "cmaxes"]:
        v1[lbl].set_color("b")

    pr0 = plt.Rectangle((0, 0), 1, 1, fc="r")
    pr1 = plt.Rectangle((0, 0), 1, 1, fc="b")
    ax.legend(
        (pr0, pr1),
        (
            r"%s (%s-%s), $\mu$=%.1f" %
            (MDICT[month1], y1, y2, np.mean(m1data)),
            r"%s (%s-%s), $\mu$=%.1f" %
            (MDICT[month2], y3, y4, np.mean(m2data)),
        ),
        ncol=1,
        loc=(0.5, -0.15),
    )
    ax.set_ylabel(r"%s $^\circ$F" % (PDICT[varname], ))
    ax.grid()

    # Third
    monofont = FontProperties(family="monospace")
    y = 0.86
    x = 0.83
    col1 = "%s_%s_%s_%s" % (MDICT[month1], varname, y1, y2)
    col2 = "%s_%s_%s_%s" % (MDICT[month2], varname, y3, y4)
    fig.text(x, y + 0.04, "Percentile Data    Diff")
    for percentile in [
            100,
            99,
            98,
            97,
            96,
            95,
            92,
            90,
            75,
            50,
            25,
            10,
            8,
            5,
            4,
            3,
            2,
            1,
    ]:
        row = df.loc[percentile]
        fig.text(x, y, "%3i" % (percentile, ), fontproperties=monofont)
        fig.text(
            x + 0.025,
            y,
            "%5.1f" % (row[col1], ),
            fontproperties=monofont,
            color="r",
        )
        fig.text(
            x + 0.07,
            y,
            "%5.1f" % (row[col2], ),
            fontproperties=monofont,
            color="b",
        )
        fig.text(
            x + 0.11,
            y,
            "%5.1f" % (row[col2] - row[col1], ),
            fontproperties=monofont,
        )
        y -= 0.04

    return fig, df
Esempio n. 3
0
def plotter(fdict):
    """ Go """
    ctx = get_autoplot_context(fdict, get_description())
    df = get_data(ctx)

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

    ax.scatter(
        df["snow_doy"],
        df["snowfall"],
        facecolor=df["color"],
        edgecolor=df["color"],
        s=100,
    )
    for _, row in df.iterrows():
        ax.scatter(
            row["snowfree_doy"],
            row["snowfall"],
            marker="x",
            s=100,
            color=row["color"],
        )
        ax.plot(
            [row["snow_doy"], row["snowfree_doy"]],
            [row["snowfall"], row["snowfall"]],
            lw="2",
            color=row["color"],
        )
    ax.set_xticks([
        1,
        32,
        60,
        91,
        121,
        152,
        182,
        213,
        244,
        274,
        305,
        335,
        1 + 366,
        32 + 366,
        60 + 366,
        91 + 366,
        121 + 366,
        152 + 366,
        182 + 366,
        213 + 366,
        244 + 366,
        274 + 366,
        305 + 366,
        335 + 366,
    ])
    ax.set_xticklabels(calendar.month_abbr[1:] + calendar.month_abbr[1:])
    ax.grid(True)
    ax.set_ylim(bottom=0)
    ax2 = ax.twinx()
    ptile = np.percentile(df["snow_doy"].values, np.arange(100))
    ax2.plot(ptile, np.arange(100), lw=2, color="k")
    ax2.set_ylabel(("Frequency of %s Date (CDF) [%%] (black line)") %
                   ("Start" if ctx["dir"] == "first" else "Last", ))
    ax.set_ylabel("Snowfall [inch], Avg: %.1f inch" %
                  (df["snowfall"].mean(), ))
    ax.set_title(
        ("[%s] %s %s %s Snowfall\n(color is how long snow remained)") % (
            ctx["station"],
            ctx["_nt"].sts[ctx["station"]]["name"],
            "Last" if ctx["dir"] == "last" else "First",
            ("Trace+" if ctx["threshold"] == "T" else "%.2f+ Inch" %
             (float(ctx["threshold"]), )),
        ))
    p0 = plt.Rectangle((0, 0), 1, 1, fc="purple")
    p1 = plt.Rectangle((0, 0), 1, 1, fc="g")
    p2 = plt.Rectangle((0, 0), 1, 1, fc="b")
    p3 = plt.Rectangle((0, 0), 1, 1, fc="r")
    ax.legend(
        (p0, p1, p2, p3),
        (
            "> 31 days [%s]" % (len(df[df["color"] == "purple"].index), ),
            "10 - 31 [%s]" % (len(df[df["color"] == "g"].index), ),
            "3 - 10 [%s]" % (len(df[df["color"] == "b"].index), ),
            "< 3 days [%s]" % (len(df[df["color"] == "r"].index), ),
        ),
        ncol=4,
        fontsize=11,
        loc=(0.0, -0.15),
    )
    ax.set_xlim(df["snow_doy"].min() - 5, df["snowfree_doy"].max() + 5)

    box = ax.get_position()
    ax.set_position(
        [box.x0, box.y0 + box.height * 0.1, box.width, box.height * 0.9])
    ax2.set_position(
        [box.x0, box.y0 + box.height * 0.1, box.width, box.height * 0.9])
    ax2.set_yticks([0, 5, 10, 25, 50, 75, 90, 95, 100])
    ax2.set_ylim(0, 101)
    df.set_index("year", inplace=True)
    del df["color"]
    return fig, df
Esempio n. 4
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn('isuag')
    ctx = get_autoplot_context(fdict, get_description())
    threshold = 50
    threshold_c = temperature(threshold, 'F').value('C')
    hours1 = ctx['hours1']
    hours2 = ctx['hours2']
    station = ctx['station']
    oldstation = XREF[station]

    df = read_sql("""
    with obs as (
        select valid, c300, lag(c300) OVER (ORDER by valid ASC) from hourly
        where station = %s),
    agg1 as (
        select valid,
        case when c300 > %s and lag < %s then 1
             when c300 < %s and lag > %s then -1
             else 0 end as t from obs),
    agg2 as (
        SELECT valid, t from agg1 where t != 0),
    agg3 as (
        select valid, lead(valid) OVER (ORDER by valid ASC),
        t from agg2),
    agg4 as (
        select extract(year from valid) as yr, valid, lead,
        rank() OVER (PARTITION by extract(year from valid) ORDER by valid ASC)
        from agg3 where t = 1
        and (lead - valid) >= '%s hours'::interval),
    agg5 as (
        select extract(year from valid) as yr, valid, lead
        from agg3 where t = -1)

    select f.yr, f.valid as fup, f.lead as flead, d.valid as dup,
    d.lead as dlead from agg4 f JOIN agg5 d ON (f.yr = d.yr)
    where f.rank = 1 and d.valid > f.valid
    ORDER by fup ASC
    """,
                  pgconn,
                  params=(oldstation, threshold, threshold, threshold,
                          threshold, hours1),
                  index_col=None)
    if df.empty:
        raise ValueError("No Data Found")

    df2 = read_sql("""
    with obs as (
        select valid, tsoil_c_avg,
        lag(tsoil_c_avg) OVER (ORDER by valid ASC) from sm_hourly
        where station = %s),
    agg1 as (
        select valid,
        case when tsoil_c_avg > %s and lag < %s then 1
             when tsoil_c_avg < %s and lag > %s then -1
             else 0 end as t from obs),
    agg2 as (
        SELECT valid, t from agg1 where t != 0),
    agg3 as (
        select valid, lead(valid) OVER (ORDER by valid ASC),
        t from agg2),
    agg4 as (
        select extract(year from valid) as yr, valid, lead,
        rank() OVER (PARTITION by extract(year from valid) ORDER by valid ASC)
        from agg3 where t = 1
        and (lead - valid) >= '%s hours'::interval),
    agg5 as (
        select extract(year from valid) as yr, valid, lead
        from agg3 where t = -1)

    select f.yr, f.valid as fup, f.lead as flead, d.valid as dup,
    d.lead as dlead from agg4 f JOIN agg5 d ON (f.yr = d.yr)
    where f.rank = 1 and d.valid > f.valid
    ORDER by fup ASC
    """,
                   pgconn,
                   params=(station, threshold_c, threshold_c, threshold_c,
                           threshold_c, hours1),
                   index_col=None)
    if df2.empty:
        raise ValueError("No Data Found")

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

    d2000 = utc(2000, 1, 1, 6)
    for d in [df, df2]:
        for _, row in d.iterrows():
            if row['dlead'] is None:
                continue
            f0 = (row['fup'].replace(year=2000) - d2000).total_seconds()
            f1 = (row['flead'].replace(year=2000) - d2000).total_seconds()
            d0 = (row['dup'].replace(year=2000) - d2000).total_seconds()
            d1 = (row['dlead'].replace(year=2000) - d2000).total_seconds()
            if d1 < d0:
                continue
            ax.barh(row['fup'].year, (f1 - f0),
                    left=f0,
                    facecolor='r',
                    align='center',
                    edgecolor='r')
            color = 'lightblue' if (d1 - d0) < (hours2 * 3600) else 'b'
            ax.barh(row['fup'].year, (d1 - d0),
                    left=d0,
                    facecolor=color,
                    align='center',
                    edgecolor=color)

    xticks = []
    xticklabels = []
    for i in range(1, 13):
        d2 = d2000.replace(month=i)
        xticks.append((d2 - d2000).total_seconds())
        xticklabels.append(d2.strftime("%-d %b"))
    ax.set_xticks(xticks)
    ax.set_xticklabels(xticklabels)
    ax.set_xlim(xticks[2], xticks[6])
    ax.grid(True)

    nt = NetworkTable("ISUSM")
    nt2 = NetworkTable("ISUAG")
    ax.set_title(
        ("[%s] %s 4 Inch Soil Temps\n[%s] %s used for pre-%s dates") %
        (station, nt.sts[station]['name'], oldstation,
         nt2.sts[oldstation]['name'], nt.sts[station]['archive_begin'].year))
    ax.set_ylim(df['yr'].min() - 1, df2['yr'].max() + 1)

    p0 = plt.Rectangle((0, 0), 1, 1, fc="r")
    p1 = plt.Rectangle((0, 0), 1, 1, fc="lightblue")
    p2 = plt.Rectangle((0, 0), 1, 1, fc="b")
    ax.legend((p0, p1, p2),
              ('First Period Above %s for %s+ Hours' %
               (threshold, hours1), 'Below %s for 1+ Hours' %
               (threshold, ), 'Below %s for %s+ Hours' % (threshold, hours2)),
              ncol=2,
              fontsize=11,
              loc=(0., -0.2))
    box = ax.get_position()
    ax.set_position(
        [box.x0, box.y0 + box.height * 0.1, box.width, box.height * 0.9])

    return fig, df
Esempio n. 5
0
    def plot_values(self, lons, lats, vals, fmt='%s', valmask=None,
                    color='#000000', textsize=14, labels=None,
                    labeltextsize=10, labelcolor='#000000',
                    showmarker=False, labelbuffer=25, outlinecolor='#FFFFFF'):
        """Plot values onto the map

        Args:
          lons (list): longitude values to use for placing `vals`
          lats (list): latitude values to use for placing `vals`
          vals (list): actual values to place on the map
          fmt (str, optional): Format specification to use for representing the
            values. For example, the default is '%s'.
          valmask (list, optional): Boolean list to use as masking of the
            `vals` while adding to the map.
          color (str, list, optional): Color to use while plotting the `vals`.
            This can be a list to specify each color to use with each value.
          textsize (str, optional): Font size to draw text.
            labels (list, optional): Optional list of labels to place below the
            plotting of `vals`
          labeltextsize (int, optional): Size of the label text
          labelcolor (str, optional): Color to use for drawing labels
          showmarker (bool, optional): Place a marker on the map for the label
          labelbuffer (int): pixel buffer around labels
          outlinecolor (color): color to use for text outlines
        """
        if valmask is None:
            valmask = [True] * len(lons)
        if labels is None:
            labels = [''] * len(lons)
        if isinstance(color, str):
            color = [color] * len(lons)
        bbox = self.fig.get_window_extent().transformed(
            self.fig.dpi_scale_trans.inverted())
        axbbox = self.ax.get_window_extent().transformed(
            self.fig.dpi_scale_trans.inverted())
        axx0 = axbbox.x0 * self.fig.dpi
        axx1 = (axbbox.x0 + axbbox.width) * self.fig.dpi
        axy0 = axbbox.y0 * self.fig.dpi
        axy1 = (axbbox.y0 + axbbox.height) * self.fig.dpi
        figwidth = bbox.width * self.fig.dpi
        figheight = bbox.height * self.fig.dpi
        if self.textmask is None:
            self.textmask = np.zeros((int(figwidth), int(figheight)), bool)
        thisax = self.ax
        # Create a fake label, to test out our scaling
        t0 = self.fig.text(0.5, 0.5, "ABCDEFGHIJ", transform=thisax.transAxes,
                           color='None', size=textsize)
        bbox = t0.get_window_extent(self.fig.canvas.get_renderer())
        xpixels_per_char = bbox.width / 10.
        ypixels = bbox.height
        for o, a, v, m, c, label in zip(lons, lats, vals, valmask,
                                        color, labels):
            if not m:
                continue

            ha = 'center'
            mystr = fmt % (v,)
            max_mystr_len = max([len(s) for s in mystr.split("\n")])
            mystr_lines = len(mystr.split("\n"))
            # compute the pixel coordinate of this data point
            (x, y) = thisax.projection.transform_point(o, a, ccrs.Geodetic())
            (imgx, imgy) = thisax.transData.transform([x, y])
            imgx0 = int(imgx - (max_mystr_len * xpixels_per_char / 2.0))
            if imgx0 < axx0:
                ha = 'left'
                imgx0 = imgx
            imgx1 = imgx0 + max_mystr_len * xpixels_per_char
            if imgx1 > axx1:
                imgx1 = imgx
                imgx0 = imgx1 - max_mystr_len * xpixels_per_char
                ha = 'right'
            imgy0 = int(imgy)
            imgy1 = imgy0 + mystr_lines * ypixels
            # Now we buffer
            imgx0 = max([0, imgx0 - labelbuffer])
            imgx1 = min([figwidth, (imgx0 + 2 * labelbuffer +
                                    max_mystr_len * xpixels_per_char)])
            imgy0 = max([0, imgy0 - labelbuffer * 0.75])
            imgy1 = min([figheight, (imgy0 +
                                     mystr_lines * ypixels +
                                     2 * labelbuffer * 0.75)])
            _cnt = np.sum(np.where(self.textmask[int(imgx0):int(imgx1),
                                                 int(imgy0):int(imgy1)],
                                   1, 0))
            # If we have more than 15 pixels of overlap, don't plot this!
            if _cnt > 15:
                if self.debug:
                    print("culling |%s| due to overlap, %s" % (repr(mystr),
                                                               _cnt))
                continue
            if self.debug:
                rec = plt.Rectangle([imgx0,
                                     imgy0],
                                    (imgx1 - imgx0),
                                    (imgy1 - imgy0),
                                    facecolor='None', edgecolor='r')
                self.fig.patches.append(rec)
            # Useful for debugging this algo
            if self.debug:
                print(("label: %s imgx: %s/%s-%s imgy: %s/%s-%s "
                       "x:%s-%s y:%s-%s _cnt:%s"
                       ) % (repr(mystr), imgx, axx0, axx1, imgy, axy0, axy1,
                            imgx0, imgx1, imgy0, imgy1, _cnt))
            self.textmask[int(imgx0):int(imgx1), int(imgy0):int(imgy1)] = True
            t0 = thisax.text(o, a, mystr, color=c,
                             size=textsize, zorder=Z_OVERLAY+2,
                             va='center' if not showmarker else 'bottom',
                             ha=ha, transform=ccrs.PlateCarree())
            bbox = t0.get_window_extent(self.fig.canvas.get_renderer())
            if self.debug:
                rec = plt.Rectangle([bbox.x0, bbox.y0],
                                    bbox.width, bbox.height,
                                    facecolor='None', edgecolor='k')
                self.fig.patches.append(rec)
            if showmarker:
                thisax.scatter(o, a, marker='+', zorder=Z_OVERLAY+2,
                               color='k', transform=ccrs.PlateCarree())
            t0.set_clip_on(True)
            t0.set_path_effects([PathEffects.Stroke(linewidth=3,
                                                    foreground=outlinecolor),
                                 PathEffects.Normal()])

            if label and label != '':
                thisax.annotate("%s" % (label, ), xy=(x, y), ha='center',
                                va='top',
                                xytext=(0, 0 - textsize/2),
                                color=labelcolor,
                                textcoords="offset points",
                                zorder=Z_OVERLAY+1,
                                clip_on=True, fontsize=labeltextsize)
Esempio n. 6
0
def _make_plot(station, df, units, nsector, rmax, hours, months, sname, level,
               bins, **kwargs):
    """Generate a matplotlib windrose plot

    Args:
      station (str): station identifier
      df (pd.DataFrame): observations
      drct (list): list of wind directions
      units (str): units of wind speed
      nsector (int): number of bins to use for windrose
      rmax (float): radius of the plot
      hours (list): hour limit for plot
      month (list): month limit for plot
      sname (str): station name
      level (int): RAOB level in hPa of interest
      bins (list): values for binning the wind speeds

    Returns:
      matplotlib.Figure
    """
    # Generate figure
    fig = plt.figure(figsize=(8, 8), dpi=100, facecolor='w', edgecolor='w')
    rect = [0.12, 0.12, 0.76, 0.76]
    ax = WindroseAxes(fig, rect, facecolor='w', rmax=rmax)
    fig.add_axes(ax)
    wu = WINDUNITS[units] if level is None else RAOB_WINDUNITS[units]
    if bins:
        wu['bins'] = bins
        wu['binlbl'] = []
        for i, mybin in enumerate(bins[1:-1]):
            wu['binlbl'].append("%g-%g" % (mybin, bins[i + 2]))
        wu['binlbl'].append("%g+" % (bins[-1], ))
    # Filters the missing values
    df2 = df[df['drct'] >= 0]
    try:
        # Unsure why this bombs out sometimes
        ax.bar(df2['drct'].values,
               df2['speed'].values,
               normed=True,
               bins=wu['bins'],
               opening=0.8,
               edgecolor='white',
               nsector=nsector)
    except Exception as exp:
        sys.stderr.write(str(exp))
    # Figure out the shortest bar
    mindir = ax._info['dir'][np.argmin(np.sum(ax._info['table'], axis=0))]
    ax.set_rlabel_position((450 - mindir) % 360 - 15)
    # Adjust the limits so to get a empty center
    rmin, rmax = ax.get_ylim()
    ax.set_rorigin(0 - (rmax - rmin) * 0.2)
    # Make labels have % formatters
    ax.yaxis.set_major_formatter(FormatStrFormatter('%.1f%%'))

    handles = []
    for p in ax.patches_list:
        color = p.get_facecolor()
        handles.append(
            plt.Rectangle((0, 0), 0.1, 0.3, facecolor=color,
                          edgecolor='black'))
    legend = fig.legend(handles,
                        wu['binlbl'],
                        bbox_to_anchor=(0.01, 0.01, 0.98, 0.09),
                        loc='center',
                        ncol=6,
                        title='Wind Speed [%s]' % (wu['abbr'], ),
                        mode=None,
                        columnspacing=0.9,
                        handletextpad=0.45,
                        fontsize=14)
    plt.setp(legend.get_texts(), fontsize=10)
    # Now we put some fancy debugging info on the plot
    tlimit = "Time Domain: "
    if len(hours) == 24 and len(months) == 12:
        tlimit = "All Year"
    if len(hours) < 24:
        if len(hours) > 4:
            tlimit += "%s-%s" % (
                datetime.datetime(2000, 1, 1, hours[0]).strftime("%-I %p"),
                datetime.datetime(2000, 1, 1, hours[-1]).strftime("%-I %p"))
        else:
            for h in hours:
                tlimit += "%s," % (datetime.datetime(2000, 1, 1,
                                                     h).strftime("%-I %p"), )
    if len(months) < 12:
        for h in months:
            tlimit += "%s," % (datetime.datetime(2000, h, 1).strftime("%b"), )
    label = """[%s] %s%s
Windrose Plot [%s]
Period of Record: %s - %s""" % (
        station, sname if sname is not None else "((%s))" %
        (station, ), "" if level is None else " @%s hPa" %
        (level, ), tlimit, df['valid'].min().strftime("%d %b %Y"),
        df['valid'].max().strftime("%d %b %Y"))
    plt.gcf().text(0.14, 0.99, label, va='top', fontsize=14)
    plt.gcf().text(
        0.5,
        0.5,
        "Calm\n%.1f%%" %
        (len(df[df['sknt'] == 0].index) / float(len(df2.index)) * 100., ),
        ha='center',
        va='center',
        fontsize=14)
    plt.gcf().text(
        0.96,
        0.11, ("Summary\nobs count: %s\nMissing: %s\nAvg Speed: %.1f %s") %
        (len(df.index), len(df.index) - len(df2.index), df['speed'].mean(),
         wu['abbr']),
        ha='right',
        fontsize=14)
    if not kwargs.get('nogenerated', False):
        plt.gcf().text(0.02,
                       0.1,
                       "Generated: %s" %
                       (datetime.datetime.now().strftime("%d %b %Y"), ),
                       verticalalignment="bottom",
                       fontsize=14)
    # Denote the direction blowing from
    plt.gcf().text(0.02,
                   0.125,
                   "Direction is where the wind is\nblowing from, not toward.",
                   va='bottom')
    # Make a logo
    im = mpimage.imread('%s/%s' % (DATADIR, 'logo.png'))
    plt.figimage(im, 10, 735)

    return fig
Esempio n. 7
0
def plotter(fdict):
    """ Go """
    pgconn = get_dbconn('coop')
    ctx = get_autoplot_context(fdict, get_description())
    station = ctx['station']
    network = ctx['network']
    month1 = ctx['month1']
    month2 = ctx['month2']
    highlight = ctx['highlight']
    varname = ctx['var']
    p1 = ctx.get('p1')
    p2 = ctx.get('p2')
    days = ctx['days']
    opt = ctx['opt']

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

    m1data, y1, y2 = get_data(pgconn, table, station, month1, p1, varname,
                              days, opt)
    m2data, y3, y4 = get_data(pgconn, table, station, month2, p2, varname,
                              days, opt)

    pc1 = np.percentile(m1data, range(0, 101, 1))
    pc2 = np.percentile(m2data, range(0, 101, 1))
    df = pd.DataFrame({
        '%s_%s_%s_%s' % (MDICT[month1], varname, y1, y2):
        pd.Series(pc1),
        '%s_%s_%s_%s' % (MDICT[month2], varname, y3, y4):
        pd.Series(pc2),
        'quantile':
        pd.Series(range(0, 101, 5))
    })
    s_slp, s_int, s_r, _, _ = stats.linregress(pc1, pc2)

    fig = plt.gcf()
    fig.set_size_inches(10.24, 7.68)
    ax = plt.axes([0.1, 0.11, 0.4, 0.76])
    ax.scatter(pc1[::5], pc2[::5], s=40, marker='s', color='b', zorder=3)
    ax.plot(pc1,
            pc1 * s_slp + s_int,
            lw=3,
            color='r',
            zorder=2,
            label=r"Fit R$^2$=%.2f" % (s_r**2, ))
    ax.axvline(highlight, zorder=1, color='k')
    y = highlight * s_slp + s_int
    ax.axhline(y, zorder=1, color='k')
    ax.text(pc1[0],
            y,
            "%.0f $^\circ$F" % (y, ),
            va='center',
            bbox=dict(color='white'))
    ax.text(highlight,
            pc2[0],
            "%.0f $^\circ$F" % (highlight, ),
            ha='center',
            rotation=90,
            bbox=dict(color='white'))
    t2 = PDICT[varname]
    if days > 1:
        t2 = "%s %s over %s days" % (ODICT[opt], PDICT[varname], days)
    fig.suptitle(("[%s] %s\n%s (%s-%s) vs %s (%s-%s)\n%s") %
                 (station, nt.sts[station]['name'], MDICT[month2], y1, y2,
                  MDICT[month1], y3, y4, t2))
    ax.set_xlabel("%s (%s-%s) %s $^\circ$F" %
                  (MDICT[month1], y1, y2, PDICT[varname]))
    ax.set_ylabel("%s (%s-%s) %s $^\circ$F" %
                  (MDICT[month2], y3, y4, PDICT[varname]))
    ax.text(0.95,
            0.05,
            "Quantile - Quantile Plot",
            transform=ax.transAxes,
            ha='right')
    ax.grid(True)
    ax.legend(loc=2)

    # Second
    ax = plt.axes([0.55, 0.18, 0.27, 0.68])
    ax.set_title("Distribution")
    v1 = ax.violinplot(m1data,
                       positions=[
                           0,
                       ],
                       showextrema=True,
                       showmeans=True)
    b = v1['bodies'][0]
    m = np.mean(b.get_paths()[0].vertices[:, 0])
    b.get_paths()[0].vertices[:, 0] = np.clip(b.get_paths()[0].vertices[:, 0],
                                              -np.inf, m)
    b.set_color('r')
    for l in ['cmins', 'cmeans', 'cmaxes']:
        v1[l].set_color('r')

    v1 = ax.violinplot(m2data,
                       positions=[
                           0,
                       ],
                       showextrema=True,
                       showmeans=True)
    b = v1['bodies'][0]
    m = np.mean(b.get_paths()[0].vertices[:, 0])
    b.get_paths()[0].vertices[:, 0] = np.clip(b.get_paths()[0].vertices[:, 0],
                                              m, np.inf)
    b.set_color('b')
    for l in ['cmins', 'cmeans', 'cmaxes']:
        v1[l].set_color('b')

    pr0 = plt.Rectangle((0, 0), 1, 1, fc="r")
    pr1 = plt.Rectangle((0, 0), 1, 1, fc="b")
    ax.legend(
        (pr0, pr1),
        ("%s (%s-%s), $\mu$=%.1f" % (MDICT[month1], y1, y2, np.mean(m1data)),
         "%s (%s-%s), $\mu$=%.1f" % (MDICT[month2], y3, y4, np.mean(m2data))),
        ncol=1,
        loc=(0.5, -0.15))
    ax.set_ylabel("%s $^\circ$F" % (PDICT[varname], ))
    ax.grid()

    # Third
    monofont = FontProperties(family='monospace')
    y = 0.86
    x = 0.83
    col1 = "%s_%s_%s_%s" % (MDICT[month1], varname, y1, y2)
    col2 = "%s_%s_%s_%s" % (MDICT[month2], varname, y3, y4)
    fig.text(x, y + 0.04, 'Percentile Data    Diff')
    for percentile in [
            100, 99, 98, 97, 96, 95, 92, 90, 75, 50, 25, 10, 8, 5, 4, 3, 2, 1
    ]:
        row = df.loc[percentile]
        fig.text(x, y, "%3i" % (percentile, ), fontproperties=monofont)
        fig.text(x + 0.025,
                 y,
                 "%5.1f" % (row[col1], ),
                 fontproperties=monofont,
                 color='r')
        fig.text(x + 0.07,
                 y,
                 "%5.1f" % (row[col2], ),
                 fontproperties=monofont,
                 color='b')
        fig.text(x + 0.11,
                 y,
                 "%5.1f" % (row[col2] - row[col1], ),
                 fontproperties=monofont)
        y -= 0.04

    return fig, df