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 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 """ 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 """ 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 """ 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 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 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 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 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: 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"] 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 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 make_map(huc, ts, ts2, scenario, v, form): """Make the map""" projection = EPSG[5070] plt.close() # suggested for runoff and precip if v in ["qc_precip", "avg_runoff"]: # c = ['#ffffa6', '#9cf26d', '#76cc94', '#6399ba', '#5558a1'] cmap = james() # suggested for detachment elif v in ["avg_loss"]: # c =['#cbe3bb', '#c4ff4d', '#ffff4d', '#ffc44d', '#ff4d4d', '#c34dee'] cmap = dep_erosion() # suggested for delivery elif v in ["avg_delivery"]: # c =['#ffffd2', '#ffff4d', '#ffe0a5', '#eeb74d', '#ba7c57', '#96504d'] cmap = dep_erosion() 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"), ) if "averaged" in form: title = "averaged between %s and %s (2008-2017)" % ( ts.strftime("%-d %b"), ts2.strftime("%-d %b"), ) # 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: plt.text( 0.5, 0.5, "Data Not Available\nPlease Check Back Later!", fontsize=20, ha="center", ) ram = BytesIO() plt.savefig(ram, format="png", dpi=100) plt.close() ram.seek(0) return ram.read(), False if huc is None: huclimiter = "" elif len(huc) == 8: huclimiter = " and substr(i.huc_12, 1, 8) = '%s' " % (huc,) elif len(huc) == 12: huclimiter = " and i.huc_12 = '%s' " % (huc,) if "iowa" in form: huclimiter += " and i.states ~* 'IA' " if "mn" in form: huclimiter += " and i.states ~* 'MN' " if "averaged" in form: # 11 years of data is standard # 10 years is for the switchgrass one-off with get_sqlalchemy_conn("idep") as conn: df = read_postgis( f""" WITH data as ( SELECT huc_12, sum({v}) / 10. as d from results_by_huc12 WHERE scenario = %s and to_char(valid, 'mmdd') between %s and %s and valid between '2008-01-01' and '2018-01-01' GROUP by huc_12) SELECT simple_geom as geom, coalesce(d.d, 0) * %s as data from huc12 i LEFT JOIN data d ON (i.huc_12 = d.huc_12) WHERE i.scenario = %s {huclimiter} """, conn, params=( scenario, ts.strftime("%m%d"), ts2.strftime("%m%d"), V2MULTI[v], 0, ), geom_col="geom", ) else: with get_sqlalchemy_conn("idep") as conn: df = read_postgis( f""" 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 simple_geom as geom, coalesce(d.d, 0) * %s as data from huc12 i LEFT JOIN data d ON (i.huc_12 = d.huc_12) WHERE i.scenario = %s {huclimiter} """, conn, params=( scenario, ts.strftime("%Y-%m-%d"), ts2.strftime("%Y-%m-%d"), V2MULTI[v], 0, ), geom_col="geom", ) minx, miny, maxx, maxy = df["geom"].total_bounds buf = 10000.0 # 10km m = MapPlot( axisbg="#EEEEEE", logo="dep", sector="custom", south=miny - buf, north=maxy + buf, west=minx - buf, east=maxx + buf, projection=projection, title="DEP %s by HUC12 %s" % (V2NAME[v], title), titlefontsize=16, caption="Daily Erosion Project", ) if ts == ts2: # Daily bins = RAMPS["english"][0] else: bins = RAMPS["english"][1] norm = mpcolors.BoundaryNorm(bins, cmap.N) for _, row in df.iterrows(): p = Polygon( row["geom"].exterior.coords, fc=cmap(norm([row["data"]]))[0], ec="k", zorder=5, lw=0.1, ) m.ax.add_patch(p) label_scenario(m.ax, scenario, pgconn) lbl = [round(_, 2) for _ in bins] if huc is not None: m.drawcounties() m.drawcities() m.draw_colorbar( bins, cmap, norm, units=V2UNITS[v], clevlabels=lbl, spacing="uniform" ) if "progressbar" in form: fig = plt.gcf() avgval = df["data"].mean() fig.text( 0.01, 0.905, "%s: %4.1f T/a" % (ts.year if "averaged" not in form else "Avg", avgval), fontsize=14, ) bar_width = 0.758 # yes, a small one off with years having 366 days proportion = (ts2 - ts).days / 365.0 * bar_width rect1 = Rectangle( (0.15, 0.905), bar_width, 0.02, color="k", zorder=40, transform=fig.transFigure, figure=fig, ) fig.patches.append(rect1) rect2 = Rectangle( (0.151, 0.907), proportion, 0.016, color=cmap(norm([avgval]))[0], zorder=50, transform=fig.transFigure, figure=fig, ) fig.patches.append(rect2) if "cruse" in form: # Crude conversion of T/a to mm depth depth = avgval / 5.0 m.ax.text( 0.9, 0.92, "%.2fmm" % (depth,), zorder=1000, fontsize=24, transform=m.ax.transAxes, ha="center", va="center", bbox=dict(color="k", alpha=0.5, boxstyle="round,pad=0.1"), color="white", ) ram = BytesIO() plt.savefig(ram, format="png", dpi=100) plt.close() 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'] 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("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 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 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 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