diff --git a/.gitignore b/.gitignore index 394b813..ecce80d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .vscode */.ipynb_checkpoints/* __pycache__/ +**/__marimo__/* # Distribution / packaging build/ diff --git a/docs/examples/quality/plot_bsrn_closure.py b/docs/examples/quality/plot_bsrn_closure.py index 228872c..28c5996 100644 --- a/docs/examples/quality/plot_bsrn_closure.py +++ b/docs/examples/quality/plot_bsrn_closure.py @@ -8,11 +8,17 @@ """ # %% -# In the example below, measured GHI is plotted against calculated GHI using -# :py:func:`solarpy.plotting.plot_bsrn_closure`. Reference closure limits of -# ±8% (dashed) and ±15% (dash-dot) are overlaid. Measurements falling -# outside these bands indicate a possible inconsistency in at least one of -# the components. +# This closure comparison test is one of the most powerful quality checks for +# solar radiation measurements, as it compared the same quantity, GHI, measured +# independently using different instruments. + +# In the example below, the difference between measured and calculated GHI is +# plotted against calculated GHI using :py:func:`solarpy.plotting.plot_bsrn_closure`. +# Reference closure limits of ±8% (dashed) and ±15% (dash-dot) are overlaid. +# Measurements falling outside these bands indicate a possible inconsistency in at +# least one of the components. It should be noted that the closure test is not a +# definitive test, as it does not indicate which of the three measurements is potentially +# erroneous. # %% # Load example data @@ -21,7 +27,6 @@ # The example data is from DTU's station in Lyngby, Denmark north of Copenhagen. # The data is from 2023 and includes measurements of GHI, DHI, and DNI at a 1-minute resolution. -import matplotlib.pyplot as plt import pvlib import solarpy diff --git a/docs/notebooks/example.py b/docs/notebooks/example.py index aa47544..cbc12d0 100644 --- a/docs/notebooks/example.py +++ b/docs/notebooks/example.py @@ -1,70 +1,98 @@ import marimo -__generated_with = "0.1.0" +__generated_with = "0.23.10" app = marimo.App() @app.cell -def __(): +def _(): import marimo as mo - return mo, + + return (mo,) @app.cell -def __(mo): - mo.md("# Welcome to Marimo!") +def _(mo): + mo.md(""" + # Interactive selection of data! + + An example of interactive selection of data in Python using Marimo notebooks in the browser. + """) return @app.cell -def __(mo): - slider = mo.ui.slider(1, 10, value=5, label="Select a value") - slider - return slider, +def _(np, pvlib, solarpy): + data, meta = solarpy.iotools.read_t16( + "https://raw.githubusercontent.com/AssessingSolar/solarpy/refs/heads/main/data/LYN_2023.csv", # noqa: E501 + map_variables=True, + ) + + # Calculate solar position + solar_position = pvlib.solarposition.get_solarposition( + data.index, latitude=meta["latitude"], longitude=meta["longitude"] + ) + + # Calculate extraterrestrial irradiance on a horizontal plane + dni_extra = pvlib.irradiance.get_extra_radiation(data.index) + cos_sza = np.cos(np.deg2rad(solar_position["apparent_zenith"])).clip(lower=0) + ghi_extra = dni_extra * cos_sza + return data, ghi_extra + + +@app.cell(hide_code=True) +def _(mo): + mo.md(r""" + In the below plot, you can select a cluster of points to see which dates + """) + return @app.cell -def __(mo, slider): - mo.md(f"You selected: **{slider.value}**") +def _(data, ghi_extra, mo, plt, solarpy): + x, y = ghi_extra, data["ghi"] + + fig, ax = solarpy.plotting.plot_bsrn_limits( + irradiance=data["ghi"], + component="ghi", + ghi_extra=ghi_extra, + ) + + fig.tight_layout() + + ax = mo.ui.matplotlib(plt.gca()) + ax + return ax, x, y + + +@app.cell(hide_code=True) +def _(mo): + mo.md(r""" + Selected points can be seen below + """) return @app.cell -def __(): - import matplotlib.pyplot as plt - import numpy as np - return np, plt +def _(ax, data, x, y): + mask = ax.value.get_mask(x, y) + value_counts = data.index[mask].to_series().dt.date.value_counts() + value_counts + return @app.cell -def __(np, plt, slider): - x = np.linspace(0, 2 * np.pi, 100) - y = np.sin(slider.value * x) +def _(): + import matplotlib.pyplot as plt + import numpy as np + import pvlib + import solarpy - fig, ax = plt.subplots(figsize=(8, 4)) - ax.plot(x, y) - ax.set_xlabel("X") - ax.set_ylabel("Y") - ax.set_title(f"Sin({slider.value}x)") - ax.grid(True, alpha=0.3) - plt.tight_layout() - fig - return ax, fig, x, y + return np, plt, pvlib, solarpy @app.cell -def __(mo): - mo.md(""" - ## Interactive Features - - This notebook demonstrates: - - Reactive UI components - - Real-time updates - - Matplotlib integration - - Markdown rendering - - Try adjusting the slider above to see the plot update! - """) +def _(): return diff --git a/src/solarpy/plotting/bsrn_comparison.py b/src/solarpy/plotting/bsrn_comparison.py index da68cfc..b104cd5 100644 --- a/src/solarpy/plotting/bsrn_comparison.py +++ b/src/solarpy/plotting/bsrn_comparison.py @@ -30,8 +30,8 @@ def plot_bsrn_closure( """Plot a scatter heatmap of the BSRN closure test. Compares measured GHI against the GHI computed from its components, - *ghi_calc* = DHI + DNI·cos(Z), using - :func:`solarpy.plotting.plot_scatter_heatmap`. Reference closure limits + *GHI_calc* = DHI + DNI·cos(Z), using + :func:`solarpy.plotting.plot_scatter_heatmap`. Closure limits of ±8% (dashed) and ±15% (dash-dot) are overlaid. Parameters @@ -137,12 +137,8 @@ def plot_bsrn_closure( limit_line_params = {"lw": 1.5, "alpha": 0.8, "c": "r", "linestyle": "--"} if relative: - ax.plot( - [0, 75, 75, 93, 93], [1.08, 1.08, 1.15, 1.15, 1], **limit_line_params - ) - ax.plot( - [0, 75, 75, 93, 93], [0.92, 0.92, 0.85, 0.85, 1], **limit_line_params - ) + ax.plot([0, 75, 75, 93, 93], [1.08, 1.08, 1.15, 1.15, 1], **limit_line_params) + ax.plot([0, 75, 75, 93, 93], [0.92, 0.92, 0.85, 0.85, 1], **limit_line_params) else: x_limits = np.array([max(xlim[0], 50), xlim[1]]) for frac, linestyle in zip([0.08, 0.15], ["--", "-."]):