From 694d35c23e5367e4836f87a06b447fd67c857a40 Mon Sep 17 00:00:00 2001 From: Lazaro Alonso Date: Sat, 24 Feb 2024 19:03:18 +0100 Subject: [PATCH 1/3] final_site not there, plus GeoMakie is broken due to Formatting --- .github/workflows/Documenter.yml | 2 +- .gitignore | 16 ++---- docs/make.jl | 48 +++--------------- docs/package.json | 6 +-- docs/src/.vitepress/config.mts | 7 ++- docs/src/{public => assets}/logo.png | Bin docs/src/{public => assets}/logo.svg | 0 .../{plottingmaps.md => plottingmaps.jl} | 0 8 files changed, 20 insertions(+), 59 deletions(-) rename docs/src/{public => assets}/logo.png (100%) rename docs/src/{public => assets}/logo.svg (100%) rename docs/src/tutorials/{plottingmaps.md => plottingmaps.jl} (100%) diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index 8f743c08..973fdb91 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -49,7 +49,7 @@ jobs: - name: Install documentation dependencies # for GLMakie plots run: sudo apt-get update && sudo apt-get install -y xorg-dev mesa-utils xvfb libgl1 freeglut3-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev - name: Install documentation dependencies - run: DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs -e 'using Pkg; pkg"add https://github.com/LuxDL/DocumenterVitepress.jl.git"; pkg"dev ."; pkg"add DimensionalData#main"; Pkg.instantiate(); Pkg.precompile(); Pkg.status()' + run: DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs -e 'using Pkg; pkg"dev ."; pkg"add DimensionalData#main"; Pkg.instantiate(); Pkg.precompile(); Pkg.status()' - name: Instantiate NPM run: cd docs/; npm i; cd .. #- name: Creating new mds from src diff --git a/.gitignore b/.gitignore index 42d4f85c..5a1f0de7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ Manifest.toml - +.DS_Store *.jl.cov *.jl.*.cov *.jl.mem @@ -7,26 +7,18 @@ tmp generated build .vscode -.DS_Store *.zarr *.nc var -docs/docs -docs/site -docs/build -docs/var -deps/build.jl -bonito - *.ipynb_checkpoints # Ignore the benchmarking results /benchmark/*.json .benchmarkci coverage/lcov.info -node_modules -docs/node_modules +bonito +docs/build .DS_Store docs/src/.vitepress/cache docs/src/.vitepress/dist @@ -35,4 +27,4 @@ docs/.vscode docs/node_modules docs/.vitepress/cache docs/.vitepress/dist -docs/.DS_Store +docs/.DS_Store \ No newline at end of file diff --git a/docs/make.jl b/docs/make.jl index e6fe2441..26eb58f3 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,6 +1,5 @@ using Documenter using DocumenterVitepress -# add https://github.com/LuxDL/DocumenterVitepress.jl.git # add DimensionalData#main using YAXArrays @@ -9,54 +8,21 @@ makedocs(; sitename="YAXArrays.jl", modules=[YAXArrays], warnonly = true, checkdocs=:all, - format=DocumenterVitepress.MarkdownVitepress(), + format=DocumenterVitepress.MarkdownVitepress( + repo = "github.com/JuliaDataCubes/YAXArrays.jl", # this must be the full URL! + devbranch = "master", + devurl = "dev"; + ), draft=false, source="src", - build=joinpath(@__DIR__, "build") + build= "build", ) # To edit the sidebar, you must edit `docs/src/.vitepress/config.mts`. -# We manually obtain the Documenter deploy configuration, -# so we can use it to set Vitepress's settings. -# TODO: make this better / encapsulate it in `makedocs` -# so the user does not need to know! -deploy_config = Documenter.auto_detect_deploy_system() -deploy_decision = Documenter.deploy_folder( - deploy_config; - repo="github.com/JuliaDataCubes/YAXArrays.jl.git", # this must be the full URL! - devbranch="master", - devurl = "dev", - push_preview=true, -) - -# VitePress relies on its config file in order to understand where files will exist. -# We need to modify this file to reflect the correct base URL, however, Documenter -# only knows about the base URL at the time of deployment. - -# So, after building the Markdown, we need to modify the config file to reflect the -# correct base URL, and then build the VitePress site. -folder = deploy_decision.subfolder -println("Deploying to $folder") -vitepress_config_file = joinpath(@__DIR__, "build", ".vitepress", "config.mts") -config = read(vitepress_config_file, String) -new_config = replace( - config, - "base: 'REPLACE_ME_WITH_DOCUMENTER_VITEPRESS_BASE_URL_WITH_TRAILING_SLASH'" => "base: '/YAXArrays.jl/$(folder)$(isempty(folder) ? "" : "/")'" -) -write(vitepress_config_file, new_config) - -# Build the docs using `npm` - we are assuming it's installed here! -haskey(ENV, "CI") && begin - cd(@__DIR__) do - run(`npm run docs:build`) - end - touch(joinpath(@__DIR__, "build", ".vitepress", "dist", ".nojekyll")) -end - deploydocs(; repo="github.com/JuliaDataCubes/YAXArrays.jl.git", # this must be the full URL! - target="build/.vitepress/dist", # this is where Vitepress stores its output + target="build", # this is where Vitepress stores its output branch = "gh-pages", devbranch="master", push_preview = true diff --git a/docs/package.json b/docs/package.json index 376a4f7f..f908fde5 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,8 +1,8 @@ { "scripts": { - "docs:dev": "vitepress dev build", - "docs:build": "vitepress build build", - "docs:preview": "vitepress preview build" + "docs:dev": "vitepress dev build/.documenter", + "docs:build": "vitepress build build/.documenter", + "docs:preview": "vitepress preview build/.documenter" }, "devDependencies": { "markdown-it": "^14.0.0", diff --git a/docs/src/.vitepress/config.mts b/docs/src/.vitepress/config.mts index 0108cdea..27265fdd 100644 --- a/docs/src/.vitepress/config.mts +++ b/docs/src/.vitepress/config.mts @@ -4,11 +4,12 @@ import mathjax3 from "markdown-it-mathjax3"; // https://vitepress.dev/reference/site-config export default defineConfig({ - base: 'REPLACE_ME_WITH_DOCUMENTER_VITEPRESS_BASE_URL_WITH_TRAILING_SLASH', + base: 'REPLACE_ME_DOCUMENTER_VITEPRESS', title: "YAXArrays.jl", description: "Yet another xarray-like Julia package", lastUpdated: true, cleanUrls: true, + outDir: 'REPLACE_ME_DOCUMENTER_VITEPRESS', // This is required for MarkdownVitepress to work correctly... ignoreDeadLinks: true, markdown: { @@ -93,7 +94,9 @@ export default defineConfig({ { text: 'API Reference', link: 'api' }, ]}, ], - + editLink: { + pattern: 'https://github.com/JuliaDataCubes/YAXArrays.jl/edit/master/docs/src/:path' + }, socialLinks: [ { icon: 'github', link: 'https://github.com/JuliaDataCubes/YAXArrays.jl' } ], diff --git a/docs/src/public/logo.png b/docs/src/assets/logo.png similarity index 100% rename from docs/src/public/logo.png rename to docs/src/assets/logo.png diff --git a/docs/src/public/logo.svg b/docs/src/assets/logo.svg similarity index 100% rename from docs/src/public/logo.svg rename to docs/src/assets/logo.svg diff --git a/docs/src/tutorials/plottingmaps.md b/docs/src/tutorials/plottingmaps.jl similarity index 100% rename from docs/src/tutorials/plottingmaps.md rename to docs/src/tutorials/plottingmaps.jl From 2f24ee717af844fce40b3a74c07879e9b3304cd4 Mon Sep 17 00:00:00 2001 From: Lazaro Alonso Date: Tue, 12 Mar 2024 20:39:16 +0100 Subject: [PATCH 2/3] some clean up --- .github/workflows/Documenter.yml | 2 +- Project.toml | 2 +- docs/contributors.jl | 20 ++ docs/logo.jl | 4 + docs/make.jl | 2 - docs/mkdocs.yml | 128 ----------- docs/src/.vitepress/config.mts | 15 +- docs/src/UserGuide/group_by.md | 204 ++++++++++++++++++ docs/src/contributors.md | 118 ++++++++++ docs/src/index.md | 3 +- .../{ => esdl}/examples_from_esdl_study_1.jl | 0 .../{ => esdl}/examples_from_esdl_study_2.jl | 0 .../{ => esdl}/examples_from_esdl_study_3.jl | 126 ++++++----- .../{ => esdl}/examples_from_esdl_study_4.jl | 2 +- .../{plottingmaps.jl => plottingmaps.md} | 0 15 files changed, 421 insertions(+), 205 deletions(-) create mode 100644 docs/contributors.jl create mode 100644 docs/logo.jl delete mode 100644 docs/mkdocs.yml create mode 100644 docs/src/UserGuide/group_by.md create mode 100644 docs/src/contributors.md rename docs/src/tutorials/{ => esdl}/examples_from_esdl_study_1.jl (100%) rename docs/src/tutorials/{ => esdl}/examples_from_esdl_study_2.jl (100%) rename docs/src/tutorials/{ => esdl}/examples_from_esdl_study_3.jl (50%) rename docs/src/tutorials/{ => esdl}/examples_from_esdl_study_4.jl (99%) rename docs/src/tutorials/{plottingmaps.jl => plottingmaps.md} (100%) diff --git a/.github/workflows/Documenter.yml b/.github/workflows/Documenter.yml index 973fdb91..3a16d229 100644 --- a/.github/workflows/Documenter.yml +++ b/.github/workflows/Documenter.yml @@ -49,7 +49,7 @@ jobs: - name: Install documentation dependencies # for GLMakie plots run: sudo apt-get update && sudo apt-get install -y xorg-dev mesa-utils xvfb libgl1 freeglut3-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev - name: Install documentation dependencies - run: DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs -e 'using Pkg; pkg"dev ."; pkg"add DimensionalData#main"; Pkg.instantiate(); Pkg.precompile(); Pkg.status()' + run: DISPLAY=:0 xvfb-run -s '-screen 0 1024x768x24' julia --project=docs -e 'using Pkg; pkg"dev ."; Pkg.instantiate(); Pkg.precompile(); Pkg.status()' - name: Instantiate NPM run: cd docs/; npm i; cd .. #- name: Creating new mds from src diff --git a/Project.toml b/Project.toml index 799ad28a..d4a522cd 100644 --- a/Project.toml +++ b/Project.toml @@ -34,7 +34,7 @@ YAXArrayBase = "90b8fcef-0c2d-428d-9c56-5f86629e9d14" [compat] CFTime = "0.0, 0.1" DataStructures = "0.17, 0.18" -DimensionalData = "0.24, 0.25" +DimensionalData = "0.24, 0.25, 0.26" DiskArrayTools = "0.1" DiskArrays = "0.3,0.4" DocStringExtensions = "0.8, 0.9" diff --git a/docs/contributors.jl b/docs/contributors.jl new file mode 100644 index 00000000..61effd54 --- /dev/null +++ b/docs/contributors.jl @@ -0,0 +1,20 @@ +using GitHub + +function getavatars(; n = 90) + contri = GitHub.contributors("JuliaDataCubes/YAXArrays.jl")[1] + avatars = [] + contributions = [] + urls = [] + for i in eachindex(contri) + push!(avatars, contri[i]["contributor"].avatar_url.uri) + push!(contributions, contri[i]["contributions"]) + push!(urls, contri[i]["contributor"].html_url.uri) + end + p = sortperm(contributions, rev=true) + return avatars[p], urls[p] +end + +avatars, urls = getavatars(; n = 90) +for (i,a) in enumerate(avatars) + println("""""") +end \ No newline at end of file diff --git a/docs/logo.jl b/docs/logo.jl new file mode 100644 index 00000000..75c95e71 --- /dev/null +++ b/docs/logo.jl @@ -0,0 +1,4 @@ +using GLMakie.Colors +using GLMakie +using Random +Random.seed!(13) \ No newline at end of file diff --git a/docs/make.jl b/docs/make.jl index 26eb58f3..969db09e 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,6 +1,5 @@ using Documenter using DocumenterVitepress -# add DimensionalData#main using YAXArrays makedocs(; sitename="YAXArrays.jl", @@ -17,7 +16,6 @@ makedocs(; sitename="YAXArrays.jl", source="src", build= "build", ) - # To edit the sidebar, you must edit `docs/src/.vitepress/config.mts`. deploydocs(; diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml deleted file mode 100644 index 9a8f480d..00000000 --- a/docs/mkdocs.yml +++ /dev/null @@ -1,128 +0,0 @@ -theme: - name: material - logo: assets/logo.png - features: - - content.code.copy - # - announce.dismiss - - content.code.annotate - # - content.tabs.link - #- content.tooltips - # - header.autohide - # - navigation.expand - #- navigation.indexes - # - navigation.instant - # - navigation.prune - #- navigation.sections - #- navigation.tabs - # - navigation.tabs.sticky - - navigation.top - - navigation.footer - #- navigation.tracking - - search.highlight - - search.share - - search.suggest - - toc.follow - #- toc.integrate # Table of contents is integrated on the left; does not appear separately on the right. - - header.autohide # header disappears as you scroll - palette: - # Light mode / dark mode - # We deliberately don't automatically use `media` to check a user's preferences. We default to light mode as - # (a) it looks more professional, and (b) is more obvious about the fact that it offers a (dark mode) toggle. - - scheme: default - primary: blue - accent: amber - toggle: - icon: material/lightbulb - name: Switch to dark mode - - scheme: slate - primary: black - accent: amber - toggle: - icon: material/lightbulb-outline - name: Switch to light mode - font: - text: Lato - icon: - repo: fontawesome/brands/github # GitHub logo in top right - #logo: "material/gridoff" # Equinox logo in top left - # favicon: "_static/icon_transparent.svg" - custom_dir: "_overrides" # Overriding part of the HTML - - # These additions are my own custom ones, having overridden a partial. - #twitter_name: "@lazarusAlon" - #twitter_url: "https://twitter.com/lazarusAlon" -site_name: YAXArrays -site_description: Yet Another XArray-like Julia Package -site_author: Lazaro Alonso -site_url: "" - -repo_url: https://github.com/JuliaDataCubes/YAXArrays.jl -repo_name: YAXArrays -edit_uri: "" # No edit button, as some of our pages are in /docs and some in /examples via symlink, so it's impossible for them all to be accurate - -strict: true # Don't allow warnings during the build process -extra_javascript: - # The below three make MathJax work, see https://squidfunk.github.io/mkdocs-material/reference/mathjax/ - - _static/mathjax.js - - https://polyfill.io/v3/polyfill.min.js?features=es6 - - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js - -extra_css: - - stylesheets/custom.css -extra_javascript: - - javascripts/mathjax.js - - https://polyfill.io/v3/polyfill.min.js?features=es6 - - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js - -markdown_extensions: - - admonition - - toc: - permalink: "¤" # Adds a clickable permalink to each section heading - toc_depth: 4 - - pymdownx.arithmatex: # Render LaTeX via MathJax - generic: true - - pymdownx.details # Allowing hidden expandable regions denoted by ??? - - pymdownx.highlight - - pymdownx.inlinehilite - - pymdownx.snippets - - pymdownx.superfences # Seems to enable syntax highlighting when used with the Material theme. - - pymdownx.tasklist: - custom_checkbox: true - - def_list - - pymdownx.tabbed: - alternate_style: true - - attr_list - - md_in_html -plugins: - - search # default search plugin; needs manually re-enabling when using any other plugins - - autorefs # Cross-links to headings - - include_exclude_files: - exclude: - - "_overrides" -# - mknotebooks # Jupyter notebooks - - mkdocs-video -nav: - - "Home": "index.md" - #- "User Guide": - - "Switch to DimensionalData": "examples/generated/HowdoI/switchtodimarray.md" - - "Creating YAXArrays and Datasets" : "examples/generated/UserGuide/creating.md" - - "Saving YAXArrays and Datasets" : "examples/generated/UserGuide/saving.md" - - "Setting chunks's size": "examples/generated/UserGuide/setchuncks.md" - - "Indexing and subsetting": "examples/generated/UserGuide/indexing_subsetting.md" - - "Apply functions on YAXArrays": "examples/generated/UserGuide/applyfunctions.md" - - "Generate a cube from function": "examples/generated/UserGuide/create_from_func.md" - - "Open NetCDF" : "examples/generated/UserGuide/openNetCDF.md" - - "Open Zarr (Store)" : "examples/generated/UserGuide/openZarr.md" - - "Distributed processes" : "examples/generated/UserGuide/distributed.md" - #- "Gallery": - - "Simple maps": "examples/generated/Gallery/simplemaps.md" - #- "Tutorials": - - "Tutorial": "tutorials/tutorial.md" - - "How do I ...": "examples/generated/HowdoI/howdoi.md" - #- "Examples from ESDL study 1": "examples/generated/UserGuide/examples_from_esdl_study_1.md" - #- "Examples from ESDL study 2": "examples/generated/UserGuide/examples_from_esdl_study_2.md" - #- "Examples from ESDL study 3": "examples/generated/UserGuide/examples_from_esdl_study_3.md" - #- "Examples from ESDL study 4": "examples/generated/UserGuide/examples_from_esdl_study_4.md" - - - "Contribute to docs": "examples/generated/contribute/contribute.md" - - "API" : "api.md" \ No newline at end of file diff --git a/docs/src/.vitepress/config.mts b/docs/src/.vitepress/config.mts index 27265fdd..62ca0b69 100644 --- a/docs/src/.vitepress/config.mts +++ b/docs/src/.vitepress/config.mts @@ -52,8 +52,14 @@ export default defineConfig({ { text: 'Overview', link: '/tutorials/tutorial' }, { text: 'Plotting maps', link: '/tutorials/plottingmaps' }, { text: 'Mean Seasonal Cycle', link: '/tutorials/mean_seasonal_cycle' }, - { text: 'ESDL study 3', link: '/tutorials/examples_from_esdl_study_3' }, - { text: 'ESDL study 4', link: '/tutorials/examples_from_esdl_study_4' }, + { text: 'ESDL studies', + items: [ + { text: 'ESDL study 1', link: '/tutorials/esdl/examples_from_esdl_study_1' }, + { text: 'ESDL study 2', link: '/tutorials/esdl/examples_from_esdl_study_2' }, + { text: 'ESDL study 3', link: '/tutorials/esdl/examples_from_esdl_study_3' }, + { text: 'ESDL study 4', link: '/tutorials/esdl/examples_from_esdl_study_4' }, + ] + }, ]}, { text: 'How do I?', items: [ @@ -80,15 +86,14 @@ export default defineConfig({ items: [ { text: 'Overview', link: '/tutorials/tutorial' }, { text: 'Plotting maps', link: '/tutorials/plottingmaps' }, - { text: 'Mean Seasonal Cycle', link: '/tutorials/mean_seasonal_cycle' }, - { text: 'ESDL study 3', link: '/tutorials/examples_from_esdl_study_3' }, - { text: 'ESDL study 4', link: '/tutorials/examples_from_esdl_study_4' }, + { text: 'Mean Seasonal Cycle', link: '/tutorials/mean_seasonal_cycle' } ]}, { text: 'How do I?', items: [ { text: 'How do I ...', link: '/HowdoI/howdoi' }, { text: 'Contribute to docs', link: '/HowdoI/contribute' } ]}, + { text: 'Contributors', link: '/contributors' }, { text: 'API', items: [ { text: 'API Reference', link: 'api' }, diff --git a/docs/src/UserGuide/group_by.md b/docs/src/UserGuide/group_by.md new file mode 100644 index 00000000..1eff2704 --- /dev/null +++ b/docs/src/UserGuide/group_by.md @@ -0,0 +1,204 @@ +# GroupBy + +The next examples will use the `groupby` function to calculate temporal and spatial averages. + +````@example compareXarray +using YAXArrays, DimensionalData +using NetCDF +using Downloads +using Dates +using Statistics +```` + +### Seasonal Averages from Time Series of Monthly Means + +The following reproduces the example in [xarray](https://docs.xarray.dev/en/stable/examples/monthly-means.html) by [Joe Hamman](https://github.com/jhamman/). + +Where the goal is to calculate the seasonal average. And in order to do this properly, is necessary to calculate the weighted average considering that each month has a different number of days. + +### Download the data + +````@example compareXarray +url_path = "https://github.com/pydata/xarray-data/raw/master/rasm.nc" +filename = Downloads.download(url_path, "rasm.nc") +ds_o = Cube(filename) +nothing # hide +```` + +::: warning + +The following rebuild should not be necessary in the future, plus is unpractical to use for large data sets. Support for out of memory data is not available yet. +Related to https://github.com/rafaqz/DimensionalData.jl/issues/642 + +::: + +````@example compareXarray + +axs = dims(ds_o) # get the dimensions +data = ds_o.data[:,:,:] # read the data +_FillValue = ds_o.properties["_FillValue"] +data = replace(data, _FillValue => NaN) +# create new YAXArray +ds = YAXArray(axs, data) +nothing # hide +```` + +## GroupBy: seasons + +::: details function weighted_season(ds) ... end + +````julia +function weighted_season(ds) + # calculate weights + tempo = dims(ds, :Ti) + month_length = YAXArray((tempo,), daysinmonth.(tempo)) + g_tempo = groupby(month_length, Ti => season(; start=December)) + sum_days = sum.(g_tempo, dims=:Ti) + weights = map(./, g_tempo, sum_days) + # unweighted seasons + g_ds = groupby(ds, Ti => season(; start=December)) + mean_g = mean.(g_ds, dims=:Ti) + mean_g = dropdims.(mean_g, dims=:Ti) + # weighted seasons + g_dsW = broadcast_dims.(*, weights, g_ds) + weighted_g = sum.(g_dsW, dims = :Ti); + weighted_g = dropdims.(weighted_g, dims=:Ti) + # differences + diff_g = map(.-, weighted_g, mean_g) + seasons = lookup(mean_g, :Ti) + return mean_g, weighted_g, diff_g, seasons +end +```` +::: + +Now, we continue with the `groupby` operations as usual + +````@ansi compareXarray +g_ds = groupby(ds, Ti => season(; start=December)) +```` + +And the mean per season is calculated as follows + +````@ansi compareXarray +mean_g = mean.(g_ds, dims=:Ti) +```` + +### dropdims + +Note that now the time dimension has length one, we can use `dropdims` to remove it + +````@ansi compareXarray +mean_g = dropdims.(mean_g, dims=:Ti) +```` + +### seasons + +Due to the `groupby` function we will obtain new grouping names, in this case in the time dimension: + +````@example compareXarray +seasons = lookup(mean_g, :Ti) +```` + +Next, we will weight this grouping by days/month in each group. + +## GroupBy: weight + +Create a `YAXArray` for the month length + +````@example compareXarray +tempo = dims(ds, :Ti) +month_length = YAXArray((tempo,), daysinmonth.(tempo)) +```` + +Now group it by season + +````@ansi compareXarray +g_tempo = groupby(month_length, Ti => season(; start=December)) +```` + +Get the number of days per season + +````@ansi compareXarray +sum_days = sum.(g_tempo, dims=:Ti) +```` + +### weights + +Weight the seasonal groups by `sum_days` + +````@ansi compareXarray +weights = map(./, g_tempo, sum_days) +```` + +Verify that the sum per season is 1 + +````@ansi compareXarray +sum.(weights) +```` +### weighted seasons + +Now, let's weight the seasons + +````@ansi compareXarray +g_dsW = broadcast_dims.(*, weights, g_ds) +```` + +apply a `sum` over the time dimension and drop it + +````@ansi compareXarray +weighted_g = sum.(g_dsW, dims = :Ti); +weighted_g = dropdims.(weighted_g, dims=:Ti) +```` + +Calculate the differences + +````@ansi compareXarray +diff_g = map(.-, weighted_g, mean_g) +```` + +All the previous steps are equivalent to calling the function defined at the top: + +````julia +mean_g, weighted_g, diff_g, seasons = weighted_season(ds) +```` + +Once all calculations are done we can plot the results with `Makie.jl` as follows: + +````@example compareXarray +using CairoMakie +# define plot arguments/attributes +colorrange = (-30,30) +colormap = Reverse(:Spectral) +highclip = :red +lowclip = :grey15 +cb_label = ds_o.properties["long_name"] +```` + +````@example compareXarray +with_theme(theme_ggplot2()) do + hm_o, hm_d, hm_w = nothing, nothing, nothing + # the figure + fig = Figure(; size = (850,500)) + axs = [Axis(fig[i,j], aspect=DataAspect()) for i in 1:3, j in 1:4] + for (j, s) in enumerate(seasons) + hm_o = heatmap!(axs[1,j], mean_g[Ti=At(s)]; colorrange, lowclip, highclip, colormap) + hm_w = heatmap!(axs[2,j], weighted_g[Ti=At(s)]; colorrange, lowclip, highclip, colormap) + hm_d = heatmap!(axs[3,j], diff_g[Ti=At(s)]; colorrange=(-0.1,0.1), lowclip, highclip, + colormap=:diverging_bwr_20_95_c54_n256) + end + Colorbar(fig[1:2,5], hm_o, label=cb_label) + Colorbar(fig[3,5], hm_d, label="Tair") + hidedecorations!.(axs, grid=false, ticks=false, label=false) + # some labels + [axs[1,j].title = string.(s) for (j,s) in enumerate(seasons)] + Label(fig[0,1:5], "Seasonal Surface Air Temperature", fontsize=18, font=:bold) + axs[1,1].ylabel = "Unweighted" + axs[2,1].ylabel = "Weighted" + axs[3,1].ylabel = "Difference" + colgap!(fig.layout, 5) + rowgap!(fig.layout, 5) + fig +end +```` + +which shows a good agreement with the results first published by [Joe Hamman](https://github.com/jhamman/). \ No newline at end of file diff --git a/docs/src/contributors.md b/docs/src/contributors.md new file mode 100644 index 00000000..409bb8c2 --- /dev/null +++ b/docs/src/contributors.md @@ -0,0 +1,118 @@ +```@raw html +--- +layout: page +--- + + + + + + + + + + + + + + + + +``` \ No newline at end of file diff --git a/docs/src/index.md b/docs/src/index.md index 35906a4e..a64b122e 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -27,8 +27,9 @@ features: link: /UserGuide/openZarr - title: Interoperability details: Well integrated with Julia's ecosystem, i.e., distributed operations are native. And plotting with Makie.jl is well supported. - - title: Named dimensions and GroupBy + - title: Named dimensions and GroupBy(in memory. WIP, out of memory) details: Apply operations over named dimensions, select values by labels and integers as well as efficient split-apply-combine operations with groupby via DimensionalData.jl. + link: /UserGuide/group_by - title: Efficiency details: Efficient mapslices(x) and mapCube operations on huge multiple arrays, optimized for high-latency data access (object storage, compressed datasets). ``` \ No newline at end of file diff --git a/docs/src/tutorials/examples_from_esdl_study_1.jl b/docs/src/tutorials/esdl/examples_from_esdl_study_1.jl similarity index 100% rename from docs/src/tutorials/examples_from_esdl_study_1.jl rename to docs/src/tutorials/esdl/examples_from_esdl_study_1.jl diff --git a/docs/src/tutorials/examples_from_esdl_study_2.jl b/docs/src/tutorials/esdl/examples_from_esdl_study_2.jl similarity index 100% rename from docs/src/tutorials/examples_from_esdl_study_2.jl rename to docs/src/tutorials/esdl/examples_from_esdl_study_2.jl diff --git a/docs/src/tutorials/examples_from_esdl_study_3.jl b/docs/src/tutorials/esdl/examples_from_esdl_study_3.jl similarity index 50% rename from docs/src/tutorials/examples_from_esdl_study_3.jl rename to docs/src/tutorials/esdl/examples_from_esdl_study_3.jl index 6f5e56ea..ece85930 100644 --- a/docs/src/tutorials/examples_from_esdl_study_3.jl +++ b/docs/src/tutorials/esdl/examples_from_esdl_study_3.jl @@ -1,94 +1,95 @@ -# Examples from the ESDL paper -## Earth Syst. Dynam., 11, 201–234, 2020 [doi](https://doi.org/10.5194/esd-11-201-2020) +# # Examples from the ESDL paper +# ## Earth Syst. Dynam., 11, 201–234, 2020 [doi](https://doi.org/10.5194/esd-11-201-2020) -**NOTE:** This section is based on the case studies from the paper "Earth system data cubes unravel global multivariate dynamics" by Mahecha, Gans et al. (2019), available [here](https://github.com/esa-esdl/ESDLPaperCode.jl). -- We have slightly adjusted the scripts. A few differences are that these new scripts are updated to Julia 1.9, and the YAXArrays.jl package is used. -- The dataset has been updated but it has less available variables. Therefore the results might differ. -- The calculations are performed with a very coarse spatial (2.5°) and temporal resolution (monthly). -- These are examples for illustrative purposes of the packages and do not intend any deeper scientific interpretation. For scientific analysis use the higher spatio-temporal resolution datasets. +# **NOTE:** This section is based on the case studies from the paper "Earth system data cubes unravel global multivariate dynamics" by Mahecha, Gans et al. (2019), available [here](https://github.com/esa-esdl/ESDLPaperCode.jl). +# - We have slightly adjusted the scripts. A few differences are that these new scripts are updated to Julia 1.9, and the YAXArrays.jl package is used. +# - The dataset has been updated but it has less available variables. Therefore the results might differ. +# - The calculations are performed with a very coarse spatial (2.5°) and temporal resolution (monthly). +# - These are examples for illustrative purposes of the packages and do not intend any deeper scientific interpretation. For scientific analysis use the higher spatio-temporal resolution datasets. -## Case study 3: Model-parameter estimation in the ESDL -### Example of the temperature sensitivity of ecosystem respiration +# ## Case study 3: Model-parameter estimation in the ESDL +# ### Example of the temperature sensitivity of ecosystem respiration -* Script to reproduce and understand examples in the paper *Earth system data cubes unravel global multivariate dynamics* . +# * Script to reproduce and understand examples in the paper *Earth system data cubes unravel global multivariate dynamics* . -* The code is written on Julia 1.9 and uses GeoMakie for plotting. +# * The code is written on Julia 1.9 and uses GeoMakie for plotting. -* Normal text are explanations referring to notation and equations in the paper +# * Normal text are explanations referring to notation and equations in the paper -* `# comments in the code are intended explain specific aspects of the coding` +# * `# comments in the code are intended explain specific aspects of the coding` -* ### New steps in workflows are introduced with **bold headers** +# * ### New steps in workflows are introduced with **bold headers** ## Load requiered packages using Pkg +Pkg.instantiate() ## for operating data cubes -using EarthDataLab using DimensionalData using Zarr, YAXArrays, NetCDF, DiskArrays ## other relevant packages -using Statistics, Dates, SkipNan +using Statistics, Dates -### Select and subet an Earth system data cube +# ### Select and subet an Earth system data cube -We have to choose a cube and here we select a monthly global cube of 2.5° resolution. This very low-resolution cube aims at fast processing for the safety of computational time and resources. +# We have to choose a cube and here we select a monthly global cube of 2.5° resolution. This very low-resolution cube aims at fast processing for the safety of computational time and resources. -cube_handle = esdc(res="tiny") +# using EarthDataLab +# cube_handle = esdc(res="tiny") -In this case it is better to have one cube for the Tair and one for terrestrial ecosystem respiration `R$_{eco}$`. +bucket = "esdl-esdc-v3.0.2" +store = "esdc-16d-2.5deg-46x72x1440-3.0.2.zarr" +path = "https://s3.bgc-jena.mpg.de:9000/" * bucket * "/" * store +cube_handle = Cube(open_dataset(zopen(path, consolidated=true, fill_as_missing=true))) +# In this case it is better to have one cube for the Tair and one for terrestrial ecosystem respiration `R$_{eco}$`. world_tair = cube_handle[variable = At("air_temperature_2m")] world_resp = cube_handle[variable = At("terrestrial_ecosystem_respiration")] -Find overlapping time between variables - +# Find overlapping time between variables span_starts = first(findall(i-> !ismissing(i), world_tair[:,:,:])) axtime = collect(cube_handle.axes[3]); println("Data span of `air_temperature_2m` starts on ", axtime[span_starts[3]]) -similarly +# similarly span_starts = first(findall(i-> !ismissing(i), world_resp[:,:,:])) axtime = collect(cube_handle.axes[3]); println("Data span of `terrestrial_ecosystem_respiration` starts on ", axtime[span_starts[3]]) -susbet again based on overlapping period - +# susbet again based on overlapping period world_tair = world_tair[time=2001:2015] world_resp = world_resp[time=2001:2015] -The objective is to estimate $Q_{10}$ from the decomposed time series. -For details we refere the reader to Mahecha, M.D. et al. (2010) *Global convergence -in the temperature sensitivity of respiration at ecosystem level.* Science, 329, 838-840. - -The first step is the transformation of both variables, so that the $Q_{10}$ model becomes linear and Tair the exponent: +# The objective is to estimate $Q_{10}$ from the decomposed time series. +# For details we refere the reader to Mahecha, M.D. et al. (2010) *Global convergence +# in the temperature sensitivity of respiration at ecosystem level.* Science, 329, 838-840. -Element-wise transformations using `map` are done in a lazy manner, so the -transformation will be applied only when the data is read or further processed -We forced `world_τ` output format as Float32 to assure the output data type is equal, and to avoid further incompatibilities +# The first step is the transformation of both variables, so that the $Q_{10}$ model becomes linear and Tair the exponent: +## Element-wise transformations using `map` are done in a lazy manner, so the +## transformation will be applied only when the data is read or further processed +## We forced `world_τ` output format as Float32 to assure the output data type is equal, and to avoid further incompatibilities world_τ = map(tair -> (tair - Float32(273.15+15))/10, world_tair) world_ρ = map(log, world_resp) -... and we combine them into a Data Cube again using `concatenatecubes` - +# ... and we combine them into a Data Cube again using `concatenatecubes` world_new = concatenatecubes([world_τ, world_ρ], Dim{:Variable}(["τ","ρ"])) -First we need a function for time-series filtering. Using a moving average filter is the simplest way -to decomposes a signal into fast and slow oscillations by caluclating a moving average over a window of points. -This creates a smoothed curve (slow osc.) which can be subtracted from the original signal to obtain -fast oscillations separately. We could have likewise used FFTs, SSA, EMD, or any other method for -discrete time-series decomposition. -Moving Average decomposes a signal into fast and slow oscillations -by calculating a moving average over a window of points. -This creates a smoothed curve (slow osc.) which can be subtracted from the original signal, -to obtain fast oscillations separately. +# First we need a function for time-series filtering. Using a moving average filter is the simplest way +# to decomposes a signal into fast and slow oscillations by caluclating a moving average over a window of points. +# This creates a smoothed curve (slow osc.) which can be subtracted from the original signal to obtain +# fast oscillations separately. We could have likewise used FFTs, SSA, EMD, or any other method for +# discrete time-series decomposition. +# Moving Average decomposes a signal into fast and slow oscillations +# by calculating a moving average over a window of points. +# This creates a smoothed curve (slow osc.) which can be subtracted from the original signal, +# to obtain fast oscillations separately. function movingAverage(xout, xin; windowsize = 4) Z = length(xin) @@ -104,16 +105,14 @@ function movingAverage(xout, xin; windowsize = 4) return xout end -here we define the input and output dimensions for the decomposition - +## here we define the input and output dimensions for the decomposition indims = InDims("Time") outdims = OutDims("Time", Dim{:Scale}(["Slow","Fast"])) cube_decomp = mapCube(movingAverage, world_new, indims=indims, outdims=outdims) -## For estimating the temperature sensitivities - -The classical $Q_{10}$ estimation could be realized with the following function +# ### For estimating the temperature sensitivities +## The classical $Q_{10}$ estimation could be realized with the following function function Q10direct(xout_Q10, xout_rb, xin) τ, ρ = eachcol(xin) ## solve the regression @@ -127,7 +126,7 @@ function Q10direct(xout_Q10, xout_rb, xin) xout_Q10 .= Q10 end -For the scale dependent parameter estimation, the function is a bit more complex. And the numbers in the code comment refer to the supporting online materials in Mahecha et al. (2010) +# For the scale dependent parameter estimation, the function is a bit more complex. And the numbers in the code comment refer to the supporting online materials in Mahecha et al. (2010) function Q10SCAPE(xout_Q10, xout_rb, xin) ## xin is now a 3D array with dimensions Time x Scale x Variable τ_slow = xin[:, 1, 1] @@ -154,28 +153,26 @@ function Q10SCAPE(xout_Q10, xout_rb, xin) xout_rb .= Rb_b end -### Application of these functions on the prepared cubes +# ### Application of these functions on the prepared cubes indims_q10 = InDims("Time","Var") outdims_q10 = OutDims() ## Just a single number, the first output cube outdims_rb = OutDims("Time") ## The Rb time series, the second output cube q10_direct, rb_direct = mapCube(Q10direct, world_new, indims=indims_q10, outdims=(outdims_q10, outdims_rb)) -For the SCAPE approach, the parameter estimation on the decomposed appraoch is then +# For the SCAPE approach, the parameter estimation on the decomposed appraoch is then indims_scape = InDims("Time","Scale","Var") q10_scape, rb_scape = mapCube(Q10SCAPE,cube_decomp, indims=indims_scape, outdims=(outdims_q10, outdims_rb)) -### The rest is plotting. In this example we use GeoMakie. - +# ### The rest is plotting. In this example we use GeoMakie. using CairoMakie, GeoMakie CairoMakie.activate!() -using MakieTeX using LaTeXStrings function geoplotsfx(xin, titlein, labelin, crange, cmap) fig = Figure(fontsize=19) - ax = GeoAxis(fig[1,1]; coastlines = false,lonlims=(-180, 180), latlims = (-90,90)) + ax = GeoAxis(fig[1,1]; )#coastlines = false,lonlims=(-180, 180), latlims = (-90,90)) sf = surface!(ax, -180:2.5:180, -90:2.5:90, xin; shading = false, colormap = (cmap, 1,), colorrange=crange, @@ -197,13 +194,12 @@ fig1 = geoplotsfx(q10_direct[:,:].data, "a) Confounded Parameter Estimation", la fig2 = geoplotsfx(q10_scape[:,:].data, "b) Scale Dependent Parameter Estimation", label_scape, crange, cmap) -## The following are some additional analyses, not included in the paper. -For this analysis we need to construct a new cube by concatenating a couple of previous cube outputs. -To do this, there are two important remarks; (1) the cubes' axes order must be the same in both cubes -(2) as well they both must have the same data chunking - -checking cubes axes order +# ## The following are some additional analyses, not included in the paper. +# For this analysis we need to construct a new cube by concatenating a couple of previous cube outputs. +# To do this, there are two important remarks; (1) the cubes' axes order must be the same in both cubes +# (2) as well they both must have the same data chunking +## checking cubes axes order world_tair.axes # and @@ -211,13 +207,11 @@ world_tair.axes rb_scape.axes -Now we need to sort the rb_scape axes order. Axes order must be the same for the cubes concatenation. - +# Now we need to sort the rb_scape axes order. Axes order must be the same for the cubes concatenation. data_reshaped = permutedims(rb_scape.data,(2,3,1)) rb_scape_reshaped = YAXArray(rb_scape.axes[[2,3,1]],data_reshaped) -checking cubes chunking - +# checking cubes chunking eachchunk(world_tair) diff --git a/docs/src/tutorials/examples_from_esdl_study_4.jl b/docs/src/tutorials/esdl/examples_from_esdl_study_4.jl similarity index 99% rename from docs/src/tutorials/examples_from_esdl_study_4.jl rename to docs/src/tutorials/esdl/examples_from_esdl_study_4.jl index a51f93fa..ed30b889 100644 --- a/docs/src/tutorials/examples_from_esdl_study_4.jl +++ b/docs/src/tutorials/esdl/examples_from_esdl_study_4.jl @@ -238,4 +238,4 @@ function geoplotsfx(xin, titlein, crange, cmap, df) CairoMakie.translate!(tex, 0,0,100) end return(fig) -end +end \ No newline at end of file diff --git a/docs/src/tutorials/plottingmaps.jl b/docs/src/tutorials/plottingmaps.md similarity index 100% rename from docs/src/tutorials/plottingmaps.jl rename to docs/src/tutorials/plottingmaps.md From 149dc8af19e3500268bf3f21e4f798a3fb232654 Mon Sep 17 00:00:00 2001 From: Lazaro Alonso Date: Tue, 12 Mar 2024 21:41:47 +0100 Subject: [PATCH 3/3] groupby example --- docs/src/.vitepress/config.mts | 7 +++- docs/src/.vitepress/theme/style.css | 55 ++++++++++++++++++++------- docs/src/UserGuide/group_by.md | 28 +++++++------- docs/src/components/AsideTrustees.vue | 2 +- docs/src/contributors.md | 2 +- docs/src/index.md | 2 +- 6 files changed, 63 insertions(+), 33 deletions(-) diff --git a/docs/src/.vitepress/config.mts b/docs/src/.vitepress/config.mts index 62ca0b69..ecbd8e84 100644 --- a/docs/src/.vitepress/config.mts +++ b/docs/src/.vitepress/config.mts @@ -43,6 +43,7 @@ export default defineConfig({ { text: 'Setting chunks size', link: '/UserGuide/setchuncks' }, { text: 'Apply functions on YAXArrays', link: '/UserGuide/applyfunctions' }, { text: 'Create Cube from function', link: '/UserGuide/create_cube_from_function' }, + { text: 'Group by', link: '/UserGuide/group_by' }, { text: 'Distributed computing', link: '/UserGuide/distributed' }, { text: 'Open NetCDF', link: '/UserGuide/openNetCDF' }, { text: 'Open Zarr (Store)', link: '/UserGuide/openZarr' }, @@ -64,7 +65,8 @@ export default defineConfig({ { text: 'How do I?', items: [ { text: 'How do I ...', link: '/HowdoI/howdoi' }, - { text: 'Contribute to docs', link: '/HowdoI/contribute' } + { text: 'Contribute to docs', link: '/HowdoI/contribute' }, + { text: 'Contributors', link: '/contributors' } ]}, ], @@ -78,6 +80,7 @@ export default defineConfig({ { text: 'Setting chunks size', link: '/UserGuide/setchuncks' }, { text: 'Apply functions on YAXArrays', link: '/UserGuide/applyfunctions' }, { text: 'Create Cube from function', link: '/UserGuide/create_cube_from_function' }, + { text: 'Group by', link: '/UserGuide/group_by' }, { text: 'Distributed computing', link: '/UserGuide/distributed' }, { text: 'Open NetCDF', link: '/UserGuide/openNetCDF' }, { text: 'Open Zarr (Store)', link: '/UserGuide/openZarr' }, @@ -91,7 +94,7 @@ export default defineConfig({ { text: 'How do I?', items: [ { text: 'How do I ...', link: '/HowdoI/howdoi' }, - { text: 'Contribute to docs', link: '/HowdoI/contribute' } + { text: 'Contribute to docs', link: '/HowdoI/contribute' }, ]}, { text: 'Contributors', link: '/contributors' }, { text: 'API', diff --git a/docs/src/.vitepress/theme/style.css b/docs/src/.vitepress/theme/style.css index 83967bdd..cbc881a0 100644 --- a/docs/src/.vitepress/theme/style.css +++ b/docs/src/.vitepress/theme/style.css @@ -1,26 +1,53 @@ -@import url(https://fonts.googleapis.com/css?family=Space+Mono:regular,italic,700,700italic); -@import url(https://fonts.googleapis.com/css?family=Space+Grotesk:regular,italic,700,700italic); - -/** - * Customize default theme styling by overriding CSS variables: - * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css +/* Customize default theme styling by overriding CSS variables: +https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css */ -/** - * Fonts - * -------------------------------------------------------------------------- - */ -:root { + /* Layouts */ + +/* + :root { + --vp-layout-max-width: 1440px; +} */ + +.VPHero .clip { + white-space: pre; + max-width: 500px; +} + +/* Fonts */ + +@font-face { + font-family: JuliaMono-Regular; + src: url("https://cdn.jsdelivr.net/gh/cormullion/juliamono/webfonts/JuliaMono-Regular.woff2"); +} + + :root { /* Typography */ - --vp-font-family-base: "Space Grotesk", "Inter var experimental", "Inter var", + --vp-font-family-base: "Barlow", "Inter var experimental", "Inter var", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; /* Code Snippet font */ - --vp-font-family-mono: "Space Mono", Menlo, Monaco, Consolas, "Courier New", - monospace; + --vp-font-family-mono: JuliaMono-Regular, monospace; + +} + +.mono { + /* + Disable contextual alternates (kind of like ligatures but different) in monospace, + which turns `/>` to an up arrow and `|>` (the Julia pipe symbol) to an up arrow as well. + This is pretty bad for Julia folks reading even though copy+paste retains the same text. + */ + font-feature-settings: 'calt' 0; + pre { + font-family: JuliaMono-Light; +}; +code { + font-family: JuliaMono-Light; + }; } + /** * Colors For inspiration visit diff --git a/docs/src/UserGuide/group_by.md b/docs/src/UserGuide/group_by.md index 1eff2704..b63787cb 100644 --- a/docs/src/UserGuide/group_by.md +++ b/docs/src/UserGuide/group_by.md @@ -1,6 +1,6 @@ # GroupBy -The next examples will use the `groupby` function to calculate temporal and spatial averages. +The following examples will use the `groupby` function to calculate temporal and spatial averages. ````@example compareXarray using YAXArrays, DimensionalData @@ -27,7 +27,7 @@ nothing # hide ::: warning -The following rebuild should not be necessary in the future, plus is unpractical to use for large data sets. Support for out of memory data is not available yet. +The following rebuild should not be necessary in the future, plus is unpractical to use for large data sets. Out of memory groupby currently is work in progress. Related to https://github.com/rafaqz/DimensionalData.jl/issues/642 ::: @@ -45,18 +45,18 @@ nothing # hide ## GroupBy: seasons -::: details function weighted_season(ds) ... end +::: details function weighted_seasons(ds) ... end ````julia -function weighted_season(ds) +function weighted_seasons(ds) # calculate weights tempo = dims(ds, :Ti) month_length = YAXArray((tempo,), daysinmonth.(tempo)) - g_tempo = groupby(month_length, Ti => season(; start=December)) + g_tempo = groupby(month_length, Ti => seasons(; start=December)) sum_days = sum.(g_tempo, dims=:Ti) weights = map(./, g_tempo, sum_days) # unweighted seasons - g_ds = groupby(ds, Ti => season(; start=December)) + g_ds = groupby(ds, Ti => seasons(; start=December)) mean_g = mean.(g_ds, dims=:Ti) mean_g = dropdims.(mean_g, dims=:Ti) # weighted seasons @@ -65,8 +65,8 @@ function weighted_season(ds) weighted_g = dropdims.(weighted_g, dims=:Ti) # differences diff_g = map(.-, weighted_g, mean_g) - seasons = lookup(mean_g, :Ti) - return mean_g, weighted_g, diff_g, seasons + seasons_g = lookup(mean_g, :Ti) + return mean_g, weighted_g, diff_g, seasons_g end ```` ::: @@ -74,7 +74,7 @@ end Now, we continue with the `groupby` operations as usual ````@ansi compareXarray -g_ds = groupby(ds, Ti => season(; start=December)) +g_ds = groupby(ds, Ti => seasons(; start=December)) ```` And the mean per season is calculated as follows @@ -96,7 +96,7 @@ mean_g = dropdims.(mean_g, dims=:Ti) Due to the `groupby` function we will obtain new grouping names, in this case in the time dimension: ````@example compareXarray -seasons = lookup(mean_g, :Ti) +seasons_g = lookup(mean_g, :Ti) ```` Next, we will weight this grouping by days/month in each group. @@ -113,7 +113,7 @@ month_length = YAXArray((tempo,), daysinmonth.(tempo)) Now group it by season ````@ansi compareXarray -g_tempo = groupby(month_length, Ti => season(; start=December)) +g_tempo = groupby(month_length, Ti => seasons(; start=December)) ```` Get the number of days per season @@ -159,7 +159,7 @@ diff_g = map(.-, weighted_g, mean_g) All the previous steps are equivalent to calling the function defined at the top: ````julia -mean_g, weighted_g, diff_g, seasons = weighted_season(ds) +mean_g, weighted_g, diff_g, seasons_g = weighted_seasons(ds) ```` Once all calculations are done we can plot the results with `Makie.jl` as follows: @@ -180,7 +180,7 @@ with_theme(theme_ggplot2()) do # the figure fig = Figure(; size = (850,500)) axs = [Axis(fig[i,j], aspect=DataAspect()) for i in 1:3, j in 1:4] - for (j, s) in enumerate(seasons) + for (j, s) in enumerate(seasons_g) hm_o = heatmap!(axs[1,j], mean_g[Ti=At(s)]; colorrange, lowclip, highclip, colormap) hm_w = heatmap!(axs[2,j], weighted_g[Ti=At(s)]; colorrange, lowclip, highclip, colormap) hm_d = heatmap!(axs[3,j], diff_g[Ti=At(s)]; colorrange=(-0.1,0.1), lowclip, highclip, @@ -190,7 +190,7 @@ with_theme(theme_ggplot2()) do Colorbar(fig[3,5], hm_d, label="Tair") hidedecorations!.(axs, grid=false, ticks=false, label=false) # some labels - [axs[1,j].title = string.(s) for (j,s) in enumerate(seasons)] + [axs[1,j].title = string.(s) for (j,s) in enumerate(seasons_g)] Label(fig[0,1:5], "Seasonal Surface Air Temperature", fontsize=18, font=:bold) axs[1,1].ylabel = "Unweighted" axs[2,1].ylabel = "Weighted" diff --git a/docs/src/components/AsideTrustees.vue b/docs/src/components/AsideTrustees.vue index 67989e03..836a6a86 100644 --- a/docs/src/components/AsideTrustees.vue +++ b/docs/src/components/AsideTrustees.vue @@ -1,6 +1,6 @@