diff --git a/pylib/iemweb/autoplot/scripts/p15.py b/pylib/iemweb/autoplot/scripts/p15.py
index 737d6986d..466c645d3 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 f27d311a9..f7a788e5a 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 8a4229ec5..185d14630 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 903f13815..33d286e40 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 946d9e009..2810f8815 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 cf032a5fa..4f53148d4 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 633851b37..034bec901 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 f08e9de10..7062dcb62 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 d6b7cceba..4ffb3c8f3 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 1968a45bd..f2a5e4b62 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 48fb0cada..f181d8d38 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 a55dd5885..b1d0cc222 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 c8fc1bf88..0f29fda19 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 551603d05..841aea18a 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 da42c583a..a70954c05 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 54b956fe6..a9852bdb1 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 aae38e2f9..1af73fe68 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 3972e208e..e52d7d3f8 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 981e1b001..6f1ebb53a 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 cabb9d49d..493dfa76b 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 476c63fab..2dbaa8b2e 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 9d2d23049..8c0371e2d 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 3f87551d7..31b97dd3f 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 4930aeb87..ba21d536d 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 3d55b43cd..dcae9052a 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 2b41c6e9a..8a939cdbe 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 a3c383fce..d5506b1d4 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 ae7db6aff..61fee1646 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 000000000..9b2d17715
--- /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 a12e6a48b..3e4a63444 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
@@ -32,6 +34,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 +54,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
@@ -56,12 +62,14 @@
/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
/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
@@ -239,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
@@ -270,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