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
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
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
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
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)
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
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