From 9f31c8df5d324466bd2dedb254a9d428078d5fe9 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 4 Aug 2026 12:34:51 +0200 Subject: [PATCH 1/3] Create split y-axis in time series irradiance plots --- src/solarpy/plotting/multiplot.py | 60 +++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/src/solarpy/plotting/multiplot.py b/src/solarpy/plotting/multiplot.py index 3a78ff5..8c4bb20 100644 --- a/src/solarpy/plotting/multiplot.py +++ b/src/solarpy/plotting/multiplot.py @@ -213,9 +213,15 @@ def multiplot(times, data, meta, horizon=None, google_api_key=None, figsize=(24, # TODO: remove pandas dependency # resampling to speed up the process for ax, c in zip(axes["line"], components): - ax.plot(data[c].resample("5min").max(), lw=0.5) + # ax.plot(data[c].resample("5min").max(), lw=0.5) + # ax.set_ylabel(f"{c.upper()} [W/m²]") + # ax.set_ylim(0, None) + ax.plot(piecewise_transform(data[c].resample("5min").max()), lw=0.5) ax.set_ylabel(f"{c.upper()} [W/m²]") - ax.set_ylim(0, None) + ax.set_ylim(piecewise_transform([-8, 1500])) + for ytick in [-6, -4, -2, 0]: + ax.axhline(piecewise_transform(ytick), c='black', linestyle='--', + alpha=0.5, lw=0.5) # Determine sunrise and sunset sun_rise_set = pvlib.solarposition.sun_rise_set_transit_spa( @@ -705,3 +711,53 @@ def multiplot(times, data, meta, horizon=None, google_api_key=None, figsize=(24, ) return fig, axes + + +def piecewise_transform(y, lower=-8, center=0, upper=1500, center_frac=0.25): + """ + Piecewise linear transform. + + Parameters + ---------- + y : array-like + Values to transform. + lower : float, default=-8 + Minimum value. + center : float, default=0 + Breakpoint between the two linear regions. + upper : float, default=1500 + Maximum value. + center_frac : float, default=0.25 + Fraction of the transformed axis occupied by the interval + ``[lower, center]``. The interval ``[center, upper]`` occupies the + remaining ``1 - center_frac`` of the axis. + + Returns + ------- + ndarray + Transformed values mapped to the interval ``[0, 1]``. + """ + is_series = isinstance(y, pd.Series) + + values = np.asarray(y, dtype=float) + out = np.empty_like(values) + + lower_mask = values <= center + out[lower_mask] = ( + (values[lower_mask] - lower) + / (center - lower) + * center_frac + ) + + upper_mask = ~lower_mask + out[upper_mask] = ( + center_frac + + (values[upper_mask] - center) + / (upper - center) + * (1 - center_frac) + ) + + if is_series: + return pd.Series(out, index=y.index, name=y.name) + + return out From c776ea83031cb7eb6652739c70fb7b56bfd3c202 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 4 Aug 2026 12:40:18 +0200 Subject: [PATCH 2/3] Add y-ticks --- src/solarpy/plotting/multiplot.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/solarpy/plotting/multiplot.py b/src/solarpy/plotting/multiplot.py index 8c4bb20..b20e8c2 100644 --- a/src/solarpy/plotting/multiplot.py +++ b/src/solarpy/plotting/multiplot.py @@ -216,11 +216,14 @@ def multiplot(times, data, meta, horizon=None, google_api_key=None, figsize=(24, # ax.plot(data[c].resample("5min").max(), lw=0.5) # ax.set_ylabel(f"{c.upper()} [W/m²]") # ax.set_ylim(0, None) - ax.plot(piecewise_transform(data[c].resample("5min").max()), lw=0.5) + ax.plot(_piecewise_transform(data[c].resample("5min").max()), lw=0.5) ax.set_ylabel(f"{c.upper()} [W/m²]") - ax.set_ylim(piecewise_transform([-8, 1500])) - for ytick in [-6, -4, -2, 0]: - ax.axhline(piecewise_transform(ytick), c='black', linestyle='--', + ax.set_ylim(_piecewise_transform([-8, 1500])) + yticks = [-8, 0, 500, 1000, 1500] + ax.set_yticks(_piecewise_transform(yticks)) + ax.set_yticklabels(yticks) + for yline in [-6, -4, -2, 0]: + ax.axhline(_piecewise_transform(yline), c='black', linestyle='--', alpha=0.5, lw=0.5) # Determine sunrise and sunset @@ -713,7 +716,7 @@ def multiplot(times, data, meta, horizon=None, google_api_key=None, figsize=(24, return fig, axes -def piecewise_transform(y, lower=-8, center=0, upper=1500, center_frac=0.25): +def _piecewise_transform(y, lower=-8, center=0, upper=1500, center_frac=0.25): """ Piecewise linear transform. From fae490079d37f317fb2aaeefea721f92de886153 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Tue, 4 Aug 2026 14:59:48 +0200 Subject: [PATCH 3/3] Make zero line solid and non-transparent --- src/solarpy/plotting/multiplot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/solarpy/plotting/multiplot.py b/src/solarpy/plotting/multiplot.py index b20e8c2..72aa067 100644 --- a/src/solarpy/plotting/multiplot.py +++ b/src/solarpy/plotting/multiplot.py @@ -222,7 +222,8 @@ def multiplot(times, data, meta, horizon=None, google_api_key=None, figsize=(24, yticks = [-8, 0, 500, 1000, 1500] ax.set_yticks(_piecewise_transform(yticks)) ax.set_yticklabels(yticks) - for yline in [-6, -4, -2, 0]: + ax.axhline(_piecewise_transform(0), c='black', linestyle='-', lw=0.5) + for yline in [-6, -4, -2]: ax.axhline(_piecewise_transform(yline), c='black', linestyle='--', alpha=0.5, lw=0.5)