def main(): """Go Main""" total = None years = 0. for yr in range(1981, 2018): print(yr) ncfn = "/mesonet/data/prism/%s_daily.nc" % (yr, ) nc = netCDF4.Dataset(ncfn) if total is None: lons = nc.variables['lon'][:] lats = nc.variables['lat'][:] total = np.zeros(nc.variables['tmax'].shape[1:], np.float) days = np.zeros(nc.variables['tmax'].shape[1:], np.float) sidx = daily_offset(datetime.date(yr, 1, 1)) eidx = daily_offset(datetime.date(yr, 7, 4)) for idx in range(sidx, eidx): days += np.where(nc.variables['tmax'][idx, :, :] > THRESHOLD, 1, 0) nc.close() years += 1. total += days val = days - (total / years) print(np.max(val)) print(np.min(val)) mp = MapPlot(sector='conus', title=("OSU PRISM 2017 Days with High >= 90$^\circ$F " "Departure"), subtitle=("2017 thru 4 July against 1981-2016 " "Year to Date Average")) mp.contourf(lons, lats, val, np.arange(-25, 26, 5), units='days', cmap=plt.get_cmap('seismic')) mp.postprocess(filename='test.png')
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 plot_maxmin(ts, field): """Generate our plot.""" nc = ncopen(ts.strftime("/mesonet/data/ndfd/%Y%m%d%H_ndfd.nc")) if field == 'high_tmpk': data = np.max(nc.variables[field][:], 0) elif field == 'low_tmpk': data = np.min(nc.variables[field][:], 0) data = masked_array(data, units.degK).to(units.degF).m subtitle = ("Based on National Digital Forecast Database (NDFD) " "00 UTC Forecast made %s") % (ts.strftime("%-d %b %Y"), ) mp = MapPlot(title='NWS NDFD 7 Day (%s through %s) %s Temperature' % ( ts.strftime("%-d %b"), (ts + datetime.timedelta(days=6)).strftime("%-d %b"), 'Maximum' if field == 'high_tmpk' else 'Minimum', ), subtitle=subtitle, sector='iailin') mp.pcolormesh(nc.variables['lon'][:], nc.variables['lat'][:], data, np.arange(10, 121, 10), cmap=plt.get_cmap('jet'), units='Degrees F') mp.drawcounties() pqstr = ( "data c %s summary/cb_ndfd_7day_%s.png summary/cb_ndfd_7day_%s.png " "png") % (ts.strftime("%Y%m%d%H%M"), "max" if field == 'high_tmpk' else 'min', "max" if field == 'high_tmpk' else 'min') mp.postprocess(pqstr=pqstr) mp.close() nc.close()
def plotter(fdict): """ Go """ ctx = get_autoplot_context(fdict, get_description()) get_df(ctx) labels = {} data = {} for state, row in ctx['df'].iterrows(): val = row['departure'] data[state] = val if pd.isna(val): if pd.isna(row['avg']): subscript = 'M' else: subscript = "[-%.0f]" % (row['avg'], ) data[state] = 0 - row['avg'] else: subscript = "[%s%.0f]" % ("+" if val > 0 else "", val) subscript = "[0]" if subscript in ['[-0]', '[+0]'] else subscript labels[state] = "%s\n%s" % ('M' if pd.isna(row['thisval']) else int(row['thisval']), subscript) mp = MapPlot( sector='conus', title=ctx['title'], subtitle=ctx['subtitle'] ) levels = range(-40, 41, 10) cmap = plt.get_cmap(ctx['cmap']) cmap.set_bad('white') mp.fill_states(data, ilabel=True, labels=labels, bins=levels, cmap=cmap, units='Absolute %', labelfontsize=16) return mp.fig, ctx['df']
def plot(argv): """Make a plot""" df = pd.read_csv("%s_maxdailyprecip.txt" % (argv[1], ), dtype={'huc12': str}) df.set_index('huc12', inplace=True) pgconn = get_dbconn('idep') huc12df = gpd.GeoDataFrame.from_postgis(""" SELECT huc12, simple_geom as geo from wbd_huc12 WHERE swat_use ORDER by huc12 """, pgconn, index_col='huc12', geom_col='geo') mp = MapPlot( sector='custom', south=34, north=48, west=-98, east=-77, title="%s Max Daily Precipitation" % (argv[1].split("_", 1)[1], ) ) bins = range(0, 201, 20) cmap = stretch_cmap('terrain_r', bins) norm = mpcolors.BoundaryNorm(bins, cmap.N) for huc12, row in huc12df.iterrows(): for poly in row['geo']: arr = np.asarray(poly.exterior) points = mp.ax.projection.transform_points(ccrs.Geodetic(), arr[:, 0], arr[:, 1]) color = cmap(norm([df.at[huc12, 'maxp'], ]))[0] poly = Polygon(points[:, :2], fc=color, ec='None', zorder=2, lw=.1) mp.ax.add_patch(poly) mp.draw_colorbar(bins, cmap, norm, units='mm') mp.postprocess(filename='test.png')
def plotter(fdict): """ Go """ bins = [0, 1, 14, 31, 91, 182, 273, 365, 730, 1460, 2920, 3800] pgconn = get_dbconn("postgis") cursor = pgconn.cursor(cursor_factory=psycopg2.extras.DictCursor) ctx = get_autoplot_context(fdict, get_description()) phenomena = ctx["phenomena"] significance = ctx["significance"] edate = ctx.get("edate") if edate is not None: edate = utc(edate.year, edate.month, edate.day, 0, 0) cursor.execute( """ select wfo, extract(days from (%s::date - max(issue))) as m from warnings where significance = %s and phenomena = %s and issue < %s GROUP by wfo ORDER by m ASC """, (edate, significance, phenomena, edate), ) else: cursor.execute( """ select wfo, extract(days from ('TODAY'::date - max(issue))) as m from warnings where significance = %s and phenomena = %s GROUP by wfo ORDER by m ASC """, (significance, phenomena), ) edate = datetime.datetime.utcnow() if cursor.rowcount == 0: raise NoDataFound(("No Events Found for %s (%s.%s)") % ( vtec.get_ps_string(phenomena, significance), phenomena, significance, )) data = {} rows = [] for row in cursor: wfo = row[0] if row[0] != "JSJ" else "SJU" rows.append(dict(wfo=wfo, days=row[1])) data[wfo] = max([row[1], 0]) df = pd.DataFrame(rows) df.set_index("wfo", inplace=True) mp = MapPlot( sector="nws", axisbg="white", nocaption=True, title="Days since Last %s by NWS Office" % (vtec.get_ps_string(phenomena, significance), ), subtitle="Valid %s" % (edate.strftime("%d %b %Y %H%M UTC"), ), ) mp.fill_cwas(data, bins=bins, ilabel=True, units="Days", lblformat="%.0f") return mp.fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn("coop") ctx = get_autoplot_context(fdict, get_description()) date1 = ctx["date1"] date2 = ctx["date2"] date1 = date1.replace(year=2000) date2 = date2.replace(year=2000) varname = ctx["varname"] df = read_sql( """ WITH t2 as ( SELECT station, high, low from ncdc_climate81 WHERE valid = %s ), t1 as ( SELECT station, high, low from ncdc_climate81 where valid = %s ), data as ( SELECT t2.station, t1.high as t1_high, t2.high as t2_high, t1.low as t1_low, t2.low as t2_low from t1 JOIN t2 on (t1.station = t2.station) ) SELECT d.station, ST_x(geom) as lon, ST_y(geom) as lat, t2_high - t1_high as high, t2_low - t1_low as low from data d JOIN stations s on (s.id = d.station) where s.network = 'NCDC81' and s.state not in ('HI', 'AK') """, pgconn, params=(date2, date1), index_col="station", ) if df.empty: raise NoDataFound("No Data Found.") days = int((date2 - date1).days) extent = int(df[varname].abs().max()) mp = MapPlot( sector="conus", title=("%s Day Change in %s NCDC 81 Climatology") % (days, PDICT[varname]), subtitle="from %s to %s" % (date1.strftime("%-d %B"), date2.strftime("%-d %B")), ) mp.contourf( df["lon"].values, df["lat"].values, df[varname].values, np.arange(0 - extent, extent + 1, 2), cmap=get_cmap(ctx["cmap"]), units="F", ) return mp.fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn('coop') ctx = get_autoplot_context(fdict, get_description()) date1 = ctx['date1'] date2 = ctx['date2'] date1 = date1.replace(year=2000) date2 = date2.replace(year=2000) varname = ctx['varname'] df = read_sql(""" WITH t2 as ( SELECT station, high, low from ncdc_climate81 WHERE valid = %s ), t1 as ( SELECT station, high, low from ncdc_climate81 where valid = %s ), data as ( SELECT t2.station, t1.high as t1_high, t2.high as t2_high, t1.low as t1_low, t2.low as t2_low from t1 JOIN t2 on (t1.station = t2.station) ) SELECT d.station, ST_x(geom) as lon, ST_y(geom) as lat, t2_high - t1_high as high, t2_low - t1_low as low from data d JOIN stations s on (s.id = d.station) where s.network = 'NCDC81' and s.state not in ('HI', 'AK') """, pgconn, params=(date2, date1), index_col='station') days = int((date2 - date1).days) extent = int(df[varname].abs().max()) mp = MapPlot(sector='conus', title=('%s Day Change in %s NCDC 81 Climatology') % (days, PDICT[varname]), subtitle='from %s to %s' % (date1.strftime("%-d %B"), date2.strftime("%-d %B"))) mp.contourf(df['lon'].values, df['lat'].values, df[varname].values, np.arange(0 - extent, extent + 1, 2), cmap=cm.get_cmap(ctx['cmap']), units='F') return mp.fig, df
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt from pyiem.plot.geoplot import MapPlot ctx = util.get_autoplot_context(fdict, get_description()) date = ctx['date'] sector = ctx['sector'] threshold = ctx['threshold'] threshold_mm = distance(threshold, 'IN').value('MM') window_sts = date - datetime.timedelta(days=90) if window_sts.year != date.year: raise Exception('Sorry, do not support multi-year plots yet!') idx0 = iemre.daily_offset(window_sts) idx1 = iemre.daily_offset(date) ncfn = "/mesonet/data/iemre/%s_mw_mrms_daily.nc" % (date.year, ) ncvar = 'p01d' if not os.path.isfile(ncfn): raise Exception("No data for that year, sorry.") nc = netCDF4.Dataset(ncfn, 'r') grid = np.zeros((len(nc.dimensions['lat']), len(nc.dimensions['lon']))) total = np.zeros((len(nc.dimensions['lat']), len(nc.dimensions['lon']))) for i, idx in enumerate(range(idx1, idx1-90, -1)): total += nc.variables[ncvar][idx, :, :] grid = np.where(np.logical_and(grid == 0, total > threshold_mm), i, grid) lon = np.append(nc.variables['lon'][:], [-80.5]) lat = np.append(nc.variables['lat'][:], [49.]) nc.close() mp = MapPlot(sector='state', state=sector, titlefontsize=14, subtitlefontsize=12, title=("NOAA MRMS Q3: Number of Recent Days " "till Accumulating %s\" of Precip" ) % (threshold, ), subtitle=("valid %s: based on per calendar day " "estimated preciptation, GaugeCorr and " "RadarOnly products" ) % (date.strftime("%-d %b %Y"), )) x, y = np.meshgrid(lon, lat) cmap = plt.get_cmap('terrain') cmap.set_over('k') cmap.set_under('white') mp.pcolormesh(x, y, grid, np.arange(0, 81, 10), cmap=cmap, units='days') mp.drawcounties() mp.drawcities() return mp.fig
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 main(): """Go Main Go.""" pgconn = get_dbconn("idep") df = read_postgis( """ with centroids as ( select huc_12, st_centroid(geom) as center, simple_geom from huc12 where scenario = 0), agg as ( select c.huc_12, sum(case when st_y(center) < st_ymax(geom) then 1 else 0 end) as west, count(*) from flowpaths f JOIN centroids c on (f.huc_12 = c.huc_12) WHERE f.scenario = 0 GROUP by c.huc_12) select a.huc_12, st_transform(c.simple_geom, 4326) as geo, a.west, a.count from agg a JOIN centroids c ON (a.huc_12 = c.huc_12) """, pgconn, index_col=None, geom_col="geo", ) df["percent"] = df["west"] / df["count"] * 100.0 bins = np.arange(0, 101, 10) cmap = plt.get_cmap("RdBu") norm = mpcolors.BoundaryNorm(bins, cmap.N) mp = MapPlot( continentalcolor="thistle", nologo=True, sector="custom", south=36.8, north=48.0, west=-99.2, east=-88.9, subtitle="", title=("DEP Flowpaths North of HUC12 Centroid (%.0f/%.0f %.2f%%)" % ( df["west"].sum(), df["count"].sum(), df["west"].sum() / df["count"].sum() * 100.0, )), ) for _i, row in df.iterrows(): c = cmap(norm([row["percent"]]))[0] arr = np.asarray(row["geo"].exterior) points = mp.ax.projection.transform_points(ccrs.Geodetic(), arr[:, 0], arr[:, 1]) p = Polygon(points[:, :2], fc=c, ec="None", zorder=2, lw=0.1) mp.ax.add_patch(p) mp.drawcounties() mp.draw_colorbar(bins, cmap, norm, title="Percent", extend="neither") mp.postprocess(filename="/tmp/huc12_north.png")
def plotter(fdict): """ Go """ ctx = get_autoplot_context(fdict, get_description()) # Covert datetime to UTC ctx['sdate'] = ctx['sdate'].replace(tzinfo=pytz.utc) ctx['edate'] = ctx['edate'].replace(tzinfo=pytz.utc) state = ctx['state'] phenomena = ctx['phenomena'] significance = ctx['significance'] station = ctx['station'][:4] t = ctx['t'] ilabel = (ctx['ilabel'] == 'yes') geo = ctx['geo'] nt = NetworkTable("WFO") if geo == 'ugc': do_ugc(ctx) elif geo == 'polygon': do_polygon(ctx) subtitle = "based on IEM Archives %s" % (ctx.get('subtitle', ''), ) if t == 'cwa': subtitle = "Plotted for %s (%s), %s" % (nt.sts[station]['name'], station, subtitle) else: subtitle = "Plotted for %s, %s" % (state_names[state], subtitle) m = MapPlot(sector=('state' if t == 'state' else 'cwa'), state=state, cwa=(station if len(station) == 3 else station[1:]), axisbg='white', title=('%s %s (%s.%s)') % (ctx['title'], vtec.get_ps_string( phenomena, significance), phenomena, significance), subtitle=subtitle, nocaption=True, titlefontsize=16) if geo == 'ugc': cmap = plt.get_cmap('Paired') cmap.set_under('white') cmap.set_over('white') m.fill_ugcs(ctx['data'], ctx['bins'], cmap=cmap, ilabel=ilabel) else: cmap = plt.get_cmap('gist_ncar') cmap.set_under('white') cmap.set_over('black') res = m.pcolormesh(ctx['lons'], ctx['lats'], ctx['data'], ctx['bins'], cmap=cmap, units='count') # Cut down on SVG et al size res.set_rasterized(True) if ctx['drawc'] == 'yes': m.drawcounties() return m.fig, ctx['df']
def plot_gdd(ts): """Generate our plot.""" nc = ncopen(ts.strftime("/mesonet/data/ndfd/%Y%m%d%H_ndfd.nc")) # compute our daily GDDs gddtot = np.zeros(np.shape(nc.variables["lon"][:])) for i in range(7): gddtot += gdd( temperature(nc.variables["high_tmpk"][i, :, :], "K"), temperature(nc.variables["low_tmpk"][i, :, :], "K"), ) cnc = ncopen("/mesonet/data/ndfd/ndfd_dailyc.nc") offset = daily_offset(ts) avggdd = np.sum(cnc.variables["gdd50"][offset:offset + 7], 0) data = gddtot - np.where(avggdd < 1, 1, avggdd) subtitle = ("Based on National Digital Forecast Database (NDFD) " "00 UTC Forecast made %s") % (ts.strftime("%-d %b %Y"), ) mp = MapPlot( title="NWS NDFD 7 Day (%s through %s) GDD50 Departure from Avg" % ( ts.strftime("%-d %b"), (ts + datetime.timedelta(days=6)).strftime("%-d %b"), ), subtitle=subtitle, sector="iailin", ) mp.pcolormesh( nc.variables["lon"][:], nc.variables["lat"][:], data, np.arange(-80, 81, 20), cmap=plt.get_cmap("RdBu_r"), units=r"$^\circ$F", spacing="proportional", ) mp.drawcounties() pqstr = ( "data c %s summary/cb_ndfd_7day_gdd.png summary/cb_ndfd_7day_gdd.png " "png") % (ts.strftime("%Y%m%d%H%M"), ) mp.postprocess(pqstr=pqstr) mp.close() nc.close()
def plotter(ctx): """ Go """ # Covert datetime to UTC do_polygon(ctx) m = MapPlot( title='2009-2018 Flash Flood Emergency Polygon Heatmap', sector='custom', axisbg='white', # west=-107, south=25.5, east=-88, north=41, # west=-82, south=36., east=-68, north=48, west=-85, south=31.8, north=45.2, east=-69, subtitle='based on unofficial IEM Archives', nocaption=True) cmap = plt.get_cmap('jet') cmap.set_under('white') cmap.set_over('black') res = m.pcolormesh(ctx['lons'], ctx['lats'], ctx['data'], ctx['bins'], cmap=cmap, units='count') # Cut down on SVG et al size res.set_rasterized(True) m.postprocess(filename='test.png')
def main(): """Go Main Go.""" dbconn = get_dbconn("postgis") df = read_sql(""" WITH data as ( SELECT wfo, eventid, extract(year from issue) as year, max(case when svs is not null then 1 else 0 end) as hit from warnings where product_issue > '2014-04-01' and product_issue < '2019-02-22' and phenomena = 'SV' and date(issue) not in ('2017-08-25', '2017-08-26', '2017-08-27', '2017-08-28', '2017-08-29', '2017-08-30') and significance = 'W' GROUP by wfo, eventid, year ) SELECT wfo, sum(hit) as got_update, count(*) as total_events from data GROUP by wfo ORDER by total_events DESC """, dbconn, index_col='wfo') if 'JSJ' in df.index and 'SJU' not in df.index: df.loc['SJU'] = df.loc['JSJ'] df['no_update_percent'] = ( 100. - df['got_update'] / df['total_events'] * 100. ) df.to_csv("140401_190221_svr_nofls.csv") # NOTE: FFW followup is FFS mp = MapPlot( sector='nws', title='Percentage of Severe TStorm Warnings without a SVS Update Issued', subtitle=('1 April 2014 - 21 February 2019 (exclude Harvey 26-30 Aug ' '2017), based on unofficial data') ) cmap = plt.get_cmap("copper_r") cmap.set_under('white') cmap.set_over('black') ramp = range(0, 101, 5) mp.fill_cwas( df['no_update_percent'], bins=ramp, cmap=cmap, units='%', ilabel=True, lblformat='%.1f' ) mp.postprocess(filename='140401_190221_svr_nosvs.png')
def plotter(fdict): """ Go """ ctx = get_autoplot_context(fdict, get_description()) ctx['qc'] = loadqc(date=ctx['date']) ctx['pgconn'] = get_dbconn('isuag') ctx['nt'] = NetworkTable("ISUSM") # Adjust stations to make some room ctx['nt'].sts['BOOI4']['lon'] -= 0.15 ctx['nt'].sts['BOOI4']['lat'] -= 0.15 ctx['nt'].sts['AHTI4']['lon'] += 0.25 ctx['nt'].sts['AHTI4']['lat'] += 0.25 title = 'TBD' subtitle = 'TBD' if ctx['opt'] == '1': title = 'ISU Soil Moisture Max/Min 4 Inch Soil Temperature' subtitle = 'based on available hourly observations' data, df = plot1(ctx) elif ctx['opt'] == '2': title = 'ISU Soil Moisture Max/Min Air Temperature' subtitle = 'based on available daily summary data' data, df = plot2(ctx) elif ctx['opt'] == '3': title = 'ISU Soil Moisture Average 4 Inch Soil Temperature' subtitle = 'based on available daily summary data' data, df = plot3(ctx) elif ctx['opt'] == '4': title = 'ISU Soil Moisture Solar Radiation [MJ]' subtitle = 'based on available daily summary data' data, df = plot4(ctx) elif ctx['opt'] == '5': title = 'ISU Soil Moisture Potential Evapotranspiration [inch]' subtitle = 'based on available daily summary data' data, df = plot5(ctx, "dailyet") elif ctx['opt'] == '6': title = 'ISU Soil Moisture Precipitation [inch]' subtitle = ( 'based on available daily summary data, liquid equiv of snow ' 'estimated' ) data, df = plot5(ctx, "rain_mm_tot") elif ctx['opt'] == '7': title = 'ISU Soil Moisture Peak Wind Gust [MPH]' subtitle = 'based on available daily summary data' data, df = plot7(ctx) elif ctx['opt'] == '8': title = 'ISU Soil Moisture Average Wind Speed [MPH]' subtitle = 'based on available daily summary data' data, df = plot8(ctx) tle = ctx['date'].strftime("%b %-d, %Y") mp = MapPlot( sector='iowa', continentalcolor='white', nocaption=True, title='%s %s' % (tle, title), subtitle=subtitle) mp.drawcounties('#EEEEEE') mp.plot_station(data, fontsize=12) return mp.fig, df
def plotter(fdict): """ Go """ ctx = get_autoplot_context(fdict, get_description()) get_df(ctx) labels = {} data = {} for state, row in ctx["df"].iterrows(): val = row["departure"] data[state] = val if pd.isna(val): if pd.isna(row["avg"]): subscript = "M" else: subscript = "[-%.0f]" % (row["avg"], ) data[state] = 0 - row["avg"] else: subscript = "[%s%.0f]" % ("+" if val > 0 else "", val) subscript = "[0]" if subscript in ["[-0]", "[+0]"] else subscript labels[state] = "%s\n%s" % ( "M" if pd.isna(row["thisval"]) else int(row["thisval"]), subscript, ) mp = MapPlot(sector="conus", title=ctx["title"], subtitle=ctx["subtitle"]) levels = range(-40, 41, 10) cmap = plt.get_cmap(ctx["cmap"]) cmap.set_bad("white") mp.fill_states( data, ilabel=True, labels=labels, bins=levels, cmap=cmap, units="Absolute %", labelfontsize=16, ) 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 main(): """Go Main Go.""" pgconn = get_dbconn("idep") df = read_postgis( """ select f.huc_12, count(*) as fps, st_transform(h.simple_geom, 4326) as geo from flowpaths f JOIN huc12 h on (f.huc_12 = h.huc_12) WHERE f.scenario = 0 and h.scenario = 0 GROUP by f.huc_12, geo ORDER by fps ASC """, pgconn, index_col=None, geom_col="geo", ) bins = np.arange(1, 42, 2) cmap = plt.get_cmap("copper") cmap.set_over("white") cmap.set_under("thistle") norm = mpcolors.BoundaryNorm(bins, cmap.N) mp = MapPlot( continentalcolor="thistle", nologo=True, sector="custom", south=36.8, north=45.0, west=-99.2, east=-88.9, subtitle="", title=("DEP HUCs with <40 Flowpaths (%.0f/%.0f %.2f%%)" % ( len(df[df["fps"] < 40].index), len(df.index), len(df[df["fps"] < 40].index) / len(df.index) * 100.0, )), ) for _i, row in df.iterrows(): c = cmap(norm([row["fps"]]))[0] arr = np.asarray(row["geo"].exterior) points = mp.ax.projection.transform_points(ccrs.Geodetic(), arr[:, 0], arr[:, 1]) p = Polygon(points[:, :2], fc=c, ec="None", zorder=2, lw=0.1) mp.ax.add_patch(p) mp.drawcounties() mp.draw_colorbar(bins, cmap, norm, title="Count") mp.postprocess(filename="/tmp/huc12_cnts.png")
def main(): """Go Main Go.""" years = 12.0 # 2008 - 2019 pgconn = get_dbconn("idep") postgis = get_dbconn("postgis") # Get the initial geometries df = read_postgis( """ SELECT ugc, name, geom from ugcs WHERE end_ts is null and substr(ugc, 1, 3) = 'IAC' """, postgis, index_col="ugc", crs="EPSG:4326", ) scenario = 0 df2 = read_sql( """WITH data as ( SELECT r.huc_12, sum(avg_loss) * 4.163 / %s as detach, sum(avg_delivery) * 4.163 / %s as delivery, sum(avg_runoff) / 25.4 / %s as runoff from results_by_huc12 r , huc12 h WHERE r.huc_12 = h.huc_12 and h.states ~* 'IA' and r.scenario = %s and h.scenario = 0 and r.valid < '2020-01-01' and r.valid > '2008-01-01' GROUP by r.huc_12) SELECT ugc, avg(detach) as detach, avg(delivery) as delivery, avg(runoff) as runoff from data d JOIN huc12 h on (d.huc_12 = h.huc_12) WHERE h.scenario = 0 GROUP by ugc ORDER by delivery desc """, pgconn, params=(years, years, years, scenario), index_col="ugc", ) newcols = { "detach": "det%s" % (0, ), "delivery": "del%s" % (0, ), "runoff": "run%s" % (0, ), } for key, val in newcols.items(): df[val] = df2[key] df = df.sort_values("del0", ascending=False) print(df.head(10)) mp = MapPlot(title="2008-2019 DEP Top 10 Erosive Counties", logo="dep", caption="") df2 = df.head(10) mp.fill_ugcs(df2["del0"].to_dict()) mp.postprocess(filename="test.png")
def main(): """Go Main Go""" data = get_data() mp = MapPlot(sector='midwest', title='8 July 2018 USDA NASS Corn Progress Percent Silking', subtitle=('Top value is 2018 percentage, bottom value is ' 'departure from 2008-2017 avg')) data2 = {} labels = {} for state in data: val = data[state]['d2017'] - data[state]['avg'] data2[state] = val labels[state.encode('utf-8')] = "%i%%\n%s%.1f%%" % (data[state]['d2017'], "+" if val > 0 else "", val) print(labels) levels = range(-40, 41, 10) mp.fill_states(data2, ilabel=True, labels=labels, bins=levels, cmap=plt.get_cmap('RdBu_r'), units='Absolute %', labelfontsize=16) mp.postprocess(filename='test.png') mp.close()
def main(): """Go Main Go.""" pgconn = get_dbconn('idep') df = read_postgis(""" select f.huc_12, count(*) as fps, st_transform(h.simple_geom, 4326) as geo from flowpaths f JOIN huc12 h on (f.huc_12 = h.huc_12) WHERE f.scenario = 0 and h.scenario = 0 GROUP by f.huc_12, geo ORDER by fps ASC """, pgconn, index_col=None, geom_col='geo') bins = np.arange(1, 42, 2) cmap = plt.get_cmap('copper') cmap.set_over('white') cmap.set_under('thistle') norm = mpcolors.BoundaryNorm(bins, cmap.N) mp = MapPlot( continentalcolor='thistle', nologo=True, sector='custom', south=36.8, north=45.0, west=-99.2, east=-88.9, subtitle='', title=('DEP HUCs with <40 Flowpaths (%.0f/%.0f %.2f%%)' % ( len(df[df['fps'] < 40].index), len(df.index), len(df[df['fps'] < 40].index) / len(df.index) * 100. ))) for _i, row in df.iterrows(): c = cmap(norm([row['fps'], ]))[0] arr = np.asarray(row['geo'].exterior) points = mp.ax.projection.transform_points( ccrs.Geodetic(), arr[:, 0], arr[:, 1]) p = Polygon(points[:, :2], fc=c, ec='None', zorder=2, lw=0.1) mp.ax.add_patch(p) mp.drawcounties() mp.draw_colorbar( bins, cmap, norm, title='Count') mp.postprocess(filename='/tmp/huc12_cnts.png')
def makeplot(ts, routes='ac'): """ Generate two plots for a given time GMT """ pgconn = get_dbconn('smos', user='******') df = read_sql(""" WITH obs as ( SELECT grid_idx, avg(soil_moisture) * 100. as sm, avg(optical_depth) as od from data where valid BETWEEN %s and %s GROUP by grid_idx) SELECT ST_x(geom) as lon, ST_y(geom) as lat, CASE WHEN sm is Null THEN -1 ELSE sm END as sm, CASE WHEN od is Null THEN -1 ELSE od END as od from obs o JOIN grid g ON (o.grid_idx = g.idx) """, pgconn, params=(ts - datetime.timedelta(hours=6), ts + datetime.timedelta(hours=6)), index_col=None) if df.empty: print(("Did not find SMOS data for: %s-%s" ) % (ts - datetime.timedelta(hours=6), ts + datetime.timedelta(hours=6))) return for sector in ['midwest', 'iowa']: clevs = np.arange(0, 71, 5) mp = MapPlot(sector=sector, axisbg='white', title='SMOS Satellite: Soil Moisture (0-5cm)', subtitle="Satelite passes around %s UTC" % ( ts.strftime("%d %B %Y %H"),)) if sector == 'iowa': mp.drawcounties() cmap = cm.get_cmap('jet_r') cmap.set_under('#EEEEEE') cmap.set_over("k") mp.hexbin(df['lon'].values, df['lat'].values, df['sm'], clevs, units='%', cmap=cmap) pqstr = "plot %s %s00 smos_%s_sm%s.png smos_%s_sm%s.png png" % ( routes, ts.strftime("%Y%m%d%H"), sector, ts.strftime("%H"), sector, ts.strftime("%H")) mp.postprocess(pqstr=pqstr) mp.close() for sector in ['midwest', 'iowa']: clevs = np.arange(0, 1.001, 0.05) mp = MapPlot(sector=sector, axisbg='white', title=('SMOS Satellite: Land Cover Optical Depth ' '(microwave L-band)'), subtitle="Satelite passes around %s UTC" % ( ts.strftime("%d %B %Y %H"),)) if sector == 'iowa': mp.drawcounties() cmap = cm.get_cmap('jet') cmap.set_under('#EEEEEE') cmap.set_over("k") mp.hexbin(df['lon'].values, df['lat'].values, df['od'], clevs, cmap=cmap) pqstr = "plot %s %s00 smos_%s_od%s.png smos_%s_od%s.png png" % ( routes, ts.strftime("%Y%m%d%H"), sector, ts.strftime("%H"), sector, ts.strftime("%H")) mp.postprocess(pqstr=pqstr) mp.close()
def make_map(ts, ts2, scenario, v): """Make the map""" import matplotlib matplotlib.use('agg') from pyiem.plot.geoplot import MapPlot import matplotlib.pyplot as plt from matplotlib.patches import Polygon import matplotlib.colors as mpcolors import cartopy.crs as ccrs # suggested for runoff and precip if v in ['qc_precip', 'avg_runoff']: c = ['#ffffa6', '#9cf26d', '#76cc94', '#6399ba', '#5558a1'] # suggested for detachment elif v in ['avg_loss']: c = ['#cbe3bb', '#c4ff4d', '#ffff4d', '#ffc44d', '#ff4d4d', '#c34dee'] # suggested for delivery elif v in ['avg_delivery']: c = ['#ffffd2', '#ffff4d', '#ffe0a5', '#eeb74d', '#ba7c57', '#96504d'] cmap = mpcolors.ListedColormap(c, 'james') cmap.set_under('white') cmap.set_over('black') pgconn = get_dbconn('idep') cursor = pgconn.cursor() title = "for %s" % (ts.strftime("%-d %B %Y"), ) if ts != ts2: title = "for period between %s and %s" % (ts.strftime("%-d %b %Y"), ts2.strftime("%-d %b %Y")) m = MapPlot(axisbg='#EEEEEE', nologo=True, sector='custom', south=36.8, north=45.0, west=-99.2, east=-88.9, title='DEP %s by HUC12 %s' % (V2NAME[v], title), caption='Daily Erosion Project') # Check that we have data for this date! cursor.execute(""" SELECT value from properties where key = 'last_date_0' """) lastts = datetime.datetime.strptime(cursor.fetchone()[0], '%Y-%m-%d') floor = datetime.date(2007, 1, 1) if ts > lastts.date() or ts2 > lastts.date() or ts < floor: m.ax.text(0.5, 0.5, "Data Not Available\nPlease Check Back Later!", transform=m.ax.transAxes, fontsize=20, ha='center') ram = cStringIO.StringIO() plt.savefig(ram, format='png', dpi=100) ram.seek(0) return ram.read(), False cursor.execute( """ WITH data as ( SELECT huc_12, sum(""" + v + """) as d from results_by_huc12 WHERE scenario = %s and valid between %s and %s GROUP by huc_12) SELECT ST_Transform(simple_geom, 4326), coalesce(d.d, 0) from huc12 i LEFT JOIN data d ON (i.huc_12 = d.huc_12) WHERE i.scenario = %s """, (scenario, ts.strftime("%Y-%m-%d"), ts2.strftime("%Y-%m-%d"), scenario)) patches = [] data = [] for row in cursor: polygon = loads(row[0].decode('hex')) a = np.asarray(polygon.exterior) points = m.ax.projection.transform_points(ccrs.Geodetic(), a[:, 0], a[:, 1]) p = Polygon(points[:, :2], fc='white', ec='k', zorder=2, lw=.1) patches.append(p) data.append(row[1]) data = np.array(data) * V2MULTI[v] if np.max(data) < 0.05: bins = [0.01, 0.02, 0.03, 0.04, 0.05] else: bins = myjenks(data, 'bah', len(c)) norm = mpcolors.BoundaryNorm(bins, cmap.N) for val, patch in zip(data, patches): c = cmap(norm([ val, ]))[0] patch.set_facecolor(c) m.ax.add_patch(patch) lbl = [round(_, 2) for _ in bins] m.draw_colorbar(bins, cmap, norm, units=V2UNITS[v], clevlabels=lbl) ram = cStringIO.StringIO() plt.savefig(ram, format='png', dpi=100) ram.seek(0) return ram.read(), True
def plotter(fdict): """ Go """ ctx = util.get_autoplot_context(fdict, get_description()) ptype = ctx["ptype"] sdate = ctx["sdate"] edate = ctx["edate"] src = ctx["src"] opt = ctx["opt"] usdm = ctx["usdm"] if sdate.year != edate.year: raise NoDataFound("Sorry, do not support multi-year plots yet!") days = (edate - sdate).days sector = ctx["sector"] x0 = 0 x1 = -1 y0 = 0 y1 = -1 state = None if len(sector) == 2: state = sector sector = "state" title = compute_title(src, sdate, edate) if src == "mrms": ncfn = iemre.get_daily_mrms_ncname(sdate.year) clncfn = iemre.get_dailyc_mrms_ncname() ncvar = "p01d" source = "MRMS Q3" subtitle = "NOAA MRMS Project, GaugeCorr and RadarOnly" elif src == "iemre": ncfn = iemre.get_daily_ncname(sdate.year) clncfn = iemre.get_dailyc_ncname() ncvar = "p01d_12z" source = "IEM Reanalysis" subtitle = "IEM Reanalysis is derived from various NOAA datasets" else: ncfn = "/mesonet/data/prism/%s_daily.nc" % (sdate.year, ) clncfn = "/mesonet/data/prism/prism_dailyc.nc" ncvar = "ppt" source = "OSU PRISM" subtitle = ("PRISM Climate Group, Oregon State Univ., " "http://prism.oregonstate.edu, created 4 Feb 2004.") mp = MapPlot( sector=sector, state=state, axisbg="white", nocaption=True, title="%s:: %s Precip %s" % (source, title, PDICT3[opt]), subtitle="Data from %s" % (subtitle, ), titlefontsize=14, ) idx0 = iemre.daily_offset(sdate) idx1 = iemre.daily_offset(edate) + 1 if not os.path.isfile(ncfn): raise NoDataFound("No data for that year, sorry.") with util.ncopen(ncfn) as nc: if state is not None: x0, y0, x1, y1 = util.grid_bounds( nc.variables["lon"][:], nc.variables["lat"][:], state_bounds[state], ) elif sector in SECTORS: bnds = SECTORS[sector] x0, y0, x1, y1 = util.grid_bounds( nc.variables["lon"][:], nc.variables["lat"][:], [bnds[0], bnds[2], bnds[1], bnds[3]], ) lats = nc.variables["lat"][y0:y1] lons = nc.variables["lon"][x0:x1] if sdate == edate: p01d = mm2inch(nc.variables[ncvar][idx0, y0:y1, x0:x1]) elif (idx1 - idx0) < 32: p01d = mm2inch( np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0)) else: # Too much data can overwhelm this app, need to chunk it for i in range(idx0, idx1, 10): i2 = min([i + 10, idx1]) if idx0 == i: p01d = mm2inch( np.sum(nc.variables[ncvar][i:i2, y0:y1, x0:x1], 0)) else: p01d += mm2inch( np.sum(nc.variables[ncvar][i:i2, y0:y1, x0:x1], 0)) if np.ma.is_masked(np.max(p01d)): raise NoDataFound("Data Unavailable") plot_units = "inches" cmap = get_cmap(ctx["cmap"]) cmap.set_bad("white") if opt == "dep": # Do departure work now with util.ncopen(clncfn) as nc: climo = mm2inch( np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0)) p01d = p01d - climo [maxv] = np.percentile(np.abs(p01d), [99]) clevs = np.around(np.linspace(0 - maxv, maxv, 11), decimals=2) elif opt == "per": with util.ncopen(clncfn) as nc: climo = mm2inch( np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0)) p01d = p01d / climo * 100.0 cmap.set_under("white") cmap.set_over("black") clevs = [1, 10, 25, 50, 75, 100, 125, 150, 200, 300, 500] plot_units = "percent" else: p01d = np.where(p01d < 0.001, np.nan, p01d) cmap.set_under("white") clevs = [0.01, 0.1, 0.3, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 8, 10] if days > 6: clevs = [0.01, 0.3, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 10, 15, 20] if days > 29: clevs = [0.01, 0.5, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 35] if days > 90: clevs = [0.01, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 35, 40] x2d, y2d = np.meshgrid(lons, lats) if ptype == "c": mp.contourf(x2d, y2d, p01d, clevs, cmap=cmap, units=plot_units, iline=False) else: res = mp.pcolormesh(x2d, y2d, p01d, clevs, cmap=cmap, units=plot_units) res.set_rasterized(True) if sector != "midwest": mp.drawcounties() mp.drawcities() if usdm == "yes": mp.draw_usdm(edate, filled=False, hatched=True) return mp.fig
def plotter(fdict): """ Go """ ctx = get_autoplot_context(fdict, get_description()) level = ctx['level'] station = ctx['station'][:4] t = ctx['t'] p = ctx['p'] month = ctx['month'] if month == 'all': months = range(1, 13) elif month == 'fall': months = [9, 10, 11] elif month == 'winter': months = [12, 1, 2] elif month == 'spring': months = [3, 4, 5] elif month == 'summer': months = [6, 7, 8] else: ts = datetime.datetime.strptime("2000-" + month + "-01", '%Y-%b-%d') # make sure it is length two for the trick below in SQL months = [ts.month, 999] ones = np.ones((int(YSZ), int(XSZ))) counts = np.zeros((int(YSZ), int(XSZ))) # counts = np.load('counts.npy') lons = np.arange(GRIDWEST, GRIDEAST, griddelta) lats = np.arange(GRIDSOUTH, GRIDNORTH, griddelta) pgconn = get_dbconn('postgis') hour = int(p.split(".")[2]) df = read_postgis( """ WITH data as ( select product_issue, issue, expire, geom, rank() OVER (PARTITION by issue ORDER by product_issue DESC) from spc_outlooks where outlook_type = %s and day = %s and threshold = %s and category = %s and ST_Within(geom, ST_GeomFromEWKT('SRID=4326;POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))')) and extract(hour from product_issue at time zone 'UTC') in %s and extract(month from product_issue) in %s ) SELECT * from data where rank = 1 """, pgconn, params=(p.split(".")[1], p.split(".")[0], level.split(".", 1)[1], level.split(".")[0], GRIDWEST, GRIDSOUTH, GRIDWEST, GRIDNORTH, GRIDEAST, GRIDNORTH, GRIDEAST, GRIDSOUTH, GRIDWEST, GRIDSOUTH, tuple([hour - 1, hour, hour + 1]), tuple(months)), geom_col='geom') if df.empty: raise NoDataFound("No results found for query") for _, row in df.iterrows(): zs = zonal_stats(row['geom'], ones, affine=PRECIP_AFF, nodata=-1, all_touched=True, raster_out=True) for z in zs: aff = z['mini_raster_affine'] west = aff.c north = aff.f raster = np.flipud(z['mini_raster_array']) x0 = int((west - GRIDWEST) / griddelta) y1 = int((north - GRIDSOUTH) / griddelta) dy, dx = np.shape(raster) x1 = x0 + dx y0 = y1 - dy counts[y0:y1, x0:x1] += np.where(raster.mask, 0, 1) mindate = datetime.datetime(2014, 10, 1) if level not in ['CATEGORICAL.MRGL', 'CATEGORICAL.ENH']: mindate = datetime.datetime(2002, 1, 1) if p.split(".")[1] == 'F': mindate = datetime.datetime(2017, 1, 1) years = (datetime.datetime.now() - mindate).total_seconds() / 365.25 / 86400. data = counts / years subtitle = "Found %s events for CONUS between %s and %s" % ( len(df.index), df['issue'].min().strftime("%d %b %Y"), df['issue'].max().strftime("%d %b %Y")) if t == 'cwa': sector = 'cwa' subtitle = "Plotted for %s (%s). %s" % ( ctx['_nt'].sts[station]['name'], station, subtitle) else: sector = 'state' if len(ctx['csector']) == 2 else ctx['csector'] mp = MapPlot(sector=sector, state=ctx['csector'], cwa=(station if len(station) == 3 else station[1:]), axisbg='white', title='SPC %s Outlook [%s] of at least %s' % ( ISSUANCE[p], month.capitalize(), OUTLOOKS[level].split("(")[0].strip(), ), subtitle=subtitle, nocaption=True, titlefontsize=16) # Get the main axes bounds if t == 'state' and ctx['csector'] == 'conus': domain = data lons, lats = np.meshgrid(lons, lats) df2 = pd.DataFrame() else: (west, east, south, north) = mp.ax.get_extent(ccrs.PlateCarree()) i0 = int((west - GRIDWEST) / griddelta) j0 = int((south - GRIDSOUTH) / griddelta) i1 = int((east - GRIDWEST) / griddelta) j1 = int((north - GRIDSOUTH) / griddelta) jslice = slice(j0, j1) islice = slice(i0, i1) domain = data[jslice, islice] lons, lats = np.meshgrid(lons[islice], lats[jslice]) df2 = pd.DataFrame({ 'lat': lats.ravel(), 'lon': lons.ravel(), 'freq': domain.ravel() }) rng = [ round(x, 2) for x in np.linspace(max([0.01, np.min(domain) - 0.5]), np.max(domain) + 0.5, 10) ] cmap = plt.get_cmap(ctx['cmap']) cmap.set_under('white') cmap.set_over('black') res = mp.pcolormesh(lons, lats, domain, rng, cmap=cmap, clip_on=False, units='days per year') # Cut down on SVG et al size res.set_rasterized(True) if ctx['drawc'] == 'yes': mp.drawcounties() return mp.fig, df2
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
def plotter(fdict): """ Go """ ctx = get_autoplot_context(fdict, get_description()) # Covert datetime to UTC ctx["sdate"] = ctx["sdate"].replace(tzinfo=pytz.utc) ctx["edate"] = ctx["edate"].replace(tzinfo=pytz.utc) state = ctx["state"] phenomena = ctx["phenomena"] significance = ctx["significance"] station = ctx["station"][:4] t = ctx["t"] ilabel = ctx["ilabel"] == "yes" geo = ctx["geo"] if geo == "ugc": do_ugc(ctx) elif geo == "polygon": do_polygon(ctx) subtitle = "based on IEM Archives %s" % (ctx.get("subtitle", ""), ) if t == "cwa": subtitle = "Plotted for %s (%s), %s" % ( ctx["_nt"].sts[station]["name"], station, subtitle, ) else: subtitle = "Plotted for %s, %s" % (state_names[state], subtitle) m = MapPlot( sector=("state" if t == "state" else "cwa"), state=state, cwa=(station if len(station) == 3 else station[1:]), axisbg="white", title=("%s %s (%s.%s)") % ( ctx["title"], vtec.get_ps_string(phenomena, significance), phenomena, significance, ), subtitle=subtitle, nocaption=True, titlefontsize=16, ) cmap = plt.get_cmap(ctx["cmap"]) cmap.set_under("white") cmap.set_over("white") if geo == "ugc": m.fill_ugcs(ctx["data"], ctx["bins"], cmap=cmap, ilabel=ilabel) else: res = m.pcolormesh( ctx["lons"], ctx["lats"], ctx["data"], ctx["bins"], cmap=cmap, units="count", ) # Cut down on SVG et al size res.set_rasterized(True) if ctx["drawc"] == "yes": m.drawcounties() return m.fig, ctx["df"]
def plotter(fdict): """ Go """ ctx = get_autoplot_context(fdict, get_description()) ctx["qc"] = loadqc(date=ctx["date"]) ctx["pgconn"] = get_dbconn("isuag") ctx["nt"] = NetworkTable("ISUSM") if not ctx["nt"].sts: raise NoDataFound("No station metadata found.") # Adjust stations to make some room ctx["nt"].sts["BOOI4"]["lon"] -= 0.15 ctx["nt"].sts["BOOI4"]["lat"] -= 0.15 ctx["nt"].sts["AHTI4"]["lon"] += 0.25 ctx["nt"].sts["AHTI4"]["lat"] += 0.25 title = "TBD" subtitle = "TBD" if ctx["opt"] == "1": title = "ISU Soil Moisture Max/Min 4 Inch Soil Temperature" subtitle = "based on available hourly observations" data, df = plot1(ctx) elif ctx["opt"] == "2": title = "ISU Soil Moisture Max/Min Air Temperature" subtitle = "based on available daily summary data" data, df = plot2(ctx) elif ctx["opt"] == "3": title = "ISU Soil Moisture Average 4 Inch Soil Temperature" subtitle = "based on available daily summary data" data, df = plot3(ctx) elif ctx["opt"] == "4": title = "ISU Soil Moisture Solar Radiation [MJ]" subtitle = "based on available daily summary data" data, df = plot4(ctx) elif ctx["opt"] == "5": title = "ISU Soil Moisture Potential Evapotranspiration [inch]" subtitle = "based on available daily summary data" data, df = plot5(ctx, "dailyet") elif ctx["opt"] == "6": title = "ISU Soil Moisture Precipitation [inch]" subtitle = ( "based on available daily summary data, liquid equiv of snow " "estimated") data, df = plot5(ctx, "rain_mm_tot") elif ctx["opt"] == "7": title = "ISU Soil Moisture Peak Wind Gust [MPH]" subtitle = "based on available daily summary data" data, df = plot7(ctx) elif ctx["opt"] == "8": title = "ISU Soil Moisture Average Wind Speed [MPH]" subtitle = "based on available daily summary data" data, df = plot8(ctx) tle = ctx["date"].strftime("%b %-d, %Y") mp = MapPlot( sector="iowa", continentalcolor="white", nocaption=True, title="%s %s" % (tle, title), subtitle=subtitle, ) mp.drawcounties("#EEEEEE") mp.plot_station(data, fontsize=12) return mp.fig, df
def makeplot(ts, routes="ac"): """ Generate two plots for a given time GMT """ pgconn = get_dbconn("smos", user="******") df = read_sql( """ WITH obs as ( SELECT grid_idx, avg(soil_moisture) * 100. as sm, avg(optical_depth) as od from data where valid BETWEEN %s and %s GROUP by grid_idx) SELECT ST_x(geom) as lon, ST_y(geom) as lat, CASE WHEN sm is Null THEN -1 ELSE sm END as sm, CASE WHEN od is Null THEN -1 ELSE od END as od from obs o JOIN grid g ON (o.grid_idx = g.idx) """, pgconn, params=( ts - datetime.timedelta(hours=6), ts + datetime.timedelta(hours=6), ), index_col=None, ) if df.empty: LOG.info( "Did not find SMOS data for: %s-%s", ts - datetime.timedelta(hours=6), ts + datetime.timedelta(hours=6), ) return for sector in ["midwest", "iowa"]: clevs = np.arange(0, 71, 5) mp = MapPlot( sector=sector, axisbg="white", title="SMOS Satellite: Soil Moisture (0-5cm)", subtitle="Satelite passes around %s UTC" % (ts.strftime("%d %B %Y %H"), ), ) if sector == "iowa": mp.drawcounties() cmap = get_cmap("jet_r") cmap.set_under("#EEEEEE") cmap.set_over("k") mp.hexbin( df["lon"].values, df["lat"].values, df["sm"], clevs, units="%", cmap=cmap, ) pqstr = "plot %s %s00 smos_%s_sm%s.png smos_%s_sm%s.png png" % ( routes, ts.strftime("%Y%m%d%H"), sector, ts.strftime("%H"), sector, ts.strftime("%H"), ) mp.postprocess(pqstr=pqstr) mp.close() for sector in ["midwest", "iowa"]: clevs = np.arange(0, 1.001, 0.05) mp = MapPlot( sector=sector, axisbg="white", title=("SMOS Satellite: Land Cover Optical Depth " "(microwave L-band)"), subtitle="Satelite passes around %s UTC" % (ts.strftime("%d %B %Y %H"), ), ) if sector == "iowa": mp.drawcounties() cmap = get_cmap("jet") cmap.set_under("#EEEEEE") cmap.set_over("k") mp.hexbin(df["lon"].values, df["lat"].values, df["od"], clevs, cmap=cmap) pqstr = "plot %s %s00 smos_%s_od%s.png smos_%s_od%s.png png" % ( routes, ts.strftime("%Y%m%d%H"), sector, ts.strftime("%H"), sector, ts.strftime("%H"), ) mp.postprocess(pqstr=pqstr) mp.close()
def plotter(fdict): """ Go """ ctx = util.get_autoplot_context(fdict, get_description()) ptype = ctx['ptype'] sdate = ctx['sdate'] edate = ctx['edate'] src = ctx['src'] opt = ctx['opt'] usdm = ctx['usdm'] if sdate.year != edate.year: raise NoDataFound('Sorry, do not support multi-year plots yet!') days = (edate - sdate).days sector = ctx['sector'] if sdate == edate: title = sdate.strftime("%-d %B %Y") else: title = "%s to %s (inclusive)" % (sdate.strftime("%-d %b"), edate.strftime("%-d %b %Y")) x0 = 0 x1 = -1 y0 = 0 y1 = -1 state = None if len(sector) == 2: state = sector sector = 'state' if src == 'mrms': ncfn = iemre.get_daily_mrms_ncname(sdate.year) clncfn = iemre.get_dailyc_mrms_ncname() ncvar = 'p01d' source = 'MRMS Q3' subtitle = 'NOAA MRMS Project, GaugeCorr and RadarOnly' elif src == 'iemre': ncfn = iemre.get_daily_ncname(sdate.year) clncfn = iemre.get_dailyc_ncname() ncvar = 'p01d_12z' source = 'IEM Reanalysis' subtitle = 'IEM Reanalysis is derived from various NOAA datasets' else: ncfn = "/mesonet/data/prism/%s_daily.nc" % (sdate.year, ) clncfn = "/mesonet/data/prism/prism_dailyc.nc" ncvar = 'ppt' source = 'OSU PRISM' subtitle = ('PRISM Climate Group, Oregon State Univ., ' 'http://prism.oregonstate.edu, created 4 Feb 2004.') mp = MapPlot(sector=sector, state=state, axisbg='white', nocaption=True, title='%s:: %s Precip %s' % (source, title, PDICT3[opt]), subtitle='Data from %s' % (subtitle, ), titlefontsize=14) idx0 = iemre.daily_offset(sdate) idx1 = iemre.daily_offset(edate) + 1 if not os.path.isfile(ncfn): raise NoDataFound("No data for that year, sorry.") with util.ncopen(ncfn) as nc: if state is not None: x0, y0, x1, y1 = util.grid_bounds(nc.variables['lon'][:], nc.variables['lat'][:], state_bounds[state]) elif sector in SECTORS: bnds = SECTORS[sector] x0, y0, x1, y1 = util.grid_bounds( nc.variables['lon'][:], nc.variables['lat'][:], [bnds[0], bnds[2], bnds[1], bnds[3]]) lats = nc.variables['lat'][y0:y1] lons = nc.variables['lon'][x0:x1] if sdate == edate: p01d = distance(nc.variables[ncvar][idx0, y0:y1, x0:x1], 'MM').value('IN') elif (idx1 - idx0) < 32: p01d = distance( np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0), 'MM').value('IN') else: # Too much data can overwhelm this app, need to chunk it for i in range(idx0, idx1, 10): i2 = min([i + 10, idx1]) if idx0 == i: p01d = distance( np.sum(nc.variables[ncvar][i:i2, y0:y1, x0:x1], 0), 'MM').value('IN') else: p01d += distance( np.sum(nc.variables[ncvar][i:i2, y0:y1, x0:x1], 0), 'MM').value('IN') if np.ma.is_masked(np.max(p01d)): raise NoDataFound("Data Unavailable") units = 'inches' cmap = plt.get_cmap(ctx['cmap']) cmap.set_bad('white') if opt == 'dep': # Do departure work now with util.ncopen(clncfn) as nc: climo = distance( np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0), 'MM').value('IN') p01d = p01d - climo [maxv] = np.percentile(np.abs(p01d), [ 99, ]) clevs = np.around(np.linspace(0 - maxv, maxv, 11), decimals=2) elif opt == 'per': with util.ncopen(clncfn) as nc: climo = distance( np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0), 'MM').value('IN') p01d = p01d / climo * 100. cmap.set_under('white') cmap.set_over('black') clevs = [1, 10, 25, 50, 75, 100, 125, 150, 200, 300, 500] units = 'percent' else: p01d = np.where(p01d < 0.001, np.nan, p01d) cmap.set_under('white') clevs = [0.01, 0.1, 0.3, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 8, 10] if days > 6: clevs = [0.01, 0.3, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 10, 15, 20] if days > 29: clevs = [0.01, 0.5, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 35] if days > 90: clevs = [0.01, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 35, 40] x2d, y2d = np.meshgrid(lons, lats) if ptype == 'c': mp.contourf(x2d, y2d, p01d, clevs, cmap=cmap, units=units, iline=False) else: res = mp.pcolormesh(x2d, y2d, p01d, clevs, cmap=cmap, units=units) res.set_rasterized(True) if sector != 'midwest': mp.drawcounties() mp.drawcities() if usdm == 'yes': mp.draw_usdm(edate, filled=False, hatched=True) return mp.fig
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 main(): """Go Main""" nt = NetworkTable(['AWOS', 'IA_ASOS']) pgconn = psycopg2.connect(database='mos', host='localhost', user='******', port=5555) df = read_sql(""" select station, avg(pwater) from model_gridpoint where model = 'NAM' and extract(hour from runtime at time zone 'UTC') = 0 and pwater > 0 and pwater < 100 and extract(month from runtime) between 4 and 9 and ftime = runtime GROUP by station ORDER by avg """, pgconn, index_col='station') df['lat'] = None df['lon'] = None df['pwater'] = distance(df['avg'].values, 'MM').value('IN') for station in df.index.values: df.at[station, 'lat'] = nt.sts[station[1:]]['lat'] df.at[station, 'lon'] = nt.sts[station[1:]]['lon'] mp = MapPlot(title=('00z Analysis NAM Warm-Season Average ' 'Precipitable Water [in]'), subtitle=("based on grid point samples " "from 2004-2017 (April-September)")) cmap = plt.get_cmap("plasma_r") cmap.set_under('white') cmap.set_over('black') mp.contourf(df['lon'], df['lat'], df['pwater'], np.arange(0.94, 1.13, 0.03), cmap=cmap, units='inch') mp.drawcounties() mp.drawcities() mp.postprocess(filename='170901.png') mp.close()
def plotter(fdict): """ Go """ fix() pgconn = get_dbconn("afos") ctx = get_autoplot_context(fdict, get_description()) pil = ctx["pil"][:3] if ctx["ets"].astimezone(pytz.UTC) > utc(): ctx["ets"] = utc() df = read_sql( ("SELECT source, pil, min(entered at time zone 'UTC') as first, " "max(entered at time zone 'UTC') as last, count(*) from products " "WHERE substr(pil, 1, 3) = %s and entered >= %s and entered < %s " "GROUP by source, pil ORDER by source, pil ASC"), pgconn, params=(pil, ctx["sts"], ctx["ets"]), index_col=None, ) if df.empty: raise NoDataFound("No text products found for query, sorry.") data = {} if ctx["var"] == "count": gdf = df.groupby("source").sum() elif ctx["var"] == "last": gdf = df.groupby("source").max() elif ctx["var"] == "first": gdf = df.groupby("source").min() minval = 1 maxval = gdf["count"].max() if ctx["var"] in ["last", "first"]: minval = gdf[ctx["var"]].min().year maxval = gdf[ctx["var"]].max().year if (maxval - minval) < 10: bins = range(minval - 1, maxval + 2) else: bins = np.linspace(minval, maxval + 2, 10, dtype="i") for source, row in gdf.iterrows(): if source == "PABR": continue key = source[1:] if key == "JSJ": key = "SJU" if ctx["var"] == "count": data[key] = row["count"] else: data[key] = row[ctx["var"]].year mp = MapPlot( title="NWS %s of %s" % (PDICT[ctx["var"]], prodDefinitions[pil]), subtitle=("Plot valid between %s UTC and %s UTC, " "based on unofficial IEM Archives") % ( ctx["sts"].strftime("%d %b %Y %H:%M"), ctx["ets"].strftime("%d %b %Y %H:%M"), ), sector="nws", nocaption=True, ) mp.fill_cwas( data, ilabel=True, lblformat="%.0f", cmap=ctx["cmap"], extend="neither", bins=bins, units="count" if ctx["var"] == "count" else "year", ) 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 """ ctx = util.get_autoplot_context(fdict, get_description()) date = ctx['date'] sector = ctx['sector'] threshold = ctx['threshold'] threshold_mm = distance(threshold, 'IN').value('MM') window_sts = date - datetime.timedelta(days=90) if window_sts.year != date.year: raise NoDataFound('Sorry, do not support multi-year plots yet!') # idx0 = iemre.daily_offset(window_sts) idx1 = iemre.daily_offset(date) ncfn = iemre.get_daily_mrms_ncname(date.year) if not os.path.isfile(ncfn): raise NoDataFound("No data found.") ncvar = 'p01d' # Get the state weight df = gpd.GeoDataFrame.from_postgis(""" SELECT the_geom from states where state_abbr = %s """, util.get_dbconn('postgis'), params=(sector, ), index_col=None, geom_col='the_geom') czs = CachingZonalStats(iemre.MRMS_AFFINE) with util.ncopen(ncfn) as nc: czs.gen_stats( np.zeros((nc.variables['lat'].size, nc.variables['lon'].size)), df['the_geom']) jslice = None islice = None for nav in czs.gridnav: # careful here as y is flipped in this context jslice = slice(nc.variables['lat'].size - (nav.y0 + nav.ysz), nc.variables['lat'].size - nav.y0) islice = slice(nav.x0, nav.x0 + nav.xsz) grid = np.zeros( (jslice.stop - jslice.start, islice.stop - islice.start)) total = np.zeros( (jslice.stop - jslice.start, islice.stop - islice.start)) for i, idx in enumerate(range(idx1, idx1 - 90, -1)): total += nc.variables[ncvar][idx, jslice, islice] grid = np.where(np.logical_and(grid == 0, total > threshold_mm), i, grid) lon = nc.variables['lon'][islice] lat = nc.variables['lat'][jslice] mp = MapPlot(sector='state', state=sector, titlefontsize=14, subtitlefontsize=12, title=("NOAA MRMS Q3: Number of Recent Days " "till Accumulating %s\" of Precip") % (threshold, ), subtitle=("valid %s: based on per calendar day " "estimated preciptation, GaugeCorr and " "RadarOnly products") % (date.strftime("%-d %b %Y"), )) x, y = np.meshgrid(lon, lat) cmap = plt.get_cmap(ctx['cmap']) cmap.set_over('k') cmap.set_under('white') mp.pcolormesh(x, y, grid, np.arange(0, 81, 10), cmap=cmap, units='days') mp.drawcounties() mp.drawcities() return mp.fig
def plotter(fdict): """ Go """ pgconn = get_dbconn("postgis") ctx = get_autoplot_context(fdict, get_description()) utcvalid = ctx.get("valid") wfo = ctx["wfo"] tzname = ctx["_nt"].sts[wfo]["tzname"] p1 = ctx["phenomenav"][:2] s1 = ctx["significancev"][:1] etn = int(ctx["etn"]) year = int(ctx["year"]) table = "warnings_%s" % (year, ) df = read_postgis( """ SELECT w.ugc, simple_geom, u.name, issue at time zone 'UTC' as issue, expire at time zone 'UTC' as expire, init_expire at time zone 'UTC' as init_expire, 1 as val, status from """ + table + """ w JOIN ugcs u on (w.gid = u.gid) WHERE w.wfo = %s and eventid = %s and significance = %s and phenomena = %s ORDER by issue ASC """, pgconn, params=(wfo[-3:], etn, s1, p1), index_col="ugc", geom_col="simple_geom", ) if df.empty: raise NoDataFound("VTEC Event was not found, sorry.") table = "sbw_%s" % (year, ) sbwdf = read_postgis( """ SELECT status, geom, polygon_begin at time zone 'UTC' as polygon_begin, polygon_end at time zone 'UTC' as polygon_end from """ + table + """ WHERE wfo = %s and eventid = %s and significance = %s and phenomena = %s ORDER by polygon_begin ASC """, pgconn, params=(wfo[-3:], etn, s1, p1), geom_col="geom", ) if utcvalid is None: utcvalid = df["issue"].max() else: # hack for an assumption below utcvalid = pd.Timestamp(utcvalid.replace(tzinfo=None)) def m(valid): """Convert to our local timestamp.""" return (valid.tz_localize(pytz.UTC).astimezone( pytz.timezone(tzname)).strftime(TFORMAT)) df["color"] = vtec.NWS_COLORS.get("%s.%s" % (p1, s1), "#FF0000") if not sbwdf.empty: df["color"] = "tan" bounds = df["simple_geom"].total_bounds buffer = 0.4 mp = MapPlot( subtitle="Map Valid: %s, Event: %s to %s" % (m(utcvalid), m(df["issue"].min()), m(df["expire"].max())), title="%s %s %s %s (%s.%s) #%s" % ( year, wfo, vtec.VTEC_PHENOMENA.get(p1, p1), vtec.VTEC_SIGNIFICANCE.get(s1, s1), p1, s1, etn, ), sector="custom", west=bounds[0] - buffer, south=bounds[1] - buffer, east=bounds[2] + buffer, north=bounds[3] + buffer, nocaption=True, ) mp.sector = "cwa" mp.cwa = wfo[-3:] # CAN statements come here with time == expire :/ df2 = df[(df["issue"] <= utcvalid) & (df["expire"] > utcvalid)] if df2.empty: mp.ax.text( 0.5, 0.5, "Event No Longer Active", zorder=1000, transform=mp.ax.transAxes, fontsize=24, ha="center", ) else: mp.fill_ugcs( df2["val"].to_dict(), color=df2["color"].to_dict(), nocbar=True, labels=df2["name"].to_dict(), missingval="", ilabel=(len(df2.index) <= 10), labelbuffer=5, ) if not sbwdf.empty: color = vtec.NWS_COLORS.get("%s.%s" % (p1, s1), "#FF0000") poly = sbwdf.iloc[0]["geom"] df2 = sbwdf[(sbwdf["polygon_begin"] <= utcvalid) & (sbwdf["polygon_end"] > utcvalid)] if not df2.empty: # draw new mp.ax.add_geometries( [poly], ccrs.PlateCarree(), facecolor="None", edgecolor="k", zorder=Z_OVERLAY2 - 1, ) poly = df2.iloc[0]["geom"] mp.ax.add_geometries( [poly], ccrs.PlateCarree(), facecolor=color, alpha=0.5, edgecolor="k", zorder=Z_OVERLAY2, ) if len(df.index) > 10: mp.drawcities() return mp.fig, df.drop("simple_geom", axis=1)