From 0ee9b27020a7adfb14771398ed12d393e549b2a4 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sat, 25 Jul 2026 23:56:09 -0800 Subject: [PATCH 01/32] Add marimo example --- .readthedocs.yaml | 14 +++++++------- docs/myst.yml | 5 +++++ docs/requirements.txt | 1 + docs/station_catalog_marimo.md | 14 ++++++++++++++ pyproject.toml | 23 +++++++++++++++++++++++ 5 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 docs/station_catalog_marimo.md create mode 100644 pyproject.toml diff --git a/.readthedocs.yaml b/.readthedocs.yaml index b23485d..c8a86a1 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -8,15 +8,15 @@ build: python: "3.13" nodejs: "22" commands: - # Install Python dependencies - - pip install -r docs/requirements.txt + # Install Python dependencies via uv, creating .venv at the repo root + # (myst.yml's marimo plugin path, ../.venv/bin/jupyter-book-marimo, expects it there) + - UV_PROJECT_ENVIRONMENT=.venv uv sync # Install mystmd - npm install -g mystmd # Build the site (myst.yml lives in docs/, so build from there) - # --execute re-runs notebook code cells instead of using their stored outputs. - - cd docs && myst build --html --execute + - cd docs && UV_PROJECT_ENVIRONMENT=.venv uv run jupyter-book build --html # Copy the output to Read the Docs expected location - - mkdir -p $READTHEDOCS_OUTPUT/html/ - - cp -r docs/_build/html/. "$READTHEDOCS_OUTPUT/html" + - mkdir -p "$READTHEDOCS_OUTPUT/html/" + - cd docs && cp -r _build/html/. "$READTHEDOCS_OUTPUT/html/" # Clean up build artifacts - - rm -rf docs/_build + - cd docs && rm -rf _build diff --git a/docs/myst.yml b/docs/myst.yml index 670c15a..5563925 100644 --- a/docs/myst.yml +++ b/docs/myst.yml @@ -20,9 +20,14 @@ project: settings: output_matplotlib_strings: remove + plugins: + - type: executable + path: ../.venv/bin/jupyter-book-marimo + toc: - file: intro.ipynb - file: station_catalog.ipynb + - file: station_catalog_marimo.md - file: station_requirements.md title: Station requirements - file: station_metadata.md diff --git a/docs/requirements.txt b/docs/requirements.txt index 080843c..df4182a 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -10,3 +10,4 @@ unidecode==1.4.0 openpyxl==3.1.5 xarray==2026.7.0 h5netcdf==1.8.1 +jupyter-book-marimo==0.0.1 diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md new file mode 100644 index 0000000..5ffe041 --- /dev/null +++ b/docs/station_catalog_marimo.md @@ -0,0 +1,14 @@ + + + + +```{marimo} python +import marimo as mo + +slider = mo.ui.slider(start=1, stop=10, label="islands") +slider +``` + +```{marimo} python +mo.md(f"The slider is set to **{slider.value}**.") +``` diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..607de60 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,23 @@ +[project] +name = "SolarStations.org" +version = "0.1.0" +description = "A catalog of multi-component solar irradiance monitoring stations." +readme = "README.md" +requires-python = ">=3.13" +dependencies = [ + "folium==0.20.0", + "itables==2.2.2", + "jupyter-book==2.1.6", + "kgcpy==1.1.8", + "matplotlib==3.11.1", + "numpy==2.5.1", + "pandas==3.0.3", + "pvlib==0.15.2", + "unidecode==1.4.0", + "openpyxl==3.1.5", + "xarray==2026.7.0", + "h5netcdf==1.8.1", + "jupyter-book==2.1.6", + "jupyter-book-marimo>=0.0.1", + "marimo", +] From e8a8c9a1767b2b592187d1208ed57616eb984424 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sat, 25 Jul 2026 23:58:34 -0800 Subject: [PATCH 02/32] Include separate uv sync install --- .readthedocs.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index c8a86a1..a6f6703 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -20,3 +20,8 @@ build: - cd docs && cp -r _build/html/. "$READTHEDOCS_OUTPUT/html/" # Clean up build artifacts - cd docs && rm -rf _build + +python: + install: + - method: uv + command: sync From 277ec64613b502da7b1c6d5bc6748df1f40b63df Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sun, 26 Jul 2026 00:03:24 -0800 Subject: [PATCH 03/32] Use real solarstations data for example --- docs/station_catalog_marimo.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 5ffe041..0fb7255 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -4,11 +4,19 @@ ```{marimo} python import marimo as mo +import pandas as pd +# Load stations +solarstations = pd.read_csv('../solarstations.csv', dtype={'Tier': str}).fillna('') -slider = mo.ui.slider(start=1, stop=10, label="islands") -slider +# df is a Pandas or Polars dataframe +table = mo.ui.table( + data=solarstations, + # use pagination when your table has many rows + pagination=True, + label="Dataframe", +) ``` ```{marimo} python -mo.md(f"The slider is set to **{slider.value}**.") +table ``` From d3dfb67ba0f0e27483a102e6340f9a35cd3534f3 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:12:45 +0200 Subject: [PATCH 04/32] Update .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index de95027..1ee2e21 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,6 @@ SolarStationsOrg-station-catalog.csv # MyST build outputs _build + +# Jupyter book +docs/.jupyter-book-marimo From b9d8d74c7d1b530ee179848989c92376724b0be7 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:21:15 +0200 Subject: [PATCH 05/32] Update jupyter-book-marimo version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 607de60..46ab11c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,6 @@ dependencies = [ "xarray==2026.7.0", "h5netcdf==1.8.1", "jupyter-book==2.1.6", - "jupyter-book-marimo>=0.0.1", + "jupyter-book-marimo>=0.0.2", "marimo", ] From 2af1b43dc7c4fe32071c10f624fa164d6fa5cfe8 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:21:21 +0200 Subject: [PATCH 06/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 0fb7255..873ab86 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -1,22 +1,23 @@ +```{marimo} python +import marimo as mo +slider = mo.ui.slider(start=1, stop=10, label="islands") +slider +``` +```{marimo} python +mo.md(f"The slider is set to **{slider.value}**.") +``` ```{marimo} python -import marimo as mo -import pandas as pd -# Load stations -solarstations = pd.read_csv('../solarstations.csv', dtype={'Tier': str}).fillna('') +from pathlib import Path -# df is a Pandas or Polars dataframe -table = mo.ui.table( - data=solarstations, - # use pagination when your table has many rows - pagination=True, - label="Dataframe", -) +path = Path.cwd() +mo.md(str(path)) ``` ```{marimo} python -table +files = [str(f) for f in path.iterdir() if f.is_file()] +mo.ui.table(files) ``` From 9b3483b3f0d5d633b22d8e36a087d6280b1e457a Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:36:15 +0200 Subject: [PATCH 07/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 873ab86..e159741 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -1,23 +1,25 @@ - ```{marimo} python import marimo as mo - -slider = mo.ui.slider(start=1, stop=10, label="islands") -slider +import pandas as pd ``` -```{marimo} python -mo.md(f"The slider is set to **{slider.value}**.") -``` ```{marimo} python -from pathlib import Path +main_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/solarstations.csv" +esmap_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/esmap_stations.csv" + +main_stations = pd.read_csv(main_ur, dtype={'Tier': str}).fillna('') +esmap_stations = pd.read_csv(esmap_url, dtype={'Tier': str}).fillna('') +stations = pd.concat([main_stations, esmap_stations], axis='rows', ignore_index=True) -path = Path.cwd() -mo.md(str(path)) +table = mo.ui.table( + stations, + pagination=True, + freeze_columns_left=["Station name"], + hidden_columns=["URL], +) ``` ```{marimo} python -files = [str(f) for f in path.iterdir() if f.is_file()] -mo.ui.table(files) -``` +table +``` \ No newline at end of file From ed96be8650c58db5594892f8dcd6d92d6715290a Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:57:07 +0200 Subject: [PATCH 08/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 49 ++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index e159741..bd584a9 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -1,22 +1,67 @@ ```{marimo} python import marimo as mo import pandas as pd +# import kgcpy ``` ```{marimo} python main_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/solarstations.csv" esmap_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/esmap_stations.csv" +country_by_continent_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/data/country_by_continent.json" -main_stations = pd.read_csv(main_ur, dtype={'Tier': str}).fillna('') +main_stations = pd.read_csv(main_url, dtype={'Tier': str}).fillna('') esmap_stations = pd.read_csv(esmap_url, dtype={'Tier': str}).fillna('') stations = pd.concat([main_stations, esmap_stations], axis='rows', ignore_index=True) +country_by_continent = pd.read_json(country_by_continent_url, typ="series").to_dict() + +stations['Continent'] = stations['Country'].map(country_by_continent) + +#stations['Koeppen Geiger classification'] = stations.apply(lambda x: kgcpy.lookupCZ(x['Latitude'], x['Longitude']), axis=1) +#kg_climates = {'A': 'Tropical', 'B': 'Dry', 'C': 'Temperate', 'D': 'Continental', 'E': 'Polar', 'O': 'Ocean'} +#stations['Koeppen Geiger climate zone'] = stations['Koeppen Geiger classification'].apply(lambda x: kg_climates[x[0]]) + +instrumentation = stations['Instrumentation'].str.split(';', expand=True) +is_tier_1 = (instrumentation=='G').any(axis=1) & (instrumentation=='B').any(axis=1) & (instrumentation=='D').any(axis=1) +stations['Tier'] = 2 - is_tier_1.astype(int) + +#annual_irradiance = pd.read_csv('../data/nasa_power_annual_irradiance_global.csv', index_col=[0, 1]) +#for index, row in stations.iterrows(): +# lat_round = round(row['Latitude']*2-0.5, 0)/2 + 0.25 +# lon_round = round(row['Longitude']*2-0.5, 0)/2 + 0.25 +# try: +# stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ +# annual_irradiance.loc[(lat_round, lon_round), :] +# except KeyError as e: +# pass +# # Manual add data missing from the climatological file (data retrieved from NASA's webinterface) +# if row['Station name'] == 'Funafuti': +# stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ +# np.array([5.33*365, 2.12*365, 4.37*365]).astype(int) +# if row['Station name'] == 'South Pole': +# stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ +# np.array([3.0*365, 1.38*365, 5.13*365]).astype(int) + +#stations = stations[~stations['Instrumentation'].str.contains('G;Ds')] # remove Tier 3 stations + +#stations = stations.sort_values('Station name', ignore_index=True) + +## Write file containing all columns, linked to above +#stations.to_csv('./SolarStationsOrg-station-catalog.csv', index=False) + +## Format station name as hyperlinks if URL is available. +## Do this after the new CSV is written, since we don't want HTML in that. +#for index, row in stations.iterrows(): +# if row['URL'].startswith('http'): +# stations.loc[index, 'Station name'] = f'{row["Station name"]}' + + table = mo.ui.table( stations, pagination=True, freeze_columns_left=["Station name"], - hidden_columns=["URL], + hidden_columns=["URL"], ) ``` From c3c3a54a7dd561d77983370bce40d82fab302bd9 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Thu, 30 Jul 2026 09:58:41 +0200 Subject: [PATCH 09/32] Add kgcpy --- docs/station_catalog_marimo.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index bd584a9..09407ba 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -1,7 +1,7 @@ ```{marimo} python import marimo as mo import pandas as pd -# import kgcpy +import kgcpy ``` @@ -18,9 +18,9 @@ country_by_continent = pd.read_json(country_by_continent_url, typ="series").to_d stations['Continent'] = stations['Country'].map(country_by_continent) -#stations['Koeppen Geiger classification'] = stations.apply(lambda x: kgcpy.lookupCZ(x['Latitude'], x['Longitude']), axis=1) -#kg_climates = {'A': 'Tropical', 'B': 'Dry', 'C': 'Temperate', 'D': 'Continental', 'E': 'Polar', 'O': 'Ocean'} -#stations['Koeppen Geiger climate zone'] = stations['Koeppen Geiger classification'].apply(lambda x: kg_climates[x[0]]) +stations['Koeppen Geiger classification'] = stations.apply(lambda x: kgcpy.lookupCZ(x['Latitude'], x['Longitude']), axis=1) +kg_climates = {'A': 'Tropical', 'B': 'Dry', 'C': 'Temperate', 'D': 'Continental', 'E': 'Polar', 'O': 'Ocean'} +stations['Koeppen Geiger climate zone'] = stations['Koeppen Geiger classification'].apply(lambda x: kg_climates[x[0]]) instrumentation = stations['Instrumentation'].str.split(';', expand=True) is_tier_1 = (instrumentation=='G').any(axis=1) & (instrumentation=='B').any(axis=1) & (instrumentation=='D').any(axis=1) From 41ed222b0bfa9b880b3787cf7618e464ed7838f8 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Thu, 30 Jul 2026 14:22:05 +0200 Subject: [PATCH 10/32] Add nasa power irradiances and comment out kgcpy --- docs/station_catalog_marimo.md | 46 ++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 09407ba..3032f4f 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -1,7 +1,8 @@ ```{marimo} python import marimo as mo import pandas as pd -import kgcpy +import numpy as np +#import kgcpy ``` @@ -9,6 +10,7 @@ import kgcpy main_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/solarstations.csv" esmap_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/esmap_stations.csv" country_by_continent_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/data/country_by_continent.json" +nasa_power_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/data/nasa_power_annual_irradiance_global.csv" main_stations = pd.read_csv(main_url, dtype={'Tier': str}).fillna('') esmap_stations = pd.read_csv(esmap_url, dtype={'Tier': str}).fillna('') @@ -18,34 +20,34 @@ country_by_continent = pd.read_json(country_by_continent_url, typ="series").to_d stations['Continent'] = stations['Country'].map(country_by_continent) -stations['Koeppen Geiger classification'] = stations.apply(lambda x: kgcpy.lookupCZ(x['Latitude'], x['Longitude']), axis=1) -kg_climates = {'A': 'Tropical', 'B': 'Dry', 'C': 'Temperate', 'D': 'Continental', 'E': 'Polar', 'O': 'Ocean'} -stations['Koeppen Geiger climate zone'] = stations['Koeppen Geiger classification'].apply(lambda x: kg_climates[x[0]]) +#stations['Koeppen Geiger classification'] = stations.apply(lambda x: kgcpy.lookupCZ(x['Latitude'], x['Longitude']), axis=1) +#kg_climates = {'A': 'Tropical', 'B': 'Dry', 'C': 'Temperate', 'D': 'Continental', 'E': 'Polar', 'O': 'Ocean'} +#stations['Koeppen Geiger climate zone'] = stations['Koeppen Geiger classification'].apply(lambda x: kg_climates[x[0]]) instrumentation = stations['Instrumentation'].str.split(';', expand=True) is_tier_1 = (instrumentation=='G').any(axis=1) & (instrumentation=='B').any(axis=1) & (instrumentation=='D').any(axis=1) stations['Tier'] = 2 - is_tier_1.astype(int) -#annual_irradiance = pd.read_csv('../data/nasa_power_annual_irradiance_global.csv', index_col=[0, 1]) -#for index, row in stations.iterrows(): -# lat_round = round(row['Latitude']*2-0.5, 0)/2 + 0.25 -# lon_round = round(row['Longitude']*2-0.5, 0)/2 + 0.25 -# try: -# stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ -# annual_irradiance.loc[(lat_round, lon_round), :] -# except KeyError as e: -# pass -# # Manual add data missing from the climatological file (data retrieved from NASA's webinterface) -# if row['Station name'] == 'Funafuti': -# stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ -# np.array([5.33*365, 2.12*365, 4.37*365]).astype(int) -# if row['Station name'] == 'South Pole': -# stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ -# np.array([3.0*365, 1.38*365, 5.13*365]).astype(int) +annual_irradiance = pd.read_csv(nasa_power_url, index_col=[0, 1]) +for index, row in stations.iterrows(): + lat_round = round(row['Latitude']*2-0.5, 0)/2 + 0.25 + lon_round = round(row['Longitude']*2-0.5, 0)/2 + 0.25 + try: + stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ + annual_irradiance.loc[(lat_round, lon_round), :] + except KeyError as e: + pass + # Manual add data missing from the climatological file (data retrieved from NASA's webinterface) + if row['Station name'] == 'Funafuti': + stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ + np.array([5.33*365, 2.12*365, 4.37*365]).astype(int) + if row['Station name'] == 'South Pole': + stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ + np.array([3.0*365, 1.38*365, 5.13*365]).astype(int) -#stations = stations[~stations['Instrumentation'].str.contains('G;Ds')] # remove Tier 3 stations +stations = stations[~stations['Instrumentation'].str.contains('G;Ds')] # remove Tier 3 stations -#stations = stations.sort_values('Station name', ignore_index=True) +stations = stations.sort_values('Station name', ignore_index=True) ## Write file containing all columns, linked to above #stations.to_csv('./SolarStationsOrg-station-catalog.csv', index=False) From 45b19032be67ba9bc389c3b0952399f19cf49f67 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:14:41 +0200 Subject: [PATCH 11/32] jupyter-book-marimo==0.0.3 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 46ab11c..efef788 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,6 @@ dependencies = [ "xarray==2026.7.0", "h5netcdf==1.8.1", "jupyter-book==2.1.6", - "jupyter-book-marimo>=0.0.2", + "jupyter-book-marimo==0.0.3", "marimo", ] From 8ce8402c66e7f8c344be6d4f39c10a8dd1717893 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:20:34 +0200 Subject: [PATCH 12/32] Remove python install section from .readthedocs.yaml --- .readthedocs.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index a6f6703..c8a86a1 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -20,8 +20,3 @@ build: - cd docs && cp -r _build/html/. "$READTHEDOCS_OUTPUT/html/" # Clean up build artifacts - cd docs && rm -rf _build - -python: - install: - - method: uv - command: sync From 90ab203449acc2f7e5aed5b395aeb7d8c9426a16 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:24:21 +0200 Subject: [PATCH 13/32] Add pip install uv --- .readthedocs.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index c8a86a1..9244253 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -8,6 +8,8 @@ build: python: "3.13" nodejs: "22" commands: + # Install uv itself (not preinstalled on the RTD build image) + - pip install uv # Install Python dependencies via uv, creating .venv at the repo root # (myst.yml's marimo plugin path, ../.venv/bin/jupyter-book-marimo, expects it there) - UV_PROJECT_ENVIRONMENT=.venv uv sync From 6f116ff1d17825b9b62f13ab0763c3996159759c Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:30:42 +0200 Subject: [PATCH 14/32] Update requirements.txt --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index df4182a..41def2f 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -10,4 +10,4 @@ unidecode==1.4.0 openpyxl==3.1.5 xarray==2026.7.0 h5netcdf==1.8.1 -jupyter-book-marimo==0.0.1 +jupyter-book-marimo==0.0.3 From 9e30e91d1410f143e8877a404a104748f5e74426 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:40:56 +0200 Subject: [PATCH 15/32] Experiment with table format --- docs/station_catalog_marimo.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 3032f4f..e4ce0e3 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -54,16 +54,21 @@ stations = stations.sort_values('Station name', ignore_index=True) ## Format station name as hyperlinks if URL is available. ## Do this after the new CSV is written, since we don't want HTML in that. -#for index, row in stations.iterrows(): -# if row['URL'].startswith('http'): -# stations.loc[index, 'Station name'] = f'{row["Station name"]}' +for index, row in stations.iterrows(): + if row['URL'].startswith('http'): + stations.loc[index, 'Station name'] = f'{row["Station name"]}' +# Drop the columns as using ``hidden_columns`` let's users know that there is a hidden column` +stations = stations.drop(columns=['URL']) table = mo.ui.table( stations, pagination=True, freeze_columns_left=["Station name"], - hidden_columns=["URL"], + page_size=20, # default is 10 + show_download=True, + column_widths={"Station name": 20}, + # hidden_columns=["URL"], ) ``` From 5e7e9719f22dc3d7fde5c51ebb527a749975eca9 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:47:01 +0200 Subject: [PATCH 16/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index e4ce0e3..1902d65 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -56,7 +56,7 @@ stations = stations.sort_values('Station name', ignore_index=True) ## Do this after the new CSV is written, since we don't want HTML in that. for index, row in stations.iterrows(): if row['URL'].startswith('http'): - stations.loc[index, 'Station name'] = f'{row["Station name"]}' + stations.loc[index, 'Station name'] = f'[{row["Station name"]}]({row["URL"]})' # Drop the columns as using ``hidden_columns`` let's users know that there is a hidden column` stations = stations.drop(columns=['URL']) @@ -67,7 +67,7 @@ table = mo.ui.table( freeze_columns_left=["Station name"], page_size=20, # default is 10 show_download=True, - column_widths={"Station name": 20}, + column_widths={"Station name": 150}, # hidden_columns=["URL"], ) ``` From 17bb111cb99e98480f87b76905b90d6fe99e219a Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:50:18 +0200 Subject: [PATCH 17/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 1902d65..8275f76 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -54,12 +54,12 @@ stations = stations.sort_values('Station name', ignore_index=True) ## Format station name as hyperlinks if URL is available. ## Do this after the new CSV is written, since we don't want HTML in that. -for index, row in stations.iterrows(): - if row['URL'].startswith('http'): - stations.loc[index, 'Station name'] = f'[{row["Station name"]}]({row["URL"]})' +#for index, row in stations.iterrows(): +# if row['URL'].startswith('http'): +# stations.loc[index, 'Station name'] = f'[{row["Station name"]}]({row["URL"]})' -# Drop the columns as using ``hidden_columns`` let's users know that there is a hidden column` -stations = stations.drop(columns=['URL']) +## Drop the columns as using ``hidden_columns`` let's users know that there is a hidden column` +#stations = stations.drop(columns=['URL']) table = mo.ui.table( stations, @@ -67,7 +67,7 @@ table = mo.ui.table( freeze_columns_left=["Station name"], page_size=20, # default is 10 show_download=True, - column_widths={"Station name": 150}, + column_widths={"Station name": 180, "URL": 30}, # hidden_columns=["URL"], ) ``` From c8f49f29968f1282659b0afca29cc3f17ba888d0 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:53:19 +0200 Subject: [PATCH 18/32] Remove formatting of URL column and keep URL column --- docs/station_catalog_marimo.md | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 8275f76..ecbb2df 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -49,17 +49,8 @@ stations = stations[~stations['Instrumentation'].str.contains('G;Ds')] # remove stations = stations.sort_values('Station name', ignore_index=True) -## Write file containing all columns, linked to above -#stations.to_csv('./SolarStationsOrg-station-catalog.csv', index=False) - -## Format station name as hyperlinks if URL is available. -## Do this after the new CSV is written, since we don't want HTML in that. -#for index, row in stations.iterrows(): -# if row['URL'].startswith('http'): -# stations.loc[index, 'Station name'] = f'[{row["Station name"]}]({row["URL"]})' - -## Drop the columns as using ``hidden_columns`` let's users know that there is a hidden column` -#stations = stations.drop(columns=['URL']) +# Write file containing all columns, linked to above +stations.to_csv('./SolarStationsOrg-station-catalog.csv', index=False) table = mo.ui.table( stations, @@ -67,8 +58,7 @@ table = mo.ui.table( freeze_columns_left=["Station name"], page_size=20, # default is 10 show_download=True, - column_widths={"Station name": 180, "URL": 30}, - # hidden_columns=["URL"], + column_widths={"Station name": 180, "URL": 80}, ) ``` From cd01c29c7029fb4cc9911d477eaaea47282b89bd Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:03:31 +0200 Subject: [PATCH 19/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index ecbb2df..a64c971 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -2,7 +2,7 @@ import marimo as mo import pandas as pd import numpy as np -#import kgcpy +import kgcpy ``` @@ -33,22 +33,32 @@ for index, row in stations.iterrows(): lat_round = round(row['Latitude']*2-0.5, 0)/2 + 0.25 lon_round = round(row['Longitude']*2-0.5, 0)/2 + 0.25 try: - stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ + stations.loc[index, ['GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2']] = \ annual_irradiance.loc[(lat_round, lon_round), :] except KeyError as e: pass # Manual add data missing from the climatological file (data retrieved from NASA's webinterface) if row['Station name'] == 'Funafuti': - stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ + stations.loc[index, ['GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2']] = \ np.array([5.33*365, 2.12*365, 4.37*365]).astype(int) if row['Station name'] == 'South Pole': - stations.loc[index, ['GHI_typical_kWh_m2', 'DHI_typical_kWh_m2', 'DNI_typical_kWh_m2']] = \ + stations.loc[index, ['GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2']] = \ np.array([3.0*365, 1.38*365, 5.13*365]).astype(int) stations = stations[~stations['Instrumentation'].str.contains('G;Ds')] # remove Tier 3 stations stations = stations.sort_values('Station name', ignore_index=True) +columns_ordered = [ + 'Station name', 'Abbreviation', 'State', 'Country', 'Continent', 'Latitude', 'Longitude', 'Elevation', + 'Time period', 'Network', 'Owner', 'Comment', 'URL', 'Data availability', 'Instrumentation', 'Tier', 'GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2', + 'URL' +] + +stations["Elevation"] = stations["Elevation"].astype(float) + +stations = stations[columns_ordered] + # Write file containing all columns, linked to above stations.to_csv('./SolarStationsOrg-station-catalog.csv', index=False) From f4d4f722279fcac768599af1e945b12bddba164b Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:05:10 +0200 Subject: [PATCH 20/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index a64c971..cc7c4f3 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -55,7 +55,7 @@ columns_ordered = [ 'URL' ] -stations["Elevation"] = stations["Elevation"].astype(float) +stations["Elevation"] = stations["Elevation"].str.replace('', np.nan).astype(float) stations = stations[columns_ordered] From da1a438fc82e7e27c04fca312b64a56e246081d9 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:06:33 +0200 Subject: [PATCH 21/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index cc7c4f3..eb51e93 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -2,7 +2,7 @@ import marimo as mo import pandas as pd import numpy as np -import kgcpy +# import kgcpy ``` @@ -20,9 +20,9 @@ country_by_continent = pd.read_json(country_by_continent_url, typ="series").to_d stations['Continent'] = stations['Country'].map(country_by_continent) -#stations['Koeppen Geiger classification'] = stations.apply(lambda x: kgcpy.lookupCZ(x['Latitude'], x['Longitude']), axis=1) -#kg_climates = {'A': 'Tropical', 'B': 'Dry', 'C': 'Temperate', 'D': 'Continental', 'E': 'Polar', 'O': 'Ocean'} -#stations['Koeppen Geiger climate zone'] = stations['Koeppen Geiger classification'].apply(lambda x: kg_climates[x[0]]) +# stations['Koeppen Geiger classification'] = stations.apply(lambda x: kgcpy.lookupCZ(x['Latitude'], x['Longitude']), axis=1) +# kg_climates = {'A': 'Tropical', 'B': 'Dry', 'C': 'Temperate', 'D': 'Continental', 'E': 'Polar', 'O': 'Ocean'} +# stations['Koeppen Geiger climate zone'] = stations['Koeppen Geiger classification'].apply(lambda x: kg_climates[x[0]]) instrumentation = stations['Instrumentation'].str.split(';', expand=True) is_tier_1 = (instrumentation=='G').any(axis=1) & (instrumentation=='B').any(axis=1) & (instrumentation=='D').any(axis=1) @@ -50,9 +50,8 @@ stations = stations[~stations['Instrumentation'].str.contains('G;Ds')] # remove stations = stations.sort_values('Station name', ignore_index=True) columns_ordered = [ - 'Station name', 'Abbreviation', 'State', 'Country', 'Continent', 'Latitude', 'Longitude', 'Elevation', - 'Time period', 'Network', 'Owner', 'Comment', 'URL', 'Data availability', 'Instrumentation', 'Tier', 'GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2', - 'URL' + 'Station name', 'URL', 'Abbreviation', 'State', 'Country', 'Continent', 'Latitude', 'Longitude', 'Elevation', + 'Time period', 'Network', 'Owner', 'Comment', 'URL', 'Data availability', 'Instrumentation', 'Tier', 'GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2', 'Koeppen Geiger climate zone', ] stations["Elevation"] = stations["Elevation"].str.replace('', np.nan).astype(float) From c9c4e186b009941c3b5d669dce0f1cbe05d2aa9d Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:14:28 +0200 Subject: [PATCH 22/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index eb51e93..8ee4f1f 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -12,8 +12,8 @@ esmap_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs country_by_continent_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/data/country_by_continent.json" nasa_power_url = "https://raw.githubusercontent.com/AssessingSolar/solarstations/refs/heads/main/data/nasa_power_annual_irradiance_global.csv" -main_stations = pd.read_csv(main_url, dtype={'Tier': str}).fillna('') -esmap_stations = pd.read_csv(esmap_url, dtype={'Tier': str}).fillna('') +main_stations = pd.read_csv(main_url) +esmap_stations = pd.read_csv(esmap_url) stations = pd.concat([main_stations, esmap_stations], axis='rows', ignore_index=True) country_by_continent = pd.read_json(country_by_continent_url, typ="series").to_dict() @@ -54,8 +54,6 @@ columns_ordered = [ 'Time period', 'Network', 'Owner', 'Comment', 'URL', 'Data availability', 'Instrumentation', 'Tier', 'GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2', 'Koeppen Geiger climate zone', ] -stations["Elevation"] = stations["Elevation"].str.replace('', np.nan).astype(float) - stations = stations[columns_ordered] # Write file containing all columns, linked to above From cbfc3966026aca280e0ae71dafdacf45bb5c95cf Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:16:41 +0200 Subject: [PATCH 23/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 8ee4f1f..1da19cf 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -51,7 +51,8 @@ stations = stations.sort_values('Station name', ignore_index=True) columns_ordered = [ 'Station name', 'URL', 'Abbreviation', 'State', 'Country', 'Continent', 'Latitude', 'Longitude', 'Elevation', - 'Time period', 'Network', 'Owner', 'Comment', 'URL', 'Data availability', 'Instrumentation', 'Tier', 'GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2', 'Koeppen Geiger climate zone', + 'Time period', 'Network', 'Owner', 'Comment', 'URL', 'Data availability', 'Instrumentation', 'Tier', 'GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2', + # 'Koeppen Geiger climate zone', ] stations = stations[columns_ordered] From 77e6c17f3052bf49b027e7b6ed28e3999119489a Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:19:09 +0200 Subject: [PATCH 24/32] Try kgcpy again --- docs/station_catalog_marimo.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 1da19cf..2b40c48 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -50,8 +50,10 @@ stations = stations[~stations['Instrumentation'].str.contains('G;Ds')] # remove stations = stations.sort_values('Station name', ignore_index=True) columns_ordered = [ - 'Station name', 'URL', 'Abbreviation', 'State', 'Country', 'Continent', 'Latitude', 'Longitude', 'Elevation', - 'Time period', 'Network', 'Owner', 'Comment', 'URL', 'Data availability', 'Instrumentation', 'Tier', 'GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2', + 'Station name', 'URL', 'Abbreviation', 'State', 'Country', 'Continent', + 'Latitude', 'Longitude', 'Elevation', + 'Time period', 'Network', 'Owner', 'Comment', 'Data availability', 'Instrumentation', 'Tier', + 'GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2', # 'Koeppen Geiger climate zone', ] From 43d4429d6e0d17111373a60d0da6c17f4ac843a3 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:27:49 +0200 Subject: [PATCH 25/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 2b40c48..31272c2 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -49,6 +49,10 @@ stations = stations[~stations['Instrumentation'].str.contains('G;Ds')] # remove stations = stations.sort_values('Station name', ignore_index=True) +for c in stations.columns: + if pd.api.types.is_numeric_dtype(stations[c]): + stations[c] = stations[c].replace(np.nan, '') + columns_ordered = [ 'Station name', 'URL', 'Abbreviation', 'State', 'Country', 'Continent', 'Latitude', 'Longitude', 'Elevation', From 9f1e3ddbbf922dc1c47d275dbb088e8b4c4b9feb Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:30:41 +0200 Subject: [PATCH 26/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 31272c2..c3efd31 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -49,8 +49,9 @@ stations = stations[~stations['Instrumentation'].str.contains('G;Ds')] # remove stations = stations.sort_values('Station name', ignore_index=True) +# Set empty string values to empty string as otherwise they are shown as NaN in the table for c in stations.columns: - if pd.api.types.is_numeric_dtype(stations[c]): + if not pd.api.types.is_numeric_dtype(stations[c]): stations[c] = stations[c].replace(np.nan, '') columns_ordered = [ From 794ebdb5a73c620d4f2894c8e7a954fd925819da Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:33:45 +0200 Subject: [PATCH 27/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index c3efd31..61f2e6d 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -34,7 +34,7 @@ for index, row in stations.iterrows(): lon_round = round(row['Longitude']*2-0.5, 0)/2 + 0.25 try: stations.loc[index, ['GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2']] = \ - annual_irradiance.loc[(lat_round, lon_round), :] + annual_irradiance.loc[(lat_round, lon_round), :].values except KeyError as e: pass # Manual add data missing from the climatological file (data retrieved from NASA's webinterface) From 517e557347cecb47953b8cf27468c78475e4b03a Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:36:40 +0200 Subject: [PATCH 28/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 61f2e6d..30606c1 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -29,12 +29,13 @@ is_tier_1 = (instrumentation=='G').any(axis=1) & (instrumentation=='B').any(axis stations['Tier'] = 2 - is_tier_1.astype(int) annual_irradiance = pd.read_csv(nasa_power_url, index_col=[0, 1]) +stations[['GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2']] = np.nan for index, row in stations.iterrows(): lat_round = round(row['Latitude']*2-0.5, 0)/2 + 0.25 lon_round = round(row['Longitude']*2-0.5, 0)/2 + 0.25 try: stations.loc[index, ['GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2']] = \ - annual_irradiance.loc[(lat_round, lon_round), :].values + annual_irradiance.loc[(lat_round, lon_round), :] except KeyError as e: pass # Manual add data missing from the climatological file (data retrieved from NASA's webinterface) From 51878b4737b3eef9e63be5e32155e3338682c65d Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:41:48 +0200 Subject: [PATCH 29/32] Try kgcpy --- docs/station_catalog_marimo.md | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 30606c1..0a678d5 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -2,7 +2,7 @@ import marimo as mo import pandas as pd import numpy as np -# import kgcpy +import kgcpy ``` @@ -20,9 +20,9 @@ country_by_continent = pd.read_json(country_by_continent_url, typ="series").to_d stations['Continent'] = stations['Country'].map(country_by_continent) -# stations['Koeppen Geiger classification'] = stations.apply(lambda x: kgcpy.lookupCZ(x['Latitude'], x['Longitude']), axis=1) -# kg_climates = {'A': 'Tropical', 'B': 'Dry', 'C': 'Temperate', 'D': 'Continental', 'E': 'Polar', 'O': 'Ocean'} -# stations['Koeppen Geiger climate zone'] = stations['Koeppen Geiger classification'].apply(lambda x: kg_climates[x[0]]) +stations['Koeppen Geiger classification'] = stations.apply(lambda x: kgcpy.lookupCZ(x['Latitude'], x['Longitude']), axis=1) +kg_climates = {'A': 'Tropical', 'B': 'Dry', 'C': 'Temperate', 'D': 'Continental', 'E': 'Polar', 'O': 'Ocean'} +stations['Koeppen Geiger climate zone'] = stations['Koeppen Geiger classification'].apply(lambda x: kg_climates[x[0]]) instrumentation = stations['Instrumentation'].str.split(';', expand=True) is_tier_1 = (instrumentation=='G').any(axis=1) & (instrumentation=='B').any(axis=1) & (instrumentation=='D').any(axis=1) diff --git a/pyproject.toml b/pyproject.toml index efef788..5a4034c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,6 @@ dependencies = [ "folium==0.20.0", "itables==2.2.2", "jupyter-book==2.1.6", - "kgcpy==1.1.8", "matplotlib==3.11.1", "numpy==2.5.1", "pandas==3.0.3", @@ -20,4 +19,5 @@ dependencies = [ "jupyter-book==2.1.6", "jupyter-book-marimo==0.0.3", "marimo", + "kgcpy==1.1.8", ] From f2183a584409e4c952f3d39159c6ac543336d800 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Fri, 28 Aug 2026 23:52:31 +0200 Subject: [PATCH 30/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 0a678d5..0ba0cd2 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -1,3 +1,11 @@ +```{marimo} python +dependencies = [ + "numpy==2.5.1", + "pandas==3.0.3", + "kgcpy==1.1.8", +] +``` + ```{marimo} python import marimo as mo import pandas as pd @@ -55,11 +63,17 @@ for c in stations.columns: if not pd.api.types.is_numeric_dtype(stations[c]): stations[c] = stations[c].replace(np.nan, '') +stations = stations.rename(columns={ + "GHI_kWh_m2": "GHI (kWh/m²)", + "DHI_kWh_m2": "DHI (kWh/m²)", + "DNI_kWh_m2": "DNI (kWh/m²)", +}) + columns_ordered = [ 'Station name', 'URL', 'Abbreviation', 'State', 'Country', 'Continent', 'Latitude', 'Longitude', 'Elevation', 'Time period', 'Network', 'Owner', 'Comment', 'Data availability', 'Instrumentation', 'Tier', - 'GHI_kWh_m2', 'DHI_kWh_m2', 'DNI_kWh_m2', + 'GHI (kWh/m²)', 'DHI (kWh/m²)', 'DNI (kWh/m²)', # 'Koeppen Geiger climate zone', ] From 41fc70ae2e4155c2f89ffc21180227fb446dcadd Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:02:42 +0200 Subject: [PATCH 31/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 35 ++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 0ba0cd2..093d40f 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -1,9 +1,32 @@ -```{marimo} python -dependencies = [ - "numpy==2.5.1", - "pandas==3.0.3", - "kgcpy==1.1.8", -] +--- +title: Station catalog +marimo-version: 0.24.0 +width: medium +auto_download: +- html +header: |- + # /// script + # requires-python = ">=3.13" + # dependencies = [ + # "kgcpy==1.1.8", + # ] + # /// + + # /// script + # requires-python = ">=3.13" + # dependencies = [ + # "kgcpy==1.1.8", + # ] + # /// +--- + +```python {.marimo} +import marimo as mo +import pandas as pd +``` + +```python {.marimo} + ``` ```{marimo} python From 9ef2bd699febc90a47b42e3c31884b04002e6d78 Mon Sep 17 00:00:00 2001 From: "Adam R. Jensen" <39184289+AdamRJensen@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:08:17 +0200 Subject: [PATCH 32/32] Update station_catalog_marimo.md --- docs/station_catalog_marimo.md | 36 +++++++++------------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/docs/station_catalog_marimo.md b/docs/station_catalog_marimo.md index 093d40f..8c8ea90 100644 --- a/docs/station_catalog_marimo.md +++ b/docs/station_catalog_marimo.md @@ -1,34 +1,16 @@ --- +pyproject: |- + requires-python = ">=3.12" + dependencies = [ + "marimo", + "pandas", + "numpy", + "kgcpy", + ] title: Station catalog -marimo-version: 0.24.0 -width: medium -auto_download: -- html -header: |- - # /// script - # requires-python = ">=3.13" - # dependencies = [ - # "kgcpy==1.1.8", - # ] - # /// - - # /// script - # requires-python = ">=3.13" - # dependencies = [ - # "kgcpy==1.1.8", - # ] - # /// +marimo-version: 0.23.13 --- -```python {.marimo} -import marimo as mo -import pandas as pd -``` - -```python {.marimo} - -``` - ```{marimo} python import marimo as mo import pandas as pd