From 29af9200d9bd1b4e17d6d00daba458057764e3b0 Mon Sep 17 00:00:00 2001 From: Dylan Beaudette Date: Tue, 29 Oct 2024 14:01:36 -0700 Subject: [PATCH] updates --- AQP/aqp/sketches.html | 1377 ++++++++++++++++++++++++------- AQP/aqp/sketches.qmd | 7 +- AQP/sharpshootR/monthly-WB.Rmd | 37 +- AQP/sharpshootR/monthly-WB.html | 224 ++++- 4 files changed, 1292 insertions(+), 353 deletions(-) diff --git a/AQP/aqp/sketches.html b/AQP/aqp/sketches.html index c539e43..86cdeee 100644 --- a/AQP/aqp/sketches.html +++ b/AQP/aqp/sketches.html @@ -2,12 +2,12 @@ - + - + Soil Profile Sketches +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1 - + - - + @@ -2708,7 +3176,7 @@

Soil Profile Sketches

Published
-

July 25, 2024

+

October 16, 2024

@@ -2716,8 +3184,10 @@

Soil Profile Sketches

+ +
@@ -2744,12 +3214,12 @@

Example Data

Canvas

See the SPC introduction for the basics.

-
+
explainPlotSPC(osds)
-
-
+
+
-

+

@@ -2786,10 +3256,10 @@

x

par(mar = c(0, 0, 0, 0)) # note other arguments used to improve legibility plotSPC(musick.sim, print.id = FALSE, name = NA, width = 0.4, divide.hz = FALSE, depth.axis = list(line = -4, cex = 1))
-
-
+
+
-

+

@@ -2805,10 +3275,10 @@

n

text(x = 10.5, y = 90, label = "additional space allocated by 'n = 15'", adj = 0, cex = 0.75) arrows(x0 = length(osds) + 1, x1 = 15, y0 = 100, y1 = 100, code = 3, length = 0.1)
-
-
+
+
-

+

@@ -2848,10 +3318,10 @@

add

# annotate simulations arrows(x0 = 2, x1 = 11, y0 = -15, y1 = -15, length = 0.1, code = 3) mtext('Simulation', side = 3, at = 5.5, line = -2.5, font = 2, adj = 0)
-
-
+
+
-

+

@@ -2884,10 +3354,10 @@

x.idx.offset

# annotate moist vs. dry text(x = s, y = bottoms, labels = 'M', pos = 3, font = 3, cex = 0.66) text(x = s - 0.4, y = bottoms, labels = 'D', pos = 3, font = 3, cex = 0.66)
-
-
+
+
-

+

@@ -2907,16 +3377,16 @@

y.offset

# demonstrate full y-range within figure axis(side = 4, line = -3, las = 1)
-
-
+
+
-

+

Shift each profile sketch a different amount. Transect or cross-section figures can be manually created in this way. See also scaling.factor for applying a vertical scaling to all profiles.

-
+
# manually create a nice looking set of relative elevations along a pretend landform
 .yshift <- c(0, 1, 4, 8, 15, 22, 30, 35, 40) * 5
 
@@ -2959,11 +3429,11 @@ 

y.offset

# remind ourselves that this is fake title('A Fake Diagram of Real Soils', line= -1.5)
-
-
+
+
-

-

A nice caption

+

+
A nice caption
@@ -2982,10 +3452,10 @@

max.depth

# SPC truncated at 145cm abline(h = 145, lty = 2)
-
-
+
+
-

+

@@ -3001,10 +3471,10 @@

width

# annotate horizontal space allocated to each profile abline(v = seq(0.5, length(osds) + 0.5, by = 1), lty = 2)
-
-
+
+
-

+

@@ -3014,28 +3484,28 @@

width

# too skinny, but lots of room for extra annotation plotSPC(osds, width = 0.1, cex.names = 0.66, print.id = FALSE)
-
-
+
+
-

+

# works OK without horizon designations on the right side
 plotSPC(osds, width = 0.45, cex.names = 0.66, name = NA)
-
-
+
+
-

+

# about right
 plotSPC(osds, width = 0.3, cex.names = 0.66)
-
-
+
+
-

+

@@ -3055,10 +3525,10 @@

scaling.factor

arrows(x0 = length(osds) + 1, x1 = length(osds) * 2, y0 = -15, y1 = -15, length = 0.1, code = 3) mtext('scaling.factor = 0.5', side = 3, at = 12.5, line = -2.25, font = 2, adj = 0, cex = 0.85)
-
-
+
+
-

+

@@ -3070,10 +3540,10 @@

lwd

par(mar = c(0, 0, 0, 1))
 plotSPC(osds, cex.names = 0.66, name.style = 'center-center', width = 0.3, lwd = 2, color = NA, name = NA)
-
-
+
+
-

+

@@ -3085,10 +3555,10 @@

lty

par(mar = c(0, 0, 0, 1))
 plotSPC(osds, cex.names = 0.66, name.style = 'center-center', width = 0.3, lty = 2, color = NA, name = NA)
-
-
+
+
-

+

@@ -3107,18 +3577,18 @@

color

# horizon top depth plotSPC(osds, color = 'top', col.label = 'Horizon Top Depth (cm)', cex.names = 0.66)
-
-
+
+
-

+

plotSPC(osds, color = 'value', col.label = 'Munsell Value (moist)', cex.names = 0.66)
-
-
+
+
-

+

@@ -3132,19 +3602,19 @@

color

par(mar = c(0, 0, 3, 1)) plotSPC(osds, color = 'hue_ordered', col.label = 'Munsell Value (moist)', cex.names = 0.66)
-
-
+
+
-

+

# reaction class is already an ordered factor, set in fetchOSD()
 plotSPC(osds, color = 'pH_class', col.label = 'Reaction Class', cex.names = 0.66, col.legend.cex = 0.66)
-
-
+
+
-

+

@@ -3156,10 +3626,10 @@

color

par(mar = c(0, 0, 0, 0)) plotSPC(osds, color = 'rainbowColors', cex.names = 0.66, col.legend.cex = 0.66)
-
-
+
+
-

+

@@ -3169,10 +3639,10 @@

color

horizons(osds)$gradientColors <- cr(n = nrow(osds)) plotSPC(osds, color = 'gradientColors', cex.names = 0.66, col.legend.cex = 0.66)
-
-
+
+
-

+

@@ -3188,10 +3658,10 @@

density

par(mar = c(0, 0, 0, 1)) plotSPC(osds, cex.names = 0.66, density = 'density.shading')
-
-
+
+
-

+

@@ -3231,10 +3701,10 @@

default.color

par(mar = c(0, 0, 0, 1)) plotSPC(osds, cex.names = 0.66, color = 'soil_color.NA', default.color = 'yellow')
-
-
+
+
-

+

@@ -3257,10 +3727,10 @@

name.style

plotSPC(osds, width = 0.33, cex.names = 0.9, shrink=TRUE, print.id = FALSE, plot.depth.axis=FALSE, name.style=i) mtext(text = i, at = 0.5, side=1, line=-4, cex=1, adj = 0, font = 2) }
-
-
+
+
-

+

@@ -3293,10 +3763,10 @@

label

par(mar = c(0, 0, 0, 1))
 plotSPC(osds, cex.names = 0.66, label = 'subgroup', name.style = 'center-center', width = 0.3)
 title('Subgroup Labels', line = -1)
-
-
+
+
-

+

@@ -3308,10 +3778,10 @@

hz.depths

par(mar = c(0, 0, 0, 0))
 plotSPC(osds, cex.names = 0.66, name.style = 'center-center', width = 0.3, depth.axis = FALSE, hz.depths = TRUE)
-
-
+
+
-

+

@@ -3323,10 +3793,10 @@

hz.depths.offset

par(mar = c(0, 0, 0, 0))
 plotSPC(osds, cex.names = 0.66, name.style = 'center-center', width = 0.3, depth.axis = FALSE, hz.depths = TRUE, hz.depths.offset = 0.05)
-
-
+
+
-

+

@@ -3338,10 +3808,10 @@

hz.depths.lines

par(mar = c(0, 0, 0, 0))
 plotSPC(osds, cex.names = 0.66, name.style = 'center-center', width = 0.3, depth.axis = FALSE, hz.depths = TRUE, hz.depths.offset = 0.05, hz.depths.lines = TRUE)
-
-
+
+
-

+

@@ -3353,10 +3823,10 @@

fixLabelCollisions

par(mar = c(0, 0, 0, 0))
 plotSPC(osds, cex.names = 0.66, name.style = 'center-center', width = 0.3, depth.axis = FALSE, hz.depths = TRUE, hz.depths.offset = 0.05, fixLabelCollisions = TRUE)
-
-
+
+
-

+

@@ -3368,10 +3838,10 @@

fixOverlapArgs

par(mar = c(0, 0, 0, 0))
 plotSPC(osds, cex.names = 0.66, name.style = 'center-center', width = 0.3, depth.axis = FALSE, hz.depths = TRUE, hz.depths.offset = 0.05, fixLabelCollisions = TRUE, fixOverlapArgs = list(method = 'S'))
-
-
+
+
-

+

@@ -3383,10 +3853,10 @@

alt.label and
par(mar = c(0, 0, 0, 1))
 plotSPC(osds, cex.names = 0.66, alt.label = 'tax_tempcl', width = 0.3, alt.label.col = 'white')
-
-
+
+
-

+

@@ -3425,10 +3895,10 @@

raggedBottom

site(osds)$rb <- TRUE plotSPC(osds, cex.names = 0.66, raggedBottom = 'rb', width = 0.33, name.style = 'center-center')
-
-
+
+
-

+

@@ -3436,10 +3906,10 @@

raggedBottom

site(osds)$rb <- c(TRUE, FALSE, FALSE) plotSPC(osds, cex.names = 0.66, raggedBottom = 'rb', width = 0.33, name.style = 'center-center')
-
-
+
+
-

+

@@ -3453,10 +3923,10 @@

divide.hz

# suppress printing of horizon designation
 par(mar = c(0, 0, 0, 1))
 plotSPC(osds, name = NA, name.style = 'center-center', divide.hz = FALSE, width = 0.33)
-
-
+
+
-

+

@@ -3469,10 +3939,10 @@

hz.distinctness.off
# use offset values instead of horizon designations to emphasize effect
 par(mar = c(0, 0, 0, 1))
 plotSPC(osds, cex.names = 0.66, name.style = 'center-center', width = 0.33, hz.distinctness.offset = 'hzd', name = 'hzd')
-
-
+
+
-

+

@@ -3487,10 +3957,10 @@

hz.topography.offset< par(mar = c(0, 0, 0, 1)) plotSPC(osds, cex.names = 0.66, name.style = 'center-center', width = 0.33, hz.topography.offset = 'hzto')

-
-
+
+
-

+

@@ -3505,10 +3975,10 @@

hz.boundary.lty

par(mar = c(0, 0, 0, 1)) plotSPC(osds, cex.names = 0.66, name.style = 'center-center', width = 0.33, hz.topography.offset = 'hzto', hz.boundary.lty = 'hzto.lty')
-
-
+
+
-

+

@@ -3540,10 +4010,10 @@

Depth Axis

depth.axis = list(cex = 0.75, line = -1.5, interval = 15), max.depth = 225 )
-
-
+
+
-

+

@@ -3583,10 +4053,10 @@

addBracket()

# annotate "B" horizons addBracket(.brackets, offset = - 0.45)
-
-
+
+
-

+

@@ -3612,10 +4082,10 @@

addVolumeFraction()

# interpret positive A-coordinates # as percentages addVolumeFraction(osds, colname = 'A.coord', col = 'white')
-
-
+
+
-

+

@@ -3675,16 +4145,16 @@

Sketch Metadata

labels = .depths[lastPP$plot.order], cex = 0.55 )
-
-
+
+
-

+


-

This document is based on aqp version 2.0.4.

+

This document is based on aqp version 2.1.0.

@@ -3716,9 +4186,23 @@

Sketch Metadata

icon: icon }; anchorJS.add('.anchored'); + const isCodeAnnotation = (el) => { + for (const clz of el.classList) { + if (clz.startsWith('code-annotation-')) { + return true; + } + } + return false; + } const clipboard = new window.ClipboardJS('.code-copy-button', { - target: function(trigger) { - return trigger.previousElementSibling; + text: function(trigger) { + const codeEl = trigger.previousElementSibling.cloneNode(true); + for (const childEl of codeEl.children) { + if (isCodeAnnotation(childEl)) { + childEl.remove(); + } + } + return codeEl.innerText; } }); clipboard.on('success', function(e) { @@ -3754,10 +4238,27 @@

Sketch Metadata

// clear code selection e.clearSelection(); }); - function tippyHover(el, contentFn) { + var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//); + var mailtoRegex = new RegExp(/^mailto:/); + var filterRegex = new RegExp('/' + window.location.host + '/'); + var isInternal = (href) => { + return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href); + } + // Inspect non-navigation links and adorn them if external + var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool)'); + for (var i=0; iSketch Metadata interactive: true, interactiveBorder: 10, theme: 'quarto', - placement: 'bottom-start' + placement: 'bottom-start', }; + if (contentFn) { + config.content = contentFn; + } + if (onTriggerFn) { + config.onTrigger = onTriggerFn; + } + if (onUntriggerFn) { + config.onUntrigger = onUntriggerFn; + } window.tippy(el, config); } const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]'); @@ -3780,9 +4290,245 @@

Sketch Metadata

try { href = new URL(href).hash; } catch {} const id = href.replace(/^#\/?/, ""); const note = window.document.getElementById(id); - return note.innerHTML; + if (note) { + return note.innerHTML; + } else { + return ""; + } }); } + const xrefs = window.document.querySelectorAll('a.quarto-xref'); + const processXRef = (id, note) => { + // Strip column container classes + const stripColumnClz = (el) => { + el.classList.remove("page-full", "page-columns"); + if (el.children) { + for (const child of el.children) { + stripColumnClz(child); + } + } + } + stripColumnClz(note) + if (id === null || id.startsWith('sec-')) { + // Special case sections, only their first couple elements + const container = document.createElement("div"); + if (note.children && note.children.length > 2) { + container.appendChild(note.children[0].cloneNode(true)); + for (let i = 1; i < note.children.length; i++) { + const child = note.children[i]; + if (child.tagName === "P" && child.innerText === "") { + continue; + } else { + container.appendChild(child.cloneNode(true)); + break; + } + } + if (window.Quarto?.typesetMath) { + window.Quarto.typesetMath(container); + } + return container.innerHTML + } else { + if (window.Quarto?.typesetMath) { + window.Quarto.typesetMath(note); + } + return note.innerHTML; + } + } else { + // Remove any anchor links if they are present + const anchorLink = note.querySelector('a.anchorjs-link'); + if (anchorLink) { + anchorLink.remove(); + } + if (window.Quarto?.typesetMath) { + window.Quarto.typesetMath(note); + } + // TODO in 1.5, we should make sure this works without a callout special case + if (note.classList.contains("callout")) { + return note.outerHTML; + } else { + return note.innerHTML; + } + } + } + for (var i=0; i res.text()) + .then(html => { + const parser = new DOMParser(); + const htmlDoc = parser.parseFromString(html, "text/html"); + const note = htmlDoc.getElementById(id); + if (note !== null) { + const html = processXRef(id, note); + instance.setContent(html); + } + }).finally(() => { + instance.enable(); + instance.show(); + }); + } + } else { + // See if we can fetch a full url (with no hash to target) + // This is a special case and we should probably do some content thinning / targeting + fetch(url) + .then(res => res.text()) + .then(html => { + const parser = new DOMParser(); + const htmlDoc = parser.parseFromString(html, "text/html"); + const note = htmlDoc.querySelector('main.content'); + if (note !== null) { + // This should only happen for chapter cross references + // (since there is no id in the URL) + // remove the first header + if (note.children.length > 0 && note.children[0].tagName === "HEADER") { + note.children[0].remove(); + } + const html = processXRef(null, note); + instance.setContent(html); + } + }).finally(() => { + instance.enable(); + instance.show(); + }); + } + }, function(instance) { + }); + } + let selectedAnnoteEl; + const selectorForAnnotation = ( cell, annotation) => { + let cellAttr = 'data-code-cell="' + cell + '"'; + let lineAttr = 'data-code-annotation="' + annotation + '"'; + const selector = 'span[' + cellAttr + '][' + lineAttr + ']'; + return selector; + } + const selectCodeLines = (annoteEl) => { + const doc = window.document; + const targetCell = annoteEl.getAttribute("data-target-cell"); + const targetAnnotation = annoteEl.getAttribute("data-target-annotation"); + const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation)); + const lines = annoteSpan.getAttribute("data-code-lines").split(","); + const lineIds = lines.map((line) => { + return targetCell + "-" + line; + }) + let top = null; + let height = null; + let parent = null; + if (lineIds.length > 0) { + //compute the position of the single el (top and bottom and make a div) + const el = window.document.getElementById(lineIds[0]); + top = el.offsetTop; + height = el.offsetHeight; + parent = el.parentElement.parentElement; + if (lineIds.length > 1) { + const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]); + const bottom = lastEl.offsetTop + lastEl.offsetHeight; + height = bottom - top; + } + if (top !== null && height !== null && parent !== null) { + // cook up a div (if necessary) and position it + let div = window.document.getElementById("code-annotation-line-highlight"); + if (div === null) { + div = window.document.createElement("div"); + div.setAttribute("id", "code-annotation-line-highlight"); + div.style.position = 'absolute'; + parent.appendChild(div); + } + div.style.top = top - 2 + "px"; + div.style.height = height + 4 + "px"; + div.style.left = 0; + let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter"); + if (gutterDiv === null) { + gutterDiv = window.document.createElement("div"); + gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter"); + gutterDiv.style.position = 'absolute'; + const codeCell = window.document.getElementById(targetCell); + const gutter = codeCell.querySelector('.code-annotation-gutter'); + gutter.appendChild(gutterDiv); + } + gutterDiv.style.top = top - 2 + "px"; + gutterDiv.style.height = height + 4 + "px"; + } + selectedAnnoteEl = annoteEl; + } + }; + const unselectCodeLines = () => { + const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"]; + elementsIds.forEach((elId) => { + const div = window.document.getElementById(elId); + if (div) { + div.remove(); + } + }); + selectedAnnoteEl = undefined; + }; + // Handle positioning of the toggle + window.addEventListener( + "resize", + throttle(() => { + elRect = undefined; + if (selectedAnnoteEl) { + selectCodeLines(selectedAnnoteEl); + } + }, 10) + ); + function throttle(fn, ms) { + let throttle = false; + let timer; + return (...args) => { + if(!throttle) { // first call gets through + fn.apply(this, args); + throttle = true; + } else { // all the others get throttled + if(timer) clearTimeout(timer); // cancel #2 + timer = setTimeout(() => { + fn.apply(this, args); + timer = throttle = false; + }, ms); + } + }; + } + // Attach click handler to the DT + const annoteDls = window.document.querySelectorAll('dt[data-target-cell]'); + for (const annoteDlNode of annoteDls) { + annoteDlNode.addEventListener('click', (event) => { + const clickedEl = event.target; + if (clickedEl !== selectedAnnoteEl) { + unselectCodeLines(); + const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active'); + if (activeEl) { + activeEl.classList.remove('code-annotation-active'); + } + selectCodeLines(clickedEl); + clickedEl.classList.add('code-annotation-active'); + } else { + // Unselect the line + unselectCodeLines(); + clickedEl.classList.remove('code-annotation-active'); + } + }); + } const findCites = (el) => { const parentEl = el.parentElement; if (parentEl) { @@ -3826,4 +4572,5 @@

Sketch Metadata

+ \ No newline at end of file diff --git a/AQP/aqp/sketches.qmd b/AQP/aqp/sketches.qmd index d5d2280..b87aa4d 100644 --- a/AQP/aqp/sketches.qmd +++ b/AQP/aqp/sketches.qmd @@ -28,12 +28,17 @@ format: #| warning = FALSE library(knitr, quietly=TRUE) + +# ugh, looks like a recent bug in quarto + pandoc + svglite +# https://github.com/quarto-dev/quarto-cli/issues/7369 +# will need to wait for the next RStudio release + opts_chunk$set( message = FALSE, warning = FALSE, background = '#F7F7F7', fig.align = 'center', - dev = 'svglite', + dev = 'png', tidy = FALSE, verbose = FALSE ) diff --git a/AQP/sharpshootR/monthly-WB.Rmd b/AQP/sharpshootR/monthly-WB.Rmd index d16fc8e..3c2e715 100644 --- a/AQP/sharpshootR/monthly-WB.Rmd +++ b/AQP/sharpshootR/monthly-WB.Rmd @@ -13,7 +13,7 @@ output: ```{r setup, echo=FALSE, results='hide', warning=FALSE} # setup library(knitr, quietly=TRUE) -opts_chunk$set(message=FALSE, warning=FALSE, background='#F7F7F7', fig.align='center', dev='svglite', tidy=FALSE, verbose=FALSE) +opts_chunk$set(message=FALSE, warning=FALSE, background='#F7F7F7', fig.align='center', dev='png', tidy=FALSE, verbose=FALSE) options(width=100, stringsAsFactors=FALSE, cache=TRUE) ``` @@ -72,7 +72,7 @@ wb.sil <- monthlyWB(AWC.sil, PPT, PET, S_init = 0, starting_month = 1, rep = 5, All values are mm. U: surplus, S: soil water storage, ET: actual ET, D: deficit. ```{r} -kable(wb.sil, digits = 2, row.names = FALSE) +knitr::kable(wb.sil, digits = 2, row.names = FALSE) ``` @@ -286,33 +286,46 @@ GROUP BY chorizon.cokey;", x s <- site(osd$SPC) txt <- sprintf("%s\n%s", s$id, s$family) title(txt, line = 3, cex.main = 1) + + return(x.wb) } ``` ```{r fig.width=14, fig.height=12} # custom margins / multi-figure -par(mar=c(4,4,5,1), bg = 'white', mfrow = c(2, 2)) +par(mar = c(4, 4, 5, 1), bg = 'white', mfrow = c(2, 2)) # iterate over these soil series names soils <- c('amador', 'lucy', 'drummer', 'pierre') -for(i in soils) { - # adjust ylim manually - compareMonthlyWB(i, ylim = c(-250, 180)) -} +res <- lapply(soils, compareMonthlyWB, ylim = c(-250, 180)) +``` + +Experimental: summarize water balance results. +```{r} +res <- do.call('rbind', lapply(res, monthlyWB_summary)) +res$series <- soils + +knitr::kable(res, digits = 2) ``` + + ```{r fig.width=14, fig.height=12} # custom margins / multi-figure -par(mar=c(4,4,5,1), bg = 'white', mfrow = c(2, 2)) +par(mar = c(4, 4, 5, 1), bg = 'white', mfrow = c(2, 2)) # iterate over these soil series names soils <- c('leon', 'tristan', 'miami', 'freznik') -for(i in soils) { - # adjust ylim manually - compareMonthlyWB(i, ylim = c(-180, 190)) -} +res <- lapply(soils, compareMonthlyWB, ylim = c(-180, 190)) ``` +Experimental: summarize water balance results. +```{r} +res <- do.call('rbind', lapply(res, monthlyWB_summary)) +res$series <- soils + +knitr::kable(res, digits = 2) +``` ---------------------------- This document is based on `sharpshootR` version `r utils::packageDescription("sharpshootR", field="Version")` and `soilDB` version `r utils::packageDescription("soilDB", field="Version")`. diff --git a/AQP/sharpshootR/monthly-WB.html b/AQP/sharpshootR/monthly-WB.html index 1dfa3f0..0b0c2f8 100644 --- a/AQP/sharpshootR/monthly-WB.html +++ b/AQP/sharpshootR/monthly-WB.html @@ -11,7 +11,7 @@ - + A Simple Monthly Water Balance Simulation @@ -354,7 +354,7 @@

A Simple Monthly Water Balance Simulation

D.E. Beaudette and J.M. Skovlin

-

2024-03-20

+

2024-10-29

@@ -439,7 +439,7 @@

Simple Example

wb.sil <- monthlyWB(AWC.sil, PPT, PET, S_init = 0, starting_month = 1, rep = 5, keep_last = TRUE, distribute = TRUE)

All values are mm. U: surplus, S: soil water storage, ET: actual ET, D: deficit.

-
kable(wb.sil, digits = 2, row.names = FALSE)
+
knitr::kable(wb.sil, digits = 2, row.names = FALSE)
@@ -596,7 +596,7 @@

Simple Example

plotWB(WB = wb.sil, legend.cex = 0.75) title('50cm of silt loam texture soil material', line = 3) -

+

# compare
 par(mar=c(4,4,4,1), bg = 'white', mfcol = c(1, 2))
 plotWB_lines(WB = wb.sl)
@@ -604,7 +604,7 @@ 

Simple Example

plotWB_lines(WB = wb.sil) title('50cm of silt loam texture soil material', line = 3)
-

+

Distributing Monthly Values

As of sharpshootR 2.2, it is possible to “distribute” monthly data @@ -621,7 +621,7 @@

Distributing Monthly Values

plotWB(WB = wb.sl2, legend.cex = 0.75) title('50cm of silt loam texture soil material\nEqual Distribution, 10 bins', line = 1.5) -

+

This time, test the effects of using ‘equal’ vs. ‘random’ distribution of monthly PPT and PET into 10 bins per month.

wb.sl1 <- monthlyWB(AWC.sil, PPT, PET, S_init = 0, starting_month = 1, rep = 1, distribute = TRUE, k = 10, method = 'equal')
@@ -633,7 +633,7 @@ 

Distributing Monthly Values

plotWB(WB = wb.sl2, legend.cex = 0.75) title('50cm of silt loam texture soil material\nRandom Distribution, 10 bins', line = 1.5)
-

+

@@ -675,10 +675,10 @@

Real Data

# last iteration x.wb <- monthlyWB(AWC, PPT, PET, S_init = 0, starting_month = 9, rep = 3, keep_last = TRUE, distribute = TRUE) plotWB(WB = x.wb) -

+

# convert total ETa into inches
 sum(x.wb$ET) * 0.03937
-
## [1] 9.246288
+
## [1] 9.265973

Calendar year.

# tighter margins
 par(mar=c(4,4,2,1), bg = 'white')
@@ -687,7 +687,7 @@ 

Real Data

# last iteration x.wb <- monthlyWB(AWC, PPT, PET, S_init = 0, starting_month = 1, rep = 3, keep_last = TRUE, distribute = TRUE) plotWB(WB = x.wb)
-

+

Bar vs. Line Graph

s <- 'auburn'
@@ -728,7 +728,7 @@ 

Bar vs. Line Graph

plotWB_lines(x.wb) title(sprintf('Monthly Water Balance: %s Series', toupper(s)), line = 2)
-

+

@@ -777,30 +777,204 @@

Comparisons

s <- site(osd$SPC) txt <- sprintf("%s\n%s", s$id, s$family) title(txt, line = 3, cex.main = 1) + + return(x.wb) }
# custom margins / multi-figure
-par(mar=c(4,4,5,1), bg = 'white', mfrow = c(2, 2))
+par(mar = c(4, 4, 5, 1), bg = 'white', mfrow = c(2, 2))
 
 # iterate over these soil series names
 soils <- c('amador', 'lucy', 'drummer', 'pierre')
-for(i in soils) {
-  # adjust ylim manually
-  compareMonthlyWB(i, ylim = c(-250, 180))
-}
-

+res <- lapply(soils, compareMonthlyWB, ylim = c(-250, 180)) +

+

Experimental: summarize water balance results.

+
res <- do.call('rbind', lapply(res, monthlyWB_summary))
+res$series <- soils
+
+knitr::kable(res, digits = 2)
+
+++++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
drymoistwetdry_conmoist_conwet_contotal_deficittotal_surplustotal_AETannual_AET_PET_ratioseries
61183122619191-618.64225.14235.360.28amador
01831830183122-121.66434.66833.340.87lucy
01522130152152-65.11335.11633.890.91drummer
030461024461-223.5625.56407.440.65pierre
# custom margins / multi-figure
-par(mar=c(4,4,5,1), bg = 'white', mfrow = c(2, 2))
+par(mar = c(4, 4, 5, 1), bg = 'white', mfrow = c(2, 2))
 
 # iterate over these soil series names
 soils <- c('leon', 'tristan', 'miami', 'freznik')
-for(i in soils) {
-  # adjust ylim manually
-  compareMonthlyWB(i, ylim = c(-180, 190))
-}
-

+res <- lapply(soils, compareMonthlyWB, ylim = c(-180, 190)) +

+

Experimental: summarize water balance results.

+
res <- do.call('rbind', lapply(res, monthlyWB_summary))
+res$series <- soils
+
+knitr::kable(res, digits = 2)
+ +++++++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
drymoistwetdry_conmoist_conwet_contotal_deficittotal_surplustotal_AETannual_AET_PET_ratioseries
01222440122122-40.21350.21973.790.96leon
0244122024491-391.10197.10205.900.34tristan
01522130152152-68.19417.19626.810.90miami
027491027491-302.9744.97235.030.44freznik

-

This document is based on sharpshootR version 2.2 and -soilDB version 2.8.1.

+

This document is based on sharpshootR version 2.3.1 and +soilDB version 2.8.5.