def plotter(fdict): """ Go """ ctx = get_autoplot_context(fdict, get_description()) get_data(ctx) title = ("Consecutive Days with %s Temp " "above(+)/below(-) Average") % ( ctx["var"].capitalize(), ) if ctx["var"] == "precip": title = "Days Since Last Measurable Precipitation" mp = MapPlot( sector=ctx["sector"], state=ctx["state"], cwa=(ctx["wfo"] if len(ctx["wfo"]) == 3 else ctx["wfo"][1:]), axisbg="tan", statecolor="#EEEEEE", title=title, subtitle=ctx["subtitle"], ) df2 = ctx["df"][pd.notnull(ctx["df"]["lon"])] mp.plot_values( df2["lon"].values, df2["lat"].values, df2["val"].values, color=df2["color"].values, labels=df2["label"].values, labeltextsize=(8 if ctx["sector"] != "state" else 12), textsize=(12 if ctx["sector"] != "state" else 16), labelbuffer=10, ) return mp.fig, ctx["df"]
def plotter(fdict): """ Go """ from pyiem.plot.geoplot import MapPlot import matplotlib.pyplot as plt ctx = get_autoplot_context(fdict, get_description()) station = ctx['station'] nt = NetworkTable(ctx['network']) year = ctx['year'] dbconn = get_dbconn('coop') table = "alldata_%s" % (station[:2], ) df = read_sql(""" with yearly as ( select year, sum(precip), station from alldata_ia where precip is not null and sday < '1012' GROUP by station, year), ames as ( select year, sum from yearly where station = %s), combo as ( select y.year, y.station, y.sum as other, a.sum as ames from yearly y JOIN ames a on (y.year = a.year) WHERE y.station != %s and y.station != 'IA0807'), y2017 as ( select * from combo where year = 2017), agg as ( SELECT station, st_x(geom) as lon, st_y(geom) as lat, sum(case when other > ames then 1 else 0 end) as hits, count(*) from combo c JOIN stations t on (c.station = t.id) WHERE t.network = %s and c.year < 2017 GROUP by station, lon, lat) SELECT y.ames as ames, y.other as other, a.* from y2017 y JOIN agg a on (y.station = a.station) """, dbconn, params=(station, station, ctx['network']), index_col='station') df = df[df['count'] > 50] df['h2017'] = 'red' df.loc[df['other'] > df['ames'], 'h2017'] = 'blue' df['freq'] = df['hits'] / df['count'] * 100. df.sort_values('freq', inplace=True) mp = MapPlot(continentalcolor='white', title=('Percentage of Years with Higher Precipitation Total ' 'than Ames'), subtitle=('For 1 January thru 12 October Period, sites ' 'in blue are higher for 2017')) mp.plot_values(df['lon'].values, df['lat'].values, df['freq'].values, '%.0f', labelbuffer=1, color=df['h2017'].values) #mp.contourf(df['lon'].values, df['lat'].values, df['freq'].values, # range(0, 101, 10), cmap=plt.get_cmap('plasma_r')) mp.drawcounties() return mp.fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn('coop') ctx = get_autoplot_context(fdict, get_description()) sector = ctx['sector'] if len(sector) != 2: raise ValueError("Sorry, this app does not support multi-state plots.") varname = ctx['var'] year = ctx['year'] popt = ctx['popt'] threshold = ctx['threshold'] table = "alldata_%s" % (sector, ) df = read_sql(""" WITH data as ( SELECT station, """ + SQLOPT[varname] + """ as doy from """ + table + """ WHERE year = %s GROUP by station ) select station, doy, st_x(geom) as lon, st_y(geom) as lat from data d JOIN stations t on (d.station = t.id) WHERE t.network = %s and substr(station, 3, 4) != '0000' and substr(station, 3, 1) != 'C' and doy not in (0, 400) ORDER by doy """, pgconn, params=(threshold, year, '%sCLIMATE' % (sector, )), index_col='station') if df.empty: raise ValueError("No data found!") def f(val): ts = datetime.date(year, 1, 1) + datetime.timedelta(days=int(val - 1)) return ts.strftime("%-m/%-d") df['pdate'] = df['doy'].apply(f) mp = MapPlot(sector=('state' if len(sector) == 2 else sector), state=ctx['sector'], continental_color='white', nocaption=True, title=r"%s %s %s$^\circ$F" % (year, PDICT2[varname], threshold), subtitle='based on NWS COOP and IEM Daily Estimates') levs = np.linspace(df['doy'].min() - 3, df['doy'].max() + 3, 7, dtype='i') levlables = list(map(f, levs)) if popt == 'contour': mp.contourf(df['lon'], df['lat'], df['doy'], levs, clevlabels=levlables) mp.plot_values(df['lon'], df['lat'], df['pdate'], labelbuffer=5) mp.drawcounties() return mp.fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn("coop") ctx = get_autoplot_context(fdict, get_description()) sector = ctx["sector"] if len(sector) != 2: raise NoDataFound("Sorry, this app doesn't support multi-state plots.") varname = ctx["var"] year = ctx["year"] popt = ctx["popt"] threshold = ctx["threshold"] table = "alldata_%s" % (sector,) nt = NetworkTable("%sCLIMATE" % (sector,)) syear = ctx.get("syear", 1893) eyear = ctx.get("eyear", datetime.date.today().year) df = read_sql( """ -- get the domain of data WITH events as ( SELECT station, month, case when month < 7 then year - 1 else year end as winter_year, year, extract(doy from day) as doy, day from """ + table + """ WHERE """ + SQLOPT[varname] + """ and month in %s and substr(station, 3, 4) != '0000' and substr(station, 3, 1) not in ('C', 'T') and year >= %s and year <= %s ), agg as ( SELECT station, winter_year, year, doy, day, case when month < 7 then doy + 366 else doy end as winter_doy, rank() OVER ( PARTITION by """ + YRGP[varname] + """, station ORDER by day """ + ORDER[varname] + """) from events) select * from agg where rank = 1 """, pgconn, params=(threshold, tuple(MONTH_DOMAIN[varname]), syear, eyear), index_col="station", ) doy = USEDOY[varname] def f(val): """Make a pretty date.""" base = datetime.date(2000, 1, 1) date = base + datetime.timedelta(days=int(val)) return date.strftime("%-m/%-d") if ctx.get("p") is None: df2 = df[df[YRGP[varname]] == year].copy() title = r"%s %s %s$^\circ$F" % (year, PDICT2[varname], threshold) df2["pdate"] = df2["day"].apply(lambda x: x.strftime("%-m/%-d")) extra = "" else: df2 = df[[doy]].groupby("station").quantile(ctx["p"] / 100.0).copy() title = r"%.0f%s Percentile Date of %s %s$^\circ$F" % ( ctx["p"], th(str(ctx["p"])), PDICT2[varname], threshold, ) df2["pdate"] = df2[doy].apply(f) extra = ", period of record: %.0f-%.0f" % ( df["year"].min(), df["year"].max(), ) if df2.empty: raise NoDataFound("No Data was found") for station in df2.index.values: if station not in nt.sts: continue df2.at[station, "lat"] = nt.sts[station]["lat"] df2.at[station, "lon"] = nt.sts[station]["lon"] mp = MapPlot( sector="state", state=ctx["sector"], continental_color="white", nocaption=True, title=title, subtitle="based on NWS COOP and IEM Daily Estimates%s" % (extra,), ) levs = np.linspace(df2[doy].min() - 1, df2[doy].max() + 1, 7, dtype="i") if "cint" in ctx: levs = np.arange( df2[doy].min() - 1, df2[doy].max() + 1, ctx["cint"], dtype="i" ) levlables = list(map(f, levs)) if popt == "contour": mp.contourf( df2["lon"], df2["lat"], df2[doy], levs, clevlabels=levlables, cmap=ctx["cmap"], ) mp.plot_values(df2["lon"], df2["lat"], df2["pdate"], labelbuffer=5) mp.drawcounties() return mp.fig, df[["year", "winter_doy", "doy"]]
def plotter(fdict): """ Go """ pgconn = get_dbconn('iem') ctx = get_autoplot_context(fdict, get_description()) varname = ctx['var'] sector = ctx['sector'] state = ctx['state'] wfo = ctx['wfo'] nt = NetworkTable("NWSCLI") today = ctx['sdate'] yesterday = today - datetime.timedelta(days=1) d180 = today - datetime.timedelta(days=180) df = read_sql(""" with obs as ( select station, valid, (case when low > low_normal then 1 else 0 end) as low_hit, (case when high > high_normal then 1 else 0 end) as high_hit, (case when precip >= 0.01 then 1 else 0 end) as precip_hit from cli_data where high is not null and high_normal is not null and low is not null and low_normal is not null and valid > %s and valid <= %s), totals as ( SELECT station, max(case when low_hit = 0 then valid else %s end) as last_low_below, max(case when low_hit = 1 then valid else %s end) as last_low_above, max(case when high_hit = 0 then valid else %s end) as last_high_below, max(case when high_hit = 1 then valid else %s end) as last_high_above, max(case when precip_hit = 0 then valid else %s end) as last_dry, max(case when precip_hit = 1 then valid else %s end) as last_wet, count(*) as count from obs GROUP by station) SELECT station, last_low_below, last_low_above, last_high_below, last_high_above, last_dry, last_wet from totals where count > 170 """, pgconn, params=(d180, today, d180, d180, d180, d180, d180, d180), index_col='station') lats = [] lons = [] vals = [] colors = [] labels = [] df['precip_days'] = (df['last_dry'] - df['last_wet']).dt.days df['low_days'] = (df['last_low_above'] - df['last_low_below']).dt.days df['high_days'] = (df['last_high_above'] - df['last_high_below']).dt.days # reorder the frame so that the largest values come first df = df.reindex(df[varname + '_days'].abs().sort_values(ascending=False).index) for station, row in df.iterrows(): if station not in nt.sts: continue lats.append(nt.sts[station]['lat']) lons.append(nt.sts[station]['lon']) if varname == 'precip': last_wet = row['last_wet'] days = 0 if last_wet in [today, yesterday] else row['precip_days'] else: days = row[varname + '_days'] vals.append(days) colors.append('r' if days > 0 else 'b') labels.append(station[1:]) title = ('Consecutive Days with %s Temp ' 'above(+)/below(-) Average') % (varname.capitalize(), ) if varname == 'precip': title = 'Days Since Last Measurable Precipitation' mp = MapPlot(sector=sector, state=state, cwa=(wfo if len(wfo) == 3 else wfo[1:]), axisbg='tan', statecolor='#EEEEEE', title=title, subtitle=('based on NWS CLI Sites, map approximately ' 'valid for %s') % (today.strftime("%-d %b %Y"), )) mp.plot_values(lons, lats, vals, color=colors, labels=labels, labeltextsize=(8 if sector != 'state' else 12), textsize=(12 if sector != 'state' else 16), labelbuffer=10) return mp.fig, df
def make_overviewmap(form): """Draw a pretty map of just the HUC.""" huc = form.get("huc") plt.close() projection = EPSG[5070] if huc is None: huclimiter = "" elif len(huc) >= 8: huclimiter = " and substr(huc_12, 1, 8) = '%s' " % (huc[:8],) with get_sqlalchemy_conn("idep") as conn: df = read_postgis( f""" SELECT simple_geom as geom, huc_12, ST_x(ST_Transform(ST_Centroid(geom), 4326)) as centroid_x, ST_y(ST_Transform(ST_Centroid(geom), 4326)) as centroid_y, hu_12_name from huc12 i WHERE i.scenario = 0 {huclimiter} """, conn, geom_col="geom", index_col="huc_12", ) minx, miny, maxx, maxy = df["geom"].total_bounds buf = float(form.get("zoom", 10.0)) * 1000.0 # 10km hucname = "" if huc not in df.index else df.at[huc, "hu_12_name"] subtitle = "The HUC8 is in tan" if len(huc) == 12: subtitle = "HUC12 highlighted in red, the HUC8 it resides in is in tan" m = MapPlot( axisbg="#EEEEEE", logo="dep", sector="custom", south=miny - buf, north=maxy + buf, west=minx - buf, east=maxx + buf, projection=projection, continentalcolor="white", title="DEP HUC %s:: %s" % (huc, hucname), subtitle=subtitle, titlefontsize=20, subtitlefontsize=18, caption="Daily Erosion Project", ) for _huc12, row in df.iterrows(): p = Polygon( row["geom"].exterior.coords, fc="red" if _huc12 == huc else "tan", ec="k", zorder=Z_OVERLAY2, lw=0.1, ) m.ax.add_patch(p) # If this is our HUC, add some text to prevent cities overlay overlap if _huc12 == huc: m.plot_values( [row["centroid_x"]], [row["centroid_y"]], [" . "], color="None", outlinecolor="None", ) if huc is not None: m.drawcounties() m.drawcities() ram = BytesIO() plt.savefig(ram, format="png", dpi=100) plt.close() ram.seek(0) return ram.read(), True