From 51a55972e26eb15a8d9d99a35797ca2ca5503b39 Mon Sep 17 00:00:00 2001 From: akrherz Date: Thu, 5 Dec 2024 13:16:29 -0600 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=93=9D=20Doc=20CF6=20weather=20code?= =?UTF-8?q?=20meanings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://mesonet.agron.iastate.edu/nws/cf6table.php --- htdocs/nws/cf6table.php | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/htdocs/nws/cf6table.php b/htdocs/nws/cf6table.php index 5b5d792d20..d70791dc67 100644 --- a/htdocs/nws/cf6table.php +++ b/htdocs/nws/cf6table.php @@ -72,7 +72,8 @@ Avg SpeedMax SpeedAvg Drct Max GustGust Drct Minutes SunshinePoss Sunshine - Cloud SSWeather Codes + Cloud SS + Weather Codes [1] @@ -192,6 +193,31 @@ function trace($val) {$table} +

1. Weather Codes: + +
The numeric weather codes shown above are just concatenated values. For +instance, a value of 12 implies a 1 and a 2 weather +code. + +
+ + + + + + + + + + + + + + + + +
CodeMeaning
1Fog or Mist
2Fog or Vis 0.25 mile or less
3Thunder
4Ice pellets
5Hail
6Freezing Rain or Drizzle
7Duststorm or Sandstorm vis 0.25 mile or less
8Smoke or Haze
9Blowing Snow
XTornado

+ EOF; $t->headextra = << From aaca751ba8cb5ce39bbd60581de23cd16305970c Mon Sep 17 00:00:00 2001 From: akrherz Date: Thu, 5 Dec 2024 14:15:41 -0600 Subject: [PATCH 2/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Autoplot=20refactoring?= =?UTF-8?q?=20for=20month2months?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pylib/iemweb/autoplot/scripts/p15.py | 14 ++--- pylib/iemweb/autoplot/scripts/p16.py | 22 +------ pylib/iemweb/autoplot/scripts/p19.py | 23 ++----- pylib/iemweb/autoplot/scripts/p41.py | 78 +++++++++--------------- pylib/iemweb/autoplot/scripts/p42.py | 20 ++---- pylib/iemweb/autoplot/scripts/p46.py | 23 ++----- pylib/iemweb/autoplot/scripts/p69.py | 20 ++---- pylib/iemweb/autoplot/scripts/p76.py | 16 ++--- pylib/iemweb/autoplot/scripts/p78.py | 17 +----- pylib/iemweb/autoplot/scripts/p79.py | 21 ++----- pylib/iemweb/autoplot/scripts100/p106.py | 19 +----- pylib/iemweb/autoplot/scripts100/p125.py | 22 +------ pylib/iemweb/autoplot/scripts100/p131.py | 21 ++----- pylib/iemweb/autoplot/scripts100/p132.py | 20 +----- pylib/iemweb/autoplot/scripts100/p139.py | 17 +----- pylib/iemweb/autoplot/scripts100/p151.py | 26 ++------ pylib/iemweb/autoplot/scripts100/p153.py | 21 +------ pylib/iemweb/autoplot/scripts100/p154.py | 20 +----- pylib/iemweb/autoplot/scripts100/p155.py | 24 ++------ pylib/iemweb/autoplot/scripts100/p161.py | 21 ++----- pylib/iemweb/autoplot/scripts100/p169.py | 21 ++----- pylib/iemweb/autoplot/scripts100/p198.py | 22 +------ pylib/iemweb/autoplot/scripts200/p200.py | 18 +----- pylib/iemweb/autoplot/scripts200/p214.py | 18 +----- pylib/iemweb/autoplot/scripts200/p215.py | 23 +++---- pylib/iemweb/autoplot/scripts200/p230.py | 22 +------ pylib/iemweb/autoplot/scripts200/p243.py | 22 +------ pylib/iemweb/autoplot/scripts200/p244.py | 30 +++------ pylib/iemweb/util.py | 37 +++++++++++ tests/iemweb/autoplot/urllist.txt | 5 ++ 30 files changed, 182 insertions(+), 501 deletions(-) create mode 100644 pylib/iemweb/util.py diff --git a/pylib/iemweb/autoplot/scripts/p15.py b/pylib/iemweb/autoplot/scripts/p15.py index 737d6986d7..466c645d37 100644 --- a/pylib/iemweb/autoplot/scripts/p15.py +++ b/pylib/iemweb/autoplot/scripts/p15.py @@ -4,7 +4,6 @@ """ import calendar -import datetime import matplotlib.patheffects as PathEffects import numpy as np @@ -12,7 +11,8 @@ from pyiem.database import get_sqlalchemy_conn from pyiem.exceptions import NoDataFound from pyiem.plot import figure_axes -from pyiem.util import get_autoplot_context +from pyiem.util import get_autoplot_context, utc +from sqlalchemy import text from iemweb.autoplot import ARG_STATION @@ -34,7 +34,7 @@ def get_description(): dict( type="year", name="year", - default=datetime.date.today().year, + default=utc().year, label="Year to Highlight", min=1893, ), @@ -51,11 +51,11 @@ def plotter(fdict): with get_sqlalchemy_conn("coop") as conn: df = pd.read_sql( - """ + text(""" with obs as (select month, year, high, lag(high) OVER (ORDER by day ASC) as lhigh, low, lag(low) OVER (ORDER by day ASC) as llow - from alldata where station = %s) + from alldata where station = :station) SELECT year, month, sum(case when high > lhigh then 1 else 0 end)::numeric as high_greater, @@ -65,9 +65,9 @@ def plotter(fdict): sum(case when low = llow then 1 else 0 end)::numeric as low_unch, sum(case when low < llow then 1 else 0 end)::numeric as low_lower from obs GROUP by year, month ORDER by year, month - """, + """), conn, - params=(station,), + params={"station": station}, index_col=None, ) gdf = df.groupby("month").sum() diff --git a/pylib/iemweb/autoplot/scripts/p16.py b/pylib/iemweb/autoplot/scripts/p16.py index f27d311a9f..f7a788e5ac 100644 --- a/pylib/iemweb/autoplot/scripts/p16.py +++ b/pylib/iemweb/autoplot/scripts/p16.py @@ -4,8 +4,6 @@ wind speed and direction. """ -import datetime - import numpy as np import pandas as pd from metpy.units import units @@ -15,6 +13,8 @@ from pyiem.util import drct2text, get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + PDICT = { "ts": "Thunderstorm (TS) Reported", "tmpf_above": "Temperature At or Above Threshold (F)", @@ -215,23 +215,7 @@ def get_highcharts(ctx: dict) -> str: def add_ctx(ctx): """Do the agnostic stuff""" ctx["station"] = ctx["zstation"] - - if ctx["month"] == "all": - months = list(range(1, 13)) - elif ctx["month"] == "fall": - months = [9, 10, 11] - elif ctx["month"] == "winter": - months = [12, 1, 2] - elif ctx["month"] == "spring": - months = [3, 4, 5] - elif ctx["month"] == "summer": - months = [6, 7, 8] - else: - ts = datetime.datetime.strptime( - "2000-" + ctx["month"] + "-01", "%Y-%b-%d" - ) - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + months = month2months(ctx["month"]) limiter = "array_to_string(wxcodes, '') ~* 'TS'" title = "Thunderstorm (TS) contained in METAR" diff --git a/pylib/iemweb/autoplot/scripts/p19.py b/pylib/iemweb/autoplot/scripts/p19.py index 8a4229ec5a..185d146304 100644 --- a/pylib/iemweb/autoplot/scripts/p19.py +++ b/pylib/iemweb/autoplot/scripts/p19.py @@ -18,6 +18,7 @@ from sqlalchemy import text from iemweb.autoplot import ARG_STATION, get_monofont +from iemweb.util import month2months MDICT = { "all": "No Month/Time Limit", @@ -91,20 +92,6 @@ def plotter(fdict): binsize = ctx["binsize"] month = ctx["month"] year = ctx.get("year") - if month == "all": - months = list(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(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] with get_sqlalchemy_conn("coop") as conn: ddf = pd.read_sql( text( @@ -113,7 +100,7 @@ def plotter(fdict): "and high >= low and month = ANY(:months) " ), conn, - params={"station": station, "months": months}, + params={"station": station, "months": month2months(month)}, index_col=None, ) if ddf.empty: @@ -146,7 +133,7 @@ def plotter(fdict): f"{ctx['_sname']} ({ddf['year'].min():.0f}-{ddf['year'].max():.0f})" ) fig = figure(title=title, subtitle=subtitle, apctx=ctx) - kax = fig.add_axes([0.65, 0.5, 0.3, 0.36]) + kax = fig.add_axes((0.65, 0.5, 0.3, 0.36)) kax.grid(True) kax.text( 0.02, @@ -194,9 +181,9 @@ def plotter(fdict): label = f"{q * 100:-6g} {val:-6.0f}" fig.text(xpos, ypos, label, fontproperties=monofont) - ax = fig.add_axes([0.07, 0.17, 0.5, 0.73]) + ax = fig.add_axes((0.07, 0.17, 0.5, 0.73)) res = ax.pcolormesh(xedges, yedges, hist.T, cmap=get_cmap(ctx["cmap"])) - cax = fig.add_axes([0.07, 0.08, 0.5, 0.01]) + cax = fig.add_axes((0.07, 0.08, 0.5, 0.01)) fig.colorbar(res, label="Days per Year", orientation="horizontal", cax=cax) ax.grid(True) ax.set_ylabel(r"High Temperature $^{\circ}\mathrm{F}$") diff --git a/pylib/iemweb/autoplot/scripts/p41.py b/pylib/iemweb/autoplot/scripts/p41.py index 903f138150..33d286e404 100644 --- a/pylib/iemweb/autoplot/scripts/p41.py +++ b/pylib/iemweb/autoplot/scripts/p41.py @@ -22,6 +22,8 @@ and duration of stretches of hot or cold weather. """ +from datetime import timedelta + import numpy as np import pandas as pd from pyiem.database import get_sqlalchemy_conn @@ -30,8 +32,10 @@ from pyiem.plot.use_agg import plt from pyiem.util import get_autoplot_context from scipy import stats +from sqlalchemy import text from iemweb.autoplot import ARG_STATION, get_monofont +from iemweb.util import month2months ODICT = {"max": "Maximum", "min": "Minimum", "avg": "Average"} PDICT = { @@ -125,40 +129,35 @@ def get_description(): def get_data(station, month, period, varname, days, opt): """Get Data please""" - doffset = "0 days" - if len(month) < 3: - mlimiter = f" and month = {int(month)} " - elif month == "all": - mlimiter = "" - elif month == "fall": - mlimiter = " and month in (9, 10, 11) " - elif month == "winter": - mlimiter = " and month in (12, 1, 2) " - doffset = "31 days" - elif month == "spring": - mlimiter = " and month in (3, 4, 5) " - else: # summer - mlimiter = " and month in (6, 7, 8) " - + params = { + "station": station, + "months": month2months(month), + "doffset": timedelta(days=0), + } + mlimiter = "and month = ANY(:months)" + if month == "winter": + params["doffset"] = timedelta(days=31) ylimiter = "" if period is not None: (y1, y2) = [int(x) for x in period.split("-")] - ylimiter = f"WHERE myyear >= {y1} and myyear <= {y2}" + params["y1"] = y1 + params["y2"] = y2 + ylimiter = "WHERE myyear >= :y1 and myyear <= :y2" if days == 1: with get_sqlalchemy_conn("coop") as conn: df = pd.read_sql( - f""" + text(f""" WITH data as ( SELECT - extract(year from day + '{doffset}'::interval)::int + extract(year from day + :doffset)::int as myyear, high, low, (high+low)/2. as avg from alldata - WHERE station = %s and high is not null + WHERE station = :station and high is not null and low is not null {mlimiter}) SELECT * from data {ylimiter} - """, + """), conn, - params=(station,), + params=params, index_col=None, ) else: @@ -168,20 +167,21 @@ def get_data(station, month, period, varname, days, opt): ) with get_sqlalchemy_conn("coop") as conn: df = pd.read_sql( - f""" + text(f""" WITH data as ( SELECT - extract(year from day + '{doffset}'::interval)::int + extract(year from day + :doffset)::int as myyear, high, low, (high+low)/2. as avg, day, month from alldata - WHERE station = %s and high is not null and low is not null), + WHERE station = :station + and high is not null and low is not null), agg1 as ( SELECT myyear, month, {res} as {varname} from data WHERE 1 = 1 {mlimiter}) SELECT * from agg1 {ylimiter} - """, + """), conn, - params=(station,), + params=params, index_col=None, ) if df.empty: @@ -221,7 +221,7 @@ def plotter(fdict): s_slp, s_int, s_r, _, _ = stats.linregress(pc1, pc2) fig = figure(apctx=ctx) - ax = fig.add_axes([0.1, 0.11, 0.4, 0.76]) + ax = fig.add_axes((0.1, 0.11, 0.4, 0.76)) ax.scatter(pc1[::5], pc2[::5], s=40, marker="s", color="b", zorder=3) ax.plot( pc1, @@ -273,7 +273,7 @@ def plotter(fdict): ax.legend(loc=2) # Second - ax = fig.add_axes([0.56, 0.18, 0.26, 0.68]) + ax = fig.add_axes((0.56, 0.18, 0.26, 0.68)) ax.set_title("Distribution") v1 = ax.violinplot(m1data, positions=[0], showextrema=True, showmeans=True) b = v1["bodies"][0] @@ -320,26 +320,8 @@ def plotter(fdict): col1 = f"{MDICT[month1]}_{varname}_{y1}_{y2}" col2 = f"{MDICT[month2]}_{varname}_{y3}_{y4}" fig.text(x, y + 0.04, "Percentile Data Diff") - for percentile in [ - 100, - 99, - 98, - 97, - 96, - 95, - 92, - 90, - 75, - 50, - 25, - 10, - 8, - 5, - 4, - 3, - 2, - 1, - ]: + pt = [100, 99, 98, 97, 96, 95, 92, 90, 75, 50, 25, 10, 8, 5, 4, 3, 2, 1] + for percentile in pt: row = df.loc[percentile] fig.text(x, y, f"{percentile:3.0f}", fontproperties=monofont) fig.text( diff --git a/pylib/iemweb/autoplot/scripts/p42.py b/pylib/iemweb/autoplot/scripts/p42.py index 946d9e0092..2810f8815a 100644 --- a/pylib/iemweb/autoplot/scripts/p42.py +++ b/pylib/iemweb/autoplot/scripts/p42.py @@ -25,6 +25,8 @@ from pyiem.plot import figure from pyiem.util import get_autoplot_context +from iemweb.util import month2months + PDICT = { "above": "At or Above Threshold...", "below": "Below Threshold...", @@ -221,21 +223,7 @@ def plotter(fdict): f" and valid >= '{int(y1)}-01-01' and " f"valid < '{int(y2) + 1}-01-01' " ) - if month == "all": - months = list(range(1, 13)) - elif month == "fall": - months = [9, 10, 11] - elif month == "winter": - months = [12, 1, 2] - elif month == "octmar": - months = [10, 11, 12, 1, 2, 3] - elif month == "spring": - months = [3, 4, 5] - elif month == "summer": - months = [6, 7, 8] - else: - ts = datetime.datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - months = [ts.month] + months = month2months(month) ab = ctx["_nt"].sts[station]["archive_begin"] if ab is None: @@ -288,7 +276,7 @@ def plotter(fdict): f"{MDICT.get(month)} :: Streaks {PDICT2[varname]} {label} {units}" ) fig = figure(title=title, subtitle=subtitle, apctx=ctx) - ax = fig.add_axes([0.07, 0.25, 0.6, 0.65]) + ax = fig.add_axes((0.07, 0.25, 0.6, 0.65)) threshold = datetime.timedelta(hours=3) reset_valid = datetime.datetime(1910, 1, 1, tzinfo=tzinfo) diff --git a/pylib/iemweb/autoplot/scripts/p46.py b/pylib/iemweb/autoplot/scripts/p46.py index cf032a5fa7..4f53148d47 100644 --- a/pylib/iemweb/autoplot/scripts/p46.py +++ b/pylib/iemweb/autoplot/scripts/p46.py @@ -6,8 +6,6 @@ greater than air temperature and wind chill less than air temperature. """ -from datetime import datetime - import numpy as np import pandas as pd from pyiem.database import get_sqlalchemy_conn @@ -16,6 +14,8 @@ from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + PDICT = { "wcht": "Minimum Wind Chill", "heat": "Maximum Heat Index", @@ -74,23 +74,8 @@ def plotter(fdict): """Go""" ctx = get_autoplot_context(fdict, get_description()) station = ctx["zstation"] - offset = 0 - if ctx["month"] == "all": - months = list(range(1, 13)) - offset = 3 - elif ctx["month"] == "fall": - months = [9, 10, 11] - elif ctx["month"] == "winter": - months = [12, 1, 2] - offset = 3 - elif ctx["month"] == "spring": - months = [3, 4, 5] - elif ctx["month"] == "summer": - months = [6, 7, 8] - else: - ts = datetime.strptime(f"2000-{ctx['month']}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + offset = 3 if ctx["month"] in ["all", "winter"] else 0 + months = month2months(ctx["month"]) additive = "feel < tmpf" if ctx["var"] == "wcht" else "feel > tmpf" with get_sqlalchemy_conn("asos") as conn: diff --git a/pylib/iemweb/autoplot/scripts/p69.py b/pylib/iemweb/autoplot/scripts/p69.py index 633851b371..034bec901c 100644 --- a/pylib/iemweb/autoplot/scripts/p69.py +++ b/pylib/iemweb/autoplot/scripts/p69.py @@ -5,8 +5,6 @@ other years with a full year's worth of data. """ -import datetime - import matplotlib.patheffects as PathEffects import pandas as pd from pyiem.database import get_sqlalchemy_conn @@ -15,6 +13,8 @@ from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + PDICT = { "high": "High Temperature", "low": "Low Temperature", @@ -112,21 +112,9 @@ def plotter(fdict): ctx["mag"] = abs(ctx["mag"]) yr = "year as yr" - if month == "all": - months = list(range(1, 13)) - elif month == "fall": - months = [9, 10, 11] - elif month == "winter": - months = [12, 1, 2] + months = month2months(month) + if month == "winter": yr = "extract(year from o.day - '60 days'::interval) as yr" - elif month == "spring": - months = [3, 4, 5] - elif month == "summer": - months = [6, 7, 8] - else: - ts = datetime.datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] metric = "" smul = 0 diff --git a/pylib/iemweb/autoplot/scripts/p76.py b/pylib/iemweb/autoplot/scripts/p76.py index f08e9de103..7062dcb622 100644 --- a/pylib/iemweb/autoplot/scripts/p76.py +++ b/pylib/iemweb/autoplot/scripts/p76.py @@ -29,6 +29,8 @@ from scipy import stats from sqlalchemy import text +from iemweb.util import month2months + MDICT = { "all": "No Month/Time Limit", "water_year": "Water Year", @@ -180,37 +182,27 @@ def get_data(ctx, startyear): today = datetime.datetime.now() lastyear = today.year deltadays = 0 - if ctx["season"] == "all": - months = list(range(1, 13)) - elif ctx["season"] == "water_year": + months = month2months(ctx["season"]) + if ctx["season"] == "water_year": deltadays = 92 - months = list(range(1, 13)) lastyear += 1 elif ctx["season"] == "spring": - months = [3, 4, 5] if today.month > 5: lastyear += 1 elif ctx["season"] == "spring2": - months = [4, 5, 6] if today.month > 6: lastyear += 1 elif ctx["season"] == "fall": - months = [9, 10, 11] if today.month > 11: lastyear += 1 elif ctx["season"] == "summer": - months = [6, 7, 8] if today.month > 8: lastyear += 1 elif ctx["season"] == "winter": deltadays = 33 - months = [12, 1, 2] if today.month > 2: lastyear += 1 else: - ts = datetime.datetime.strptime(f"2000-{ctx['season']}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] lastyear += 1 if startyear >= lastyear: raise NoDataFound("Start year should be less than end year.") diff --git a/pylib/iemweb/autoplot/scripts/p78.py b/pylib/iemweb/autoplot/scripts/p78.py index d6b7cceba6..4ffb3c8f39 100644 --- a/pylib/iemweb/autoplot/scripts/p78.py +++ b/pylib/iemweb/autoplot/scripts/p78.py @@ -18,6 +18,8 @@ from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + MDICT = { "all": "No Month/Time Limit", "spring": "Spring (MAM)", @@ -74,20 +76,7 @@ def plotter(fdict): station = ctx["zstation"] month = ctx["month"] - if month == "all": - months = list(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(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + months = month2months(month) with get_sqlalchemy_conn("asos") as conn: df = pd.read_sql( text( diff --git a/pylib/iemweb/autoplot/scripts/p79.py b/pylib/iemweb/autoplot/scripts/p79.py index 1968a45bde..f2a5e4b623 100644 --- a/pylib/iemweb/autoplot/scripts/p79.py +++ b/pylib/iemweb/autoplot/scripts/p79.py @@ -12,11 +12,14 @@ import metpy.calc as mcalc import pandas as pd from metpy.units import units +from pyiem.database import get_sqlalchemy_conn from pyiem.exceptions import NoDataFound from pyiem.plot import figure_axes -from pyiem.util import get_autoplot_context, get_sqlalchemy_conn +from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + MDICT = { "all": "No Month/Time Limit", "spring": "Spring (MAM)", @@ -66,21 +69,7 @@ def plotter(fdict): station = ctx["zstation"] month = ctx["month"] - - if month == "all": - months = list(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(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + months = month2months(month) with get_sqlalchemy_conn("asos") as conn: df = pd.read_sql( text( diff --git a/pylib/iemweb/autoplot/scripts100/p106.py b/pylib/iemweb/autoplot/scripts100/p106.py index 48fb0cada1..f181d8d38b 100644 --- a/pylib/iemweb/autoplot/scripts100/p106.py +++ b/pylib/iemweb/autoplot/scripts100/p106.py @@ -6,13 +6,13 @@ temperature. """ -import datetime - from pyiem.database import get_dbconn from pyiem.exceptions import NoDataFound from pyiem.plot import figure_axes from pyiem.util import get_autoplot_context +from iemweb.util import month2months + PDICT = { "tmpf_above": "Temperature At or Above Threshold (F)", "tmpf_below": "Temperature Below Threshold (F)", @@ -84,20 +84,7 @@ def plotter(fdict): opt = ctx["opt"] month = ctx["month"] - if month == "all": - months = list(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(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + months = month2months(month) if opt == "tmpf_above": limiter = f"round(tmpf::numeric,0) >= {threshold}" diff --git a/pylib/iemweb/autoplot/scripts100/p125.py b/pylib/iemweb/autoplot/scripts100/p125.py index a55dd58855..b1d0cc222c 100644 --- a/pylib/iemweb/autoplot/scripts100/p125.py +++ b/pylib/iemweb/autoplot/scripts100/p125.py @@ -11,7 +11,6 @@ """ import calendar -from datetime import datetime import pandas as pd from pyiem.database import get_sqlalchemy_conn @@ -21,6 +20,8 @@ from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + PDICT = { "state": "State Level Maps (select state)", } @@ -175,24 +176,7 @@ def plotter(fdict): sector = ctx["sector"] opt = ctx["opt"] month = ctx["month"] - if month == "all": - months = list(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 == "mjj": - months = [5, 6, 7] - elif month == "gs": - months = [5, 6, 7, 8, 9] - elif month == "summer": - months = [6, 7, 8] - else: - ts = datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month] + months = month2months(month) if len(months) == 1: title = calendar.month_name[months[0]] diff --git a/pylib/iemweb/autoplot/scripts100/p131.py b/pylib/iemweb/autoplot/scripts100/p131.py index c8fc1bf880..0f29fda197 100644 --- a/pylib/iemweb/autoplot/scripts100/p131.py +++ b/pylib/iemweb/autoplot/scripts100/p131.py @@ -8,11 +8,14 @@ import datetime import pandas as pd +from pyiem.database import get_sqlalchemy_conn from pyiem.exceptions import NoDataFound from pyiem.plot import figure_axes -from pyiem.util import get_autoplot_context, get_sqlalchemy_conn +from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + PDICT = {"CLR": "Clear (CLR)", "OVC": "Overcast (OVC)"} MDICT = { "all": "No Month/Time Limit", @@ -78,21 +81,7 @@ def plotter(fdict): month = ctx["month"] varname = ctx["var"] hour = ctx.get("hour") - - if month == "all": - months = list(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(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + months = month2months(month) if hour is None: with get_sqlalchemy_conn("asos") as conn: diff --git a/pylib/iemweb/autoplot/scripts100/p132.py b/pylib/iemweb/autoplot/scripts100/p132.py index 551603d056..841aea18ac 100644 --- a/pylib/iemweb/autoplot/scripts100/p132.py +++ b/pylib/iemweb/autoplot/scripts100/p132.py @@ -24,6 +24,7 @@ from sqlalchemy import text from iemweb.autoplot import ARG_STATION +from iemweb.util import month2months MDICT = { "all": "Entire Year", @@ -95,22 +96,7 @@ def plotter(fdict): varname = ctx["var"] days = ctx["days"] - if month == "all": - months = list(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] - elif month == "octmar": - months = [10, 11, 12, 1, 2, 3] - else: - ts = datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + months = month2months(month) sorder = "ASC" if varname in ["min_greatest_low"] else "DESC" with get_sqlalchemy_conn("coop") as conn: @@ -188,7 +174,7 @@ def plotter(fdict): ) fig = figure(apctx=ctx, title=title) - ax = fig.add_axes([0.1, 0.1, 0.5, 0.8]) + ax = fig.add_axes((0.1, 0.1, 0.5, 0.8)) ax.barh( range(10, 0, -1), df[varname], diff --git a/pylib/iemweb/autoplot/scripts100/p139.py b/pylib/iemweb/autoplot/scripts100/p139.py index da42c583af..a70954c05e 100644 --- a/pylib/iemweb/autoplot/scripts100/p139.py +++ b/pylib/iemweb/autoplot/scripts100/p139.py @@ -23,6 +23,7 @@ from sqlalchemy import text from iemweb.autoplot import get_monofont +from iemweb.util import month2months MDICT = { "all": "No Month/Time Limit", @@ -127,21 +128,7 @@ def plotter(fdict): ctx = get_autoplot_context(fdict, get_description()) station = ctx["zstation"] month = ctx["month"] - - if month == "all": - months = list(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.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + months = month2months(month) order = "DESC" if ctx["v"] == "largest" else "ASC" with get_sqlalchemy_conn("iem") as conn: diff --git a/pylib/iemweb/autoplot/scripts100/p151.py b/pylib/iemweb/autoplot/scripts100/p151.py index 54b956fe67..a9852bdb17 100644 --- a/pylib/iemweb/autoplot/scripts100/p151.py +++ b/pylib/iemweb/autoplot/scripts100/p151.py @@ -6,8 +6,6 @@ averages over some period of years. """ -import datetime - import numpy as np import pandas as pd from pyiem.database import get_sqlalchemy_conn @@ -17,6 +15,8 @@ from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + PDICT = { "state": "State Level Maps (select state)", } @@ -193,24 +193,8 @@ def get_data(ctx): p2eyear = ctx["p2eyear"] p2years = p2eyear - p2syear + 1 - mlimiter = "and month = ANY(:months)" - if month == "all": - mlimiter = "" - months = list(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] - elif month == "gs": - months = [5, 6, 7, 8, 9] - else: - ts = datetime.datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month] + mlimiter = "and month = ANY(:months)" if month != "all" else "" + months = month2months(month) table = "alldata" if sector == "state": # optimization @@ -356,7 +340,7 @@ def plotter(fdict): else: levels = [ round(v, PRECISION.get(varname, 1)) - for v in np.percentile(df2[column].values, range(0, 101, 10)) + for v in np.percentile(df2[column].to_numpy(), range(0, 101, 10)) ] if opt in ["both", "contour"]: mp.contourf( diff --git a/pylib/iemweb/autoplot/scripts100/p153.py b/pylib/iemweb/autoplot/scripts100/p153.py index aae38e2f99..1af73fe681 100644 --- a/pylib/iemweb/autoplot/scripts100/p153.py +++ b/pylib/iemweb/autoplot/scripts100/p153.py @@ -11,7 +11,7 @@ that hour. For example, a 9:53 AM observation becomes the ob for 10 AM. """ -from datetime import date, datetime +from datetime import date import pandas as pd from matplotlib.font_manager import FontProperties @@ -22,6 +22,7 @@ from sqlalchemy import text from iemweb.autoplot import get_monofont +from iemweb.util import month2months PDICT = { "max_dwpf": "Highest Dew Point Temperature", @@ -139,23 +140,7 @@ def plotter(fdict): varname2 = "i" + varname2 month = ctx["month"] station = ctx["zstation"] - - if month == "all": - months = list(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] - elif month == "gs": - months = [5, 6, 7, 8, 9] - else: - ts = datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month] + months = month2months(month) params = { "tzname": ctx["_nt"].sts[station]["tzname"], "station": station, diff --git a/pylib/iemweb/autoplot/scripts100/p154.py b/pylib/iemweb/autoplot/scripts100/p154.py index 3972e208e9..e52d7d3f86 100644 --- a/pylib/iemweb/autoplot/scripts100/p154.py +++ b/pylib/iemweb/autoplot/scripts100/p154.py @@ -16,6 +16,8 @@ from scipy import stats from sqlalchemy import text +from iemweb.util import month2months + PDICT = {"avg_tmpf": "Average Temperature"} UNITS = {"avg_tmpf": "F"} MDICT = { @@ -86,23 +88,7 @@ def plotter(fdict): month = ctx["month"] station = ctx["zstation"] hour = ctx["hour"] - - if month == "all": - months = list(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] - elif month == "gs": - months = [5, 6, 7, 8, 9] - else: - ts = datetime.datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month] + months = month2months(month) with get_sqlalchemy_conn("asos") as conn: df = pd.read_sql( diff --git a/pylib/iemweb/autoplot/scripts100/p155.py b/pylib/iemweb/autoplot/scripts100/p155.py index 981e1b001d..6f1ebb53a9 100644 --- a/pylib/iemweb/autoplot/scripts100/p155.py +++ b/pylib/iemweb/autoplot/scripts100/p155.py @@ -20,11 +20,14 @@ import datetime import pandas as pd +from pyiem.database import get_sqlalchemy_conn from pyiem.exceptions import NoDataFound from pyiem.plot import figure -from pyiem.util import get_autoplot_context, get_sqlalchemy_conn +from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + MDICT = { "all": "Entire Year", "spring": "Spring (MAM)", @@ -178,22 +181,7 @@ def plotter(fdict): ) title2 = f"on {ctx['sdate']:%-d %b}" else: - if month == "all": - months = list(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] - elif month == "octmar": - months = [10, 11, 12, 1, 2, 3] - else: - ts = datetime.datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + months = month2months(month) date_limiter = ( " and extract(month from valid at time zone :tzname)" " = ANY(:months) " @@ -313,7 +301,7 @@ def plotter(fdict): f"({ab.year}-{datetime.datetime.now().year})" ) fig = figure(title=title, subtitle=subtitle, apctx=ctx) - ax = fig.add_axes([0.1, 0.1, 0.65, 0.8]) + ax = fig.add_axes((0.1, 0.1, 0.65, 0.8)) ax.barh( range(len(y), 0, -1), y, diff --git a/pylib/iemweb/autoplot/scripts100/p161.py b/pylib/iemweb/autoplot/scripts100/p161.py index cabb9d49d6..493dfa76b8 100644 --- a/pylib/iemweb/autoplot/scripts100/p161.py +++ b/pylib/iemweb/autoplot/scripts100/p161.py @@ -7,11 +7,14 @@ import datetime import pandas as pd +from pyiem.database import get_sqlalchemy_conn from pyiem.exceptions import NoDataFound from pyiem.plot import figure_axes -from pyiem.util import get_autoplot_context, get_sqlalchemy_conn +from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + MDICT = { "all": "No Month/Time Limit", "spring": "Spring (MAM)", @@ -106,21 +109,7 @@ def add_context(ctx): threshold = ctx["thres"] offset = "day" - if month == "all": - months = list(range(1, 13)) - elif month == "fall": - months = [9, 10, 11] - elif month == "winter": - months = [12, 1, 2] - offset = "day + '1 month'::interval" - 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] + months = month2months(month) opp = ">=" if mydir == "aoa" else "<" with get_sqlalchemy_conn("iem") as conn: diff --git a/pylib/iemweb/autoplot/scripts100/p169.py b/pylib/iemweb/autoplot/scripts100/p169.py index 476c63fab6..2dbaa8b2e4 100644 --- a/pylib/iemweb/autoplot/scripts100/p169.py +++ b/pylib/iemweb/autoplot/scripts100/p169.py @@ -26,7 +26,7 @@ plot, but only considers a calendar day.

""" -from datetime import date, datetime, timedelta +from datetime import date, timedelta from zoneinfo import ZoneInfo import pandas as pd @@ -36,6 +36,8 @@ from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + MDICT = {"warm": "Rise", "cool": "Drop"} MDICT2 = { "all": "No Month/Time Limit", @@ -142,22 +144,7 @@ def plotter(fdict): if varname not in PDICT2: raise NoDataFound("Invalid varname") - 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.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ - ts.month, - ] + months = month2months(month) tzname = ctx["_nt"].sts[station]["tzname"] ab = ctx["_nt"].sts[station]["archive_begin"] diff --git a/pylib/iemweb/autoplot/scripts100/p198.py b/pylib/iemweb/autoplot/scripts100/p198.py index 9d2d230493..8c0371e2d1 100644 --- a/pylib/iemweb/autoplot/scripts100/p198.py +++ b/pylib/iemweb/autoplot/scripts100/p198.py @@ -11,8 +11,6 @@ Some derived parameters are a work-in-progress. """ -from datetime import datetime - import pandas as pd from pyiem.database import get_sqlalchemy_conn from pyiem.exceptions import NoDataFound @@ -20,6 +18,8 @@ from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + PDICT = {"00": "00 UTC", "12": "12 UTC", "ALL": "Any Hour"} MDICT = { "all": "No Month/Time Limit", @@ -173,23 +173,7 @@ def plotter(fdict): level = ctx["level"] agg = ctx["agg"] offset = 0 - if month == "all": - months = list(range(1, 13)) - elif month == "fall": - months = [9, 10, 11] - elif month == "winter": - months = [12, 1, 2] - offset = 32 - elif month == "spring": - months = [3, 4, 5] - elif month == "mjj": - months = [5, 6, 7] - elif month == "summer": - months = [6, 7, 8] - else: - ts = datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month] + months = month2months(month) name = ctx["_nt"].sts[station]["name"] stations = [station] diff --git a/pylib/iemweb/autoplot/scripts200/p200.py b/pylib/iemweb/autoplot/scripts200/p200.py index 3f87551d76..31b97dd3fc 100644 --- a/pylib/iemweb/autoplot/scripts200/p200.py +++ b/pylib/iemweb/autoplot/scripts200/p200.py @@ -20,7 +20,7 @@ chart of days per year by WFO, state.

""" -from datetime import datetime, timedelta +from datetime import timedelta import geopandas as gpd import numpy as np @@ -36,6 +36,7 @@ from sqlalchemy import text from iemweb.autoplot import ARG_FEMA +from iemweb.util import month2months PDICT5 = { "yes": "YES: Draw Counties/Parishes", @@ -257,20 +258,7 @@ def plotter(fdict): p = ctx["p"] month = ctx["month"] - if month == "all": - months = list(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.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + months = month2months(month) griddelta = 0.05 YSZ = (GRIDNORTH - GRIDSOUTH) / griddelta diff --git a/pylib/iemweb/autoplot/scripts200/p214.py b/pylib/iemweb/autoplot/scripts200/p214.py index 4930aeb87b..ba21d536d3 100644 --- a/pylib/iemweb/autoplot/scripts200/p214.py +++ b/pylib/iemweb/autoplot/scripts200/p214.py @@ -17,6 +17,8 @@ from pyiem.util import get_autoplot_context from sqlalchemy import text +from iemweb.util import month2months + VDICT = { "dwpf": "Air Dew Point Temp [F]", "tmpf": "Air Temperature [F]", @@ -168,21 +170,7 @@ def add_data(ctx): assert x in VDICT assert y in VDICT assert agg in ADICT - - if month == "all": - months = list(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(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] + months = month2months(month) cast = "int" if x in ["tmpf", "dwpf", "feel"] else "real" basets = datetime.date(ctx["syear"], 1, 1) diff --git a/pylib/iemweb/autoplot/scripts200/p215.py b/pylib/iemweb/autoplot/scripts200/p215.py index 3d55b43cd4..dcae9052a9 100644 --- a/pylib/iemweb/autoplot/scripts200/p215.py +++ b/pylib/iemweb/autoplot/scripts200/p215.py @@ -5,7 +5,7 @@ """ import calendar -from datetime import date, datetime +from datetime import date import numpy as np import pandas as pd @@ -19,6 +19,7 @@ from sqlalchemy import text from iemweb.autoplot import ARG_STATION +from iemweb.util import month2months PDICT = { "high": "High Temperature [F]", @@ -101,21 +102,11 @@ def get_df(ctx, period): """Get our data.""" month = ctx["month"] ctx["mlabel"] = f"{month.capitalize()} Season" + months = month2months(month) if month == "all": - months = list(range(1, 13)) ctx["mlabel"] = "All Year" - 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.strptime(f"2000-{month}-01", "%Y-%b-%d") - months = [ts.month] - ctx["mlabel"] = calendar.month_name[ts.month] + elif len(months) == 1: + ctx["mlabel"] = calendar.month_name[months[0]] with get_sqlalchemy_conn("coop") as conn: df = pd.read_sql( text( @@ -171,7 +162,7 @@ def plotter(fdict): ) fitbox(fig, title, 0.12, 0.9, 0.91, 0.99) - ax = fig.add_axes([0.12, 0.38, 0.75, 0.52]) + ax = fig.add_axes((0.12, 0.38, 0.75, 0.52)) C1 = "blue" C2 = "red" alpha = 0.4 @@ -202,7 +193,7 @@ def plotter(fdict): ax.xaxis.set_major_locator(MaxNLocator(20)) # Sub ax - ax2 = fig.add_axes([0.12, 0.1, 0.75, 0.22]) + ax2 = fig.add_axes((0.12, 0.1, 0.75, 0.22)) delta = df[label2] - df[label1] ax2.plot(df.index.values, delta) dam = delta.abs().max() * 1.1 diff --git a/pylib/iemweb/autoplot/scripts200/p230.py b/pylib/iemweb/autoplot/scripts200/p230.py index 2b41c6e9a1..8a939cdbee 100644 --- a/pylib/iemweb/autoplot/scripts200/p230.py +++ b/pylib/iemweb/autoplot/scripts200/p230.py @@ -6,7 +6,7 @@ usage of levels with time. """ -from datetime import date, datetime +from datetime import date import pandas as pd from matplotlib.patches import Rectangle @@ -18,6 +18,7 @@ from sqlalchemy import text from iemweb.autoplot import ARG_FEMA +from iemweb.util import month2months MDICT = { "all": "Entire Year", @@ -160,24 +161,7 @@ def plotter(fdict): date_limiter = " and outlook_date < :date " params["date"] = ctx["date"] 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] - elif month == "octmar": - months = [10, 11, 12, 1, 2, 3] - else: - ts = datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ - ts.month, - ] + months = month2months(month) if month != "all": date_limiter = ( f" and extract(month from issue) = ANY(:months) {date_limiter}" diff --git a/pylib/iemweb/autoplot/scripts200/p243.py b/pylib/iemweb/autoplot/scripts200/p243.py index a3c383fced..d5506b1d4a 100644 --- a/pylib/iemweb/autoplot/scripts200/p243.py +++ b/pylib/iemweb/autoplot/scripts200/p243.py @@ -11,8 +11,6 @@ produces monthly heatmaps. """ -from datetime import datetime - import pandas as pd import pyiem.nws.vtec as vtec from pyiem import reference @@ -23,6 +21,7 @@ from sqlalchemy import text from iemweb.autoplot import ARG_FEMA, FEMA_REGIONS, fema_region2states +from iemweb.util import month2months MDICT = { "all": "Entire Year", @@ -137,22 +136,7 @@ def plotter(fdict): "tzname": "America/Chicago", } month = ctx["month"] - if month == "all": - months = list(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] - elif month == "octmar": - months = [10, 11, 12, 1, 2, 3] - else: - ts = datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month] + months = month2months(month) params = { "ph": [ phenomena, @@ -277,7 +261,7 @@ def plotter(fdict): ), apctx=ctx, ) - ax = fig.add_axes([0.3, 0.1, 0.5, 0.8]) + ax = fig.add_axes((0.3, 0.1, 0.5, 0.8)) ax.spines["top"].set_visible(False) ax.spines["right"].set_visible(False) ax.spines["left"].set_visible(False) diff --git a/pylib/iemweb/autoplot/scripts200/p244.py b/pylib/iemweb/autoplot/scripts200/p244.py index ae7db6affa..61fee16465 100644 --- a/pylib/iemweb/autoplot/scripts200/p244.py +++ b/pylib/iemweb/autoplot/scripts200/p244.py @@ -5,19 +5,15 @@

Variances shown are problems with IEM's database/processing, not NCEI! """ -import datetime - import pandas as pd +from pyiem.database import get_dbconn, get_sqlalchemy_conn from pyiem.exceptions import NoDataFound from pyiem.plot import figure -from pyiem.util import ( - get_autoplot_context, - get_dbconn, - get_properties, - get_sqlalchemy_conn, -) +from pyiem.util import get_autoplot_context, get_properties from sqlalchemy import text +from iemweb.util import month2months + PDICT = { "sum_precip": "Total Precipitation", "avg_high": "Average High Temperature", @@ -129,23 +125,11 @@ def plotter(fdict): raise NoDataFound("Sorry, no data found!") month = ctx["m"] - if month == "all": - months = range(1, 13) - elif month == "fall": - months = [9, 10, 11] - elif month == "spring": - months = [3, 4, 5] - elif month == "summer": - months = [6, 7, 8] - elif month == "winter": - months = [12, 1, 2] + months = month2months(month) + if month == "winter": df = df.reset_index() df["year"] = df.loc[df["month"].isin([1, 2]), "year"] - 1 df = df.set_index("year") - else: - ts = datetime.datetime.strptime(f"2000-{month}-01", "%Y-%b-%d") - # make sure it is length two for the trick below in SQL - months = [ts.month, 999] df = ( df.loc[df["month"].isin(months)] @@ -167,7 +151,7 @@ def plotter(fdict): subtitle=f"{PDICT[varname]}, NCEI processdate: {procdate}", apctx=ctx, ) - ax = fig.add_axes([0.1, 0.1, 0.6, 0.8]) + ax = fig.add_axes((0.1, 0.1, 0.6, 0.8)) df["iem_bias"] = df[f"iem_{varname}"] - df[f"ncei_{varname}"] bias = df["iem_bias"].mean() ax.bar( diff --git a/pylib/iemweb/util.py b/pylib/iemweb/util.py new file mode 100644 index 0000000000..9b2d177159 --- /dev/null +++ b/pylib/iemweb/util.py @@ -0,0 +1,37 @@ +"""iemweb utility functions.""" + +from datetime import datetime + + +def month2months(month: str) -> list[int]: + """ + Convert a month string to a list of months. + + Args: + month (str): A month string commonly used by IEM apps + + Returns: + list: A list of ints (months) + """ + if month in ["all", "water_year"]: + months = list(range(1, 13)) + elif month == "fall": + months = [9, 10, 11] + elif month == "winter": + months = [12, 1, 2] + elif month == "octmar": + months = [10, 11, 12, 1, 2, 3] + elif month == "spring": + months = [3, 4, 5] + elif month == "spring2": + months = [4, 5, 6] + elif month == "summer": + months = [6, 7, 8] + elif month == "gs": + months = [5, 6, 7, 8, 9] + elif month == "mjj": + months = [5, 6, 7] + else: + fmt = "%b" if len(month) == 3 else "%m" + months = [datetime.strptime(f"2000-{month}-01", f"%Y-{fmt}-%d").month] + return months diff --git a/tests/iemweb/autoplot/urllist.txt b/tests/iemweb/autoplot/urllist.txt index a12e6a48bd..d2c64f304a 100644 --- a/tests/iemweb/autoplot/urllist.txt +++ b/tests/iemweb/autoplot/urllist.txt @@ -32,6 +32,9 @@ /plotting/auto/plot/39/network:IACLIMATE::station:IATAME::compare:manual::year:2024::month:1::date:2024-01-03::_r:t::dpi:100.png /plotting/auto/plot/40/network:IA_ASOS::zstation:DSM::month:1::ptype:vsby::year:2020::_r:t::dpi:100.png /plotting/auto/plot/40/network:IA_ASOS::zstation:DSM::month:1::ptype:sky::year:2020::_r:t::dpi:100.png +/plotting/auto/plot/41/network:IACLIMATE::station:IATAME::month1:winter::month2:7::var:high::highlight:55::days:1::opt:max::_r:t::dpi:100.png +/plotting/auto/plot/41/network:IACLIMATE::station:IATAME::month1:winter::p1:1893-1950::month2:7::p2:1950-2017::var:high::highlight:55::days:7::opt:avg::_r:43::dpi:100.png +/plotting/auto/plot/42/network:IA_ASOS::zstation:DSM::m:octmar::yrange:1928-2024::dir:below::var:mslp::threshold:1003::t2:1000::_r:43::dpi:100.png /plotting/auto/plot/43/network:IA_ASOS::station:AMW::sdate:2020-07-01::p:default::_r:88::dpi:100.png /plotting/auto/plot/43/network:IA_ASOS::station:AMW::sdate:2020-07-01::p:two::_r:88::dpi:100.png /plotting/auto/plot/44/plot:bar::opt:fema::network:WFO::station:DMX::state:IA::fema:7::limit:yes::c:single::phenomena:TO::significance:W::syear:1986::eyear:2024::s:jan1::_r:t::dpi:100.png @@ -49,6 +52,7 @@ /plotting/auto/plot/59/network:IA_ASOS::station:CSQ::units:mph::_r:t::dpi:100.png /plotting/auto/plot/60/network:IA_ASOS::zstation:DSM::var:tmpf::w:freq::threshold:120::direction:above::cmap:jet::_r:t::dpi:100.png /plotting/auto/plot/61/var:high::sdate:2024-08-01::sector:conus::network:WFO::wfo:STO::state:IA::_r:t::dpi:100.png +/plotting/auto/plot/69/network:IACLIMATE::station:IA0000::var:high::which:above::unit:degrees::mag:0::month:winter::opt:percent::_r:t::dpi:100.png /plotting/auto/plot/70/opt:wfo::network:WFO::station:DMX::state:IA::phenomena:TO::significance:W::split:jan1::f:daily::cmap:jet::_r:t::dpi:100.png /plotting/auto/plot/70/opt:state::network:WFO::station:DMX::state:IA::phenomena:TO::significance:W::split:jul1::f:none::cmap:jet::_r:t::dpi:100.png /plotting/auto/plot/70/opt:state::network:WFO::station:DMX::state:IA::phenomena:TO::significance:W::split:jan1::f:accum::cmap:jet::_r:t::dpi:100.png @@ -62,6 +66,7 @@ /plotting/auto/plot/73/opt:wfo::network:WFO::station:TSA::state:IA::ugc:IAC169::limit:udf::sday:0104::eday:0104::phenomena:SV::significance:W::_r:t::dpi:100.png /plotting/auto/plot/76/network:IA_ASOS::station:DSM::season:winter::varname:dwpf::agg:mean::year:1893::w:bar::_r:t::dpi:100.png /plotting/auto/plot/76/network:IA_ASOS::station:DSM::season:water_year::varname:vpd::agg:mean::year:1893::w:bar::_r:t::dpi:100.png +/plotting/auto/plot/78/network:IA_ASOS::zstation:DSM::month:winter::date:2024-08-01::_r:t::dpi:100.png /plotting/auto/plot/80/which:wfo::network:WFO::wfo:DMX::ugc:IAC153::phenomena:TO::significance:W::_r:t::dpi:100.png /plotting/auto/plot/80/which:ugc::network:WFO::wfo:DMX::ugc:IAC153::phenomena:TO::significance:W::_r:t::dpi:100.png /plotting/auto/plot/82/network:IA_ASOS::station:AMW::var:pday::sdate:2024-05-16::edate:2024-08-14::_r:t::dpi:100.png From 356f41a517ee4dac714bfccf77ea537b4abd4683 Mon Sep 17 00:00:00 2001 From: akrherz Date: Thu, 5 Dec 2024 20:28:32 -0600 Subject: [PATCH 3/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Address=20coverage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/iemweb/autoplot/urllist.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/iemweb/autoplot/urllist.txt b/tests/iemweb/autoplot/urllist.txt index d2c64f304a..3e4a63444d 100644 --- a/tests/iemweb/autoplot/urllist.txt +++ b/tests/iemweb/autoplot/urllist.txt @@ -22,6 +22,8 @@ /plotting/auto/plot/24/which:st::csector:midwest::var:aridity::w:dep::p:day::year:2024::month:1::sdate:2022-12-15::edate:2023-01-15::cmap:BrBG_r::_r:43::dpi:100.png /plotting/auto/plot/27/network:IACLIMATE::station:IATAME::t1:-55::t2:-60::_r:43::dpi:100.png /plotting/auto/plot/28/network:IACLIMATE::station:IATAME::opt:rank::date:2024-07-26::_r:t::dpi:100::_cb:1.png +/plotting/auto/plot/31/network:IACLIMATE::station:IATAME::syear:1893::eyear:2024::month:gs::how:three::var:low::days:4::stat:avg::thres:70::mdays:2::mstat:avg::fdays:4::fstat:avg::agg:month::_r:43::dpi:100.png +/plotting/auto/plot/31/network:IACLIMATE::station:IATAME::syear:1893::eyear:2024::month:fall::how:two::var:high::days:1::stat:max::mdays:4::mstat:max::fdays:4::fstat:max::agg:year::_r:43::dpi:100.png /plotting/auto/plot/32/network:IACLIMATE::station:IATAME::year:2024::var:era5land_srad::gddbase:50::gddceil:86::how:sigma::cmap:jet::_r:t::dpi:100.png /plotting/auto/plot/32/network:IACLIMATE::station:IATAME::year:2024::var:era5land_srad::gddbase:50::gddceil:86::how:valrange::cmap:jet::_r:t::dpi:100.png /plotting/auto/plot/32/network:IACLIMATE::station:IATAME::year:2024::var:era5land_srad::gddbase:50::gddceil:86::how:ptile::cmap:jet::_r:t::dpi:100.png @@ -60,6 +62,7 @@ /plotting/auto/plot/70/opt:fema::network:WFO::station:DMX::state:IA::fema:7::phenomena:SV::significance:W::split:jan1::f:daily::cmap:jet::_r:t::dpi:100::_cb:1.png /plotting/auto/plot/72/network:WFO::station:DMX::phenomena:TO::significance:W::season:jul.png /plotting/auto/plot/72/network:WFO::station:DMX::phenomena:TO::significance:W::season:all.png +/plotting/auto/plot/72/network:WFO::station:OAX::phenomena:TO::significance:W::season:spring2::_r:43::dpi:100.png /plotting/auto/plot/73/opt:fema::network:WFO::station:DMX::state:IA::fema:7::ugc:IAC169::limit:no::sday:0101::eday:1231::phenomena:FF::significance:W::_r:t::dpi:100::_cb:1.png /plotting/auto/plot/73/opt:wfo::network:WFO::station:DMX::state:IA::ugc:IAC169::limit:yes::sday:0101::eday:1231::phenomena:TO::significance:W::_r:t::dpi:100.png /plotting/auto/plot/73/opt:ugc::network:WFO::station:PQR::state:WA::ugc:WAZ660::limit:no::sday:0101::eday:1231::phenomena:FW::significance:W::_r:t::dpi:100.png @@ -244,6 +247,8 @@ /plotting/auto/plot/196/network:IA_ASOS::station:AMW::opt:no::var:chill::_r:43::dpi:100.png /plotting/auto/plot/197/csector:IA::var:corn_planting::w:avg::weeks:1::date:2021-05-09::cmap:BrBG::_r:43::dpi:100.png /plotting/auto/plot/198/network:RAOB::station:_OAX::hour:12::month:all::agg:avg::var:tmpc::level:500::quorum:no::_r:t::dpi:100.png +/plotting/auto/plot/198/network:RAOB::station:_OAX::hour:ALL::month:mjj::agg:max::var:pwater_mm::level:500::quorum:no::_r:43::dpi:100.png +/plotting/auto/plot/198/network:RAOB::station:_OAX::hour:12::month:spring::agg:max::var:height::level:825::quorum:yes::_r:43::dpi:100.png /plotting/auto/plot/199/opt:1::date:2024-07-24::_r:t::dpi:100.png /plotting/auto/plot/199/opt:2::date:2024-07-24::_r:t::dpi:100.png /plotting/auto/plot/199/opt:3::date:2024-07-24::_r:t::dpi:100.png @@ -275,6 +280,7 @@ /plotting/auto/plot/211/ptype:wind::network:IA_ASOS::zstation:AMW::sts:2024-07-10%200000::ets:2024-07-12%202359::_r:t::dpi:100::_cb:1.png /plotting/auto/plot/211/ptype:windkt::network:IA_ASOS::zstation:AMW::sts:2024-07-10%200000::ets:2024-07-12%202359::_r:t::dpi:100.png /plotting/auto/plot/212/network:RAOB::station:_OAX::year:2024::hour:both::var:height::level:500::_r:t::dpi:100.png +/plotting/auto/plot/215/network:IACLIMATE::station:IATAME::v:avgt::month:mar::sy1:1981::ey1:2010::sy2:1991::ey2:2020::_r:43::dpi:100.png /plotting/auto/plot/216/network:MA_ASOS::station:BOS::var:max_dwpf::dir:above::threshold:70::_r:43::dpi:100.png /plotting/auto/plot/216/network:IA_ASOS::station:AMW::var:high::dir:below::threshold:32::_r:t::dpi:100.png /plotting/auto/plot/217/pid:202408100731-KMHX-WWUS82-SPSMHX::segnum:0::_r:t::dpi:100::_cb:1.png