| Title: | Asymmetric Smoothed-Association Matrices via GAM Fits |
|---|---|
| Description: | Render a pairwise, asymmetric smoothed-association matrix of continuous variables. Each cell shows the fitted spline from an 'mgcv' generalised additive model, with the upper triangle displaying 'gam(x_j ~ s(x_i))' and the lower triangle 'gam(x_i ~ s(x_j))'. Unlike Pearson's correlation matrix, the visualisation is intentionally asymmetric, revealing heteroscedasticity, leverage, and directional non-linearity that a single scalar correlation hides. An asymmetry index and a 24-category shape taxonomy quantify the directional difference and qualitative form of each fitted smooth. |
| Authors: | Max Moldovan [aut, cre, cph] (ORCID: <https://orcid.org/0000-0001-9680-8474>) |
| Maintainer: | Max Moldovan <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.1.1 |
| Built: | 2026-07-02 21:31:09 UTC |
| Source: | https://github.com/cran/janusplot |
Render a pairwise, asymmetric matrix of smoothed associations between
numeric variables. Each cell [i, j] where i != j shows the fitted
spline from mgcv::gam():
Upper triangle (i < j): gam(x_j ~ s(x_i) + <adjust>).
Lower triangle (i > j): gam(x_i ~ s(x_j) + <adjust>).
Diagonal: blank panel when labels live on the border (default),
or a variable-name label when labels = "diagonal".
The two triangles intentionally differ — the asymmetry reveals heteroscedasticity, leverage, and directional non-linearity that a single scalar correlation hides.
janusplot( data, vars = NULL, adjust = NULL, method = NULL, k = -1L, bs = "tp", engine = c("bam", "gam"), discrete = FALSE, nthreads = 1L, order = c("original", "hclust", "alphabetical"), show_data = TRUE, show_ci = TRUE, display = c("fit", "d1", "d2"), derivative_ci = c("none", "pointwise", "simultaneous"), derivative_ci_nsim = 1000L, n_grid = NULL, colour_by = c("pearson", "spearman", "kendall", "edf", "deviance_gap", "none"), fill_by = NULL, palette = NULL, annotations = c("edf", "A"), shape_cutoffs = janusplot_shape_cutoffs(), show_shape_legend = TRUE, glyph_style = c("ascii", "unicode"), labels = c("border", "diagonal", "none"), diagonal = c("auto", "blank", "name", "density"), label_srt = 45, label_cex = 1, signif_glyph = TRUE, show_asymmetry = NULL, na_action = c("pairwise", "complete"), parallel = FALSE, with_data = FALSE, text_scale_diag = 1, text_scale_off_diag = 1, show_glossary = TRUE, glossary_scale = 1, k_check_thresholds = NULL, auto_refit_k = FALSE, k_max_iter = 2L, compact = c("auto", "always", "never"), compact_threshold = 12L, compact_levels = NULL, focus_by = NA_character_, focus_threshold = "q90", focus_dim_alpha = 0.25, axes = c("original", "standardised", "centred", "rank"), save_as = NULL, save_width = NULL, save_height = NULL, save_dpi = 300, ... )janusplot( data, vars = NULL, adjust = NULL, method = NULL, k = -1L, bs = "tp", engine = c("bam", "gam"), discrete = FALSE, nthreads = 1L, order = c("original", "hclust", "alphabetical"), show_data = TRUE, show_ci = TRUE, display = c("fit", "d1", "d2"), derivative_ci = c("none", "pointwise", "simultaneous"), derivative_ci_nsim = 1000L, n_grid = NULL, colour_by = c("pearson", "spearman", "kendall", "edf", "deviance_gap", "none"), fill_by = NULL, palette = NULL, annotations = c("edf", "A"), shape_cutoffs = janusplot_shape_cutoffs(), show_shape_legend = TRUE, glyph_style = c("ascii", "unicode"), labels = c("border", "diagonal", "none"), diagonal = c("auto", "blank", "name", "density"), label_srt = 45, label_cex = 1, signif_glyph = TRUE, show_asymmetry = NULL, na_action = c("pairwise", "complete"), parallel = FALSE, with_data = FALSE, text_scale_diag = 1, text_scale_off_diag = 1, show_glossary = TRUE, glossary_scale = 1, k_check_thresholds = NULL, auto_refit_k = FALSE, k_max_iter = 2L, compact = c("auto", "always", "never"), compact_threshold = 12L, compact_levels = NULL, focus_by = NA_character_, focus_threshold = "q90", focus_dim_alpha = 0.25, axes = c("original", "standardised", "centred", "rank"), save_as = NULL, save_width = NULL, save_height = NULL, save_dpi = 300, ... )
data |
A data frame with numeric columns to include. |
vars |
Character vector of column names to use. |
adjust |
A one-sided formula RHS giving additional covariates
and/or random effects to include in every pairwise GAM. For example,
|
method |
Smoothing-parameter estimation method passed to
the chosen fitting backend. Default |
k |
Integer, or named list mapping variable names to integers.
Basis dimension for |
bs |
Basis type for |
engine |
One of
|
discrete |
Logical. |
nthreads |
Integer. |
order |
One of |
show_data |
Logical. If |
show_ci |
Logical. If |
display |
One of
A single matrix shows a single quantity by design: stacked
multi-panel cells crowd the matrix at any realistic variable
count. To compare fit against derivative, render two or three
Orders |
derivative_ci |
One of
|
derivative_ci_nsim |
Integer. Number of Monte Carlo samples
used when |
n_grid |
Integer or |
colour_by |
One of |
fill_by |
Deprecated alias for |
palette |
Character. Colour palette for the cell fill scale.
Defaults to |
annotations |
Character vector, a subset of
Default |
shape_cutoffs |
Named list of classification thresholds used to
map the continuous shape indices into discrete |
show_shape_legend |
Logical. If |
glyph_style |
One of |
labels |
One of
|
diagonal |
One of
|
label_srt |
Numeric. Rotation (degrees) of top labels when
|
label_cex |
Positive numeric multiplier on the border-label
font size. Default |
signif_glyph |
Logical. If |
show_asymmetry |
Deprecated. Use |
na_action |
One of |
parallel |
Logical. If |
with_data |
Logical. If |
text_scale_diag |
Positive numeric multiplier applied to the
diagonal variable-name labels. Default |
text_scale_off_diag |
Positive numeric multiplier applied to
all off-diagonal annotations ( |
show_glossary |
Logical. If |
glossary_scale |
Positive numeric multiplier on the glossary
caption font size. Default |
k_check_thresholds |
Named list giving the three flag-criterion
thresholds used by |
auto_refit_k |
Logical. If |
k_max_iter |
Integer. Maximum number of doublings allowed
per cell when |
compact |
One of
|
compact_threshold |
Integer. The |
compact_levels |
Optional named list with entries |
focus_by |
One of |
focus_threshold |
Either a quantile-string like |
focus_dim_alpha |
Numeric in |
axes |
One of
At compact tier 3 ( |
save_as |
Optional file path with extension. When set,
the final assembled plot is written to this path via
|
save_width |
Numeric. Override width (inches) for
|
save_height |
Numeric. Override height (inches) for
|
save_dpi |
Integer. Raster DPI for |
... |
Additional arguments passed to |
If with_data = FALSE (default), a ggplot2::ggplot object
(via patchwork::wrap_plots()) carrying a top-of-matrix title
that names the displayed quantity ("Direct fit",
"First derivative f'", or "Second derivative f''"). If
with_data = TRUE, a list with two elements: plot (the
ggplot) and data (a tidy table with columns var_x, var_y,
position, n_used, edf, pvalue, signif, dev_exp,
asymmetry_index, cor_pearson, cor_spearman,
cor_kendall, tie_ratio, monotonicity_index,
convexity_index, n_turning_points, n_inflections,
flat_range_ratio, shape_category, colour_value,
display, one row per off-diagonal cell). The display
column tags which quantity the call rendered, so separate
calls for fit / d1 / d2 yield comparable, stackable tables.
Derivative curves themselves (grid of , fitted
, SE) live on janusplot_data() — see there.
janusplot_data() for the raw per-cell fits + metrics.
Other smooth-associations:
janusplot_data()
# Minimal runnable example — 3 variables, 6 asymmetric pairwise GAM fits. janusplot(mtcars[, c("mpg", "hp", "wt")]) # Heteroscedastic DGP: Pearson r is ~ 0.9 but the inverse fit is # clearly non-linear, yielding asymmetry index > 0.5. set.seed(2026L) n <- 200L x1 <- stats::runif(n, 0, 10) x2 <- x1 + stats::rnorm(n, sd = 0.2 * x1) janusplot(data.frame(x1 = x1, x2 = x2, x3 = stats::rnorm(n))) # A single matrix renders a single quantity. To compare the fit # against its derivatives, render three calls and place them # side-by-side; each call's title makes the quantity explicit. set.seed(2026L) xs <- stats::runif(300L, -3, 3) df <- data.frame( x = xs, y1 = sin(xs) + stats::rnorm(300L, sd = 0.3), y2 = xs^2 + stats::rnorm(300L, sd = 0.6) ) janusplot(df, display = "fit") janusplot(df, display = "d1") janusplot(df, display = "d2") # Simultaneous CI bands on a derivative panel, per Simpson (2018). janusplot(df, display = "d1", derivative_ci = "simultaneous")# Minimal runnable example — 3 variables, 6 asymmetric pairwise GAM fits. janusplot(mtcars[, c("mpg", "hp", "wt")]) # Heteroscedastic DGP: Pearson r is ~ 0.9 but the inverse fit is # clearly non-linear, yielding asymmetry index > 0.5. set.seed(2026L) n <- 200L x1 <- stats::runif(n, 0, 10) x2 <- x1 + stats::rnorm(n, sd = 0.2 * x1) janusplot(data.frame(x1 = x1, x2 = x2, x3 = stats::rnorm(n))) # A single matrix renders a single quantity. To compare the fit # against its derivatives, render three calls and place them # side-by-side; each call's title makes the quantity explicit. set.seed(2026L) xs <- stats::runif(300L, -3, 3) df <- data.frame( x = xs, y1 = sin(xs) + stats::rnorm(300L, sd = 0.3), y2 = xs^2 + stats::rnorm(300L, sd = 0.6) ) janusplot(df, display = "fit") janusplot(df, display = "d1") janusplot(df, display = "d2") # Simultaneous CI bands on a derivative panel, per Simpson (2018). janusplot(df, display = "d1", derivative_ci = "simultaneous")
Companion to janusplot() returning the raw list of GAM fits plus
per-cell metrics (EDF, F-test p-value, deviance explained, asymmetry
index, pairwise correlations, shape descriptors) without constructing
the ggplot. Useful for custom rendering or downstream analysis.
janusplot_data( data, vars = NULL, adjust = NULL, method = NULL, k = -1L, bs = "tp", na_action = c("pairwise", "complete"), parallel = FALSE, keep_fits = FALSE, derivatives = integer(), derivative_ci = c("pointwise", "none", "simultaneous"), derivative_ci_nsim = 1000L, n_grid = NULL, shape_cutoffs = janusplot_shape_cutoffs(), k_check_thresholds = NULL, auto_refit_k = FALSE, k_max_iter = 2L, engine = c("bam", "gam"), discrete = FALSE, nthreads = 1L, ... )janusplot_data( data, vars = NULL, adjust = NULL, method = NULL, k = -1L, bs = "tp", na_action = c("pairwise", "complete"), parallel = FALSE, keep_fits = FALSE, derivatives = integer(), derivative_ci = c("pointwise", "none", "simultaneous"), derivative_ci_nsim = 1000L, n_grid = NULL, shape_cutoffs = janusplot_shape_cutoffs(), k_check_thresholds = NULL, auto_refit_k = FALSE, k_max_iter = 2L, engine = c("bam", "gam"), discrete = FALSE, nthreads = 1L, ... )
data |
A data frame with numeric columns to include. |
vars |
Character vector of column names to use. |
adjust |
A one-sided formula RHS giving additional covariates
and/or random effects to include in every pairwise GAM. For example,
|
method |
Smoothing-parameter estimation method passed to
the chosen fitting backend. Default |
k |
Integer, or named list mapping variable names to integers.
Basis dimension for |
bs |
Basis type for |
na_action |
One of |
parallel |
Logical. If |
keep_fits |
Logical. If |
derivatives |
Integer vector of derivative orders to compute
on every pair (subset of |
derivative_ci |
One of
|
derivative_ci_nsim |
Integer. Number of Monte Carlo samples
used when |
n_grid |
Integer or |
shape_cutoffs |
Named list of classification thresholds used to
map the continuous shape indices ( |
k_check_thresholds |
Named list giving the three flag-criterion
thresholds used by |
auto_refit_k |
Logical. If |
k_max_iter |
Integer. Maximum number of doublings allowed
per cell when |
engine |
One of
|
discrete |
Logical. |
nthreads |
Integer. |
... |
Additional arguments passed to |
A list with components:
varsCharacter vector of variables used, in plotted order.
pairsList of per-pair results. Each element has i, j,
var_i, var_j, fit_yx, fit_xy (NULL if keep_fits = FALSE),
pred_yx, pred_xy (data frames with x, fit, se, lo,
hi), edf_yx, edf_xy, pvalue_yx, pvalue_xy, dev_exp_yx,
dev_exp_xy, n_used, asymmetry_index, plus Pearson /
Spearman / Kendall correlations (cor_pearson, cor_spearman,
cor_kendall), the maximum tie ratio across x and y
(tie_ratio), and per-direction shape descriptors
(monotonicity_index_yx, convexity_index_yx,
monotonicity_index_xy, convexity_index_xy,
n_turning_yx, n_inflect_yx, n_turning_xy,
n_inflect_xy, shape_yx, shape_xy).
When derivatives is non-empty, each pair additionally
carries deriv_yx and deriv_xy, each a named list keyed by
order ("1", "2") whose entries are data frames with
columns x, fit, se, lo, hi, ci_type matching the
schema of pred_yx / pred_xy. The ci_type column records
whether the lo / hi columns are "pointwise" (default),
"simultaneous" (Ruppert–Wand–Carroll / Simpson 2018
critical-multiplier bands), or "none". When
derivative_ci = "simultaneous", each derivative frame also
carries a "crit_multiplier" attribute giving the MC-derived
critical multiplier used.
See janusplot_shape_metrics() for the definition of the
monotonicity and convexity indices.
callMatch call.
janusplot() for the ggplot front-end,
janusplot_shape_metrics() for the shape-metric primitives.
Other smooth-associations:
janusplot()
# Per-pair fits + metrics on a small mtcars slice out <- janusplot_data(mtcars[, c("mpg", "hp", "wt")]) out$pairs[[1L]]$asymmetry_index out$pairs[[1L]]$cor_spearman out$pairs[[1L]]$shape_yx# Per-pair fits + metrics on a small mtcars slice out <- janusplot_data(mtcars[, c("mpg", "hp", "wt")]) out$pairs[[1L]]$asymmetry_index out$pairs[[1L]]$cor_spearman out$pairs[[1L]]$shape_yx
shape_category classificationReturns the named list of thresholds used to map the continuous
monotonicity (M) and convexity (C) indices (plus inflection
counts) into a discrete shape_category. Expose so callers can
override individual thresholds or pass a fully custom list to
janusplot() / janusplot_shape_metrics().
janusplot_shape_cutoffs(...)janusplot_shape_cutoffs(...)
... |
Optional named overrides to merge into the defaults. |
A named list with numeric thresholds:
mono_strong|M| threshold for a strictly monotone smooth (default 0.9).
mono_mod|M| threshold for a curved-but-monotone smooth (default 0.5).
mono_nonmono|M| below this is considered non-monotone (default 0.3).
mono_s|M| threshold for labelling an S-shape (default 0.5).
curv_low|C| below this is considered near-linear curvature (default 0.2).
curv_mod|C| threshold for a clearly curved monotone (default 0.5).
curv_strong|C| threshold for a U-shape / inverted-U shape
(default 0.5).
flatrange(fit) / sd(y) below this is called flat (default 0.05).
Other shape-metrics:
janusplot_shape_hierarchy(),
janusplot_shape_metrics()
janusplot_shape_cutoffs() janusplot_shape_cutoffs(curv_mod = 0.6, flat = 0.02)janusplot_shape_cutoffs() janusplot_shape_cutoffs(curv_mod = 0.6, flat = 0.02)
Return the full janusplot shape taxonomy as a data frame with four
hierarchy columns plus presentation fields. The taxonomy is the
single source of truth consumed by the classifier, the cell
renderer, the legend plate, and the janusplot_data() output.
Hierarchy columns (finest → coarsest):
category24-way fine label (linear_up, skewed_peak,
bimodal, …). Computed per cell by janusplot().
codeUnique two-letter ASCII shorthand (safe on any
font or typesetting pipeline) — e.g. lu for linear_up.
archetypeSeven-family grouping: monotone_linear,
monotone_curved, unimodal, wave, multimodal,
chaotic, degenerate.
monotonicThree-way coarse classification: monotone
/ non_monotone / degenerate.
linearBinary: linear / non_linear /
degenerate.
The broader tiers (linear/non-linear, monotone/non-monotone) are
textbook calculus; the archetype layer maps cleanly to
shape-constrained regression vocabulary (Pya & Wood 2015;
Meyer 2008) and to dose-response shape categories (Calabrese
2008; Calabrese & Baldwin 2001). The (T, I) dispatch
underlying each fine category is a coarsened Morse-theoretic
critical-point classification (Milnor 1963).
janusplot_shape_hierarchy()janusplot_shape_hierarchy()
A data frame with 24 rows and columns category,
code, archetype, monotonic, linear, glyph, ascii,
label, gloss.
Calabrese, E. J. (2008). Hormesis: why it is important to toxicology and toxicologists. Environmental Toxicology and Chemistry, 27(7), 1451–1474.
Meyer, M. C. (2008). Inference using shape-restricted regression splines. Annals of Applied Statistics, 2(3), 1013–1033.
Milnor, J. (1963). Morse Theory. Princeton University Press.
Pya, N., & Wood, S. N. (2015). Shape constrained additive models. Statistics and Computing, 25(3), 543–559.
Other shape-metrics:
janusplot_shape_cutoffs(),
janusplot_shape_metrics()
tax <- janusplot_shape_hierarchy() head(tax[, c("category", "code", "archetype", "monotonic", "linear")]) # Count how many categories live in each archetype table(tax$archetype)tax <- janusplot_shape_hierarchy() head(tax[, c("category", "code", "archetype", "monotonic", "linear")]) # Count how many categories live in each archetype table(tax$archetype)
Compute the continuous monotonicity and convexity indices, inflection
and turning-point counts, and rule-based shape category for a fitted
univariate smooth. Works on either a per-pair fit object returned
from the janusplot internal machinery or a freshly fitted
mgcv::gam() with a single s() term.
Both indices are bounded in [-1, 1] and weighted by the empirical
density of the predictor:
monotonicity_index (paper symbol M). Let f be the fitted
smooth evaluated on a dense grid of n_grid equally-spaced
points across the predictor range, f' its numerical first
derivative, and w the empirical density of the predictor on
the same grid with sum(w) = 1. Then
monotonicity_index = sum(w * f') / sum(w * |f'|) in [-1, 1].
+1 is strictly increasing, -1 strictly decreasing, 0
non-monotone.
convexity_index (paper symbol C). With f'' the numerical
second derivative on the same grid,
convexity_index = sum(w * f'') / sum(w * |f''|) in [-1, 1].
+1 is globally convex (bowl-up), -1 globally concave
(bowl-down), 0 inflection-dominated (S-curve, sine, flat).
Both indices are scale-invariant (replacing y -> a*y + b leaves
them unchanged) and density-weighted so they describe the smooth
where the data actually live, not extrapolated tails.
janusplot_shape_metrics( fit, x_name = NULL, newdata = NULL, n_grid = 200L, cutoffs = janusplot_shape_cutoffs() )janusplot_shape_metrics( fit, x_name = NULL, newdata = NULL, n_grid = 200L, cutoffs = janusplot_shape_cutoffs() )
fit |
Either a list returned by a janusplot pair-fit helper
(must contain |
x_name |
Character. Column name of the predictor when |
newdata |
Optional data frame supplying the raw predictor values
used for density weighting when |
n_grid |
Integer. Prediction grid length when |
cutoffs |
Named list of classification thresholds; see
|
A named list with components:
monotonicity_indexM in [-1, 1]. See Description.
convexity_indexC in [-1, 1]. See Description.
n_turning_pointsInteger count of lobe-mass-weighted
sign changes of f'. Equals the number of interior extrema.
n_inflectionsInteger count of lobe-mass-weighted
sign changes of f''.
flat_range_ratiorange(f) / sd(y) — small values
indicate a degenerate flat smooth.
shape_categoryOne of 24 labels from
janusplot_shape_hierarchy() dispatched on
(n_turning_points, n_inflections) with
(monotonicity_index, convexity_index) disambiguation for
the monotone case.
janusplot_shape_cutoffs(), janusplot(), janusplot_data().
Other shape-metrics:
janusplot_shape_cutoffs(),
janusplot_shape_hierarchy()
# On a fitted gam set.seed(2026L) n <- 200L x <- stats::runif(n, 0, 10) y <- log1p(x) + stats::rnorm(n, sd = 0.3) d <- data.frame(x = x, y = y) fit <- mgcv::gam(y ~ s(x), data = d, method = "REML") janusplot_shape_metrics(fit, x_name = "x", newdata = d)# On a fitted gam set.seed(2026L) n <- 200L x <- stats::runif(n, 0, 10) y <- log1p(x) + stats::rnorm(n, sd = 0.3) d <- data.frame(x = x, y = y) fit <- mgcv::gam(y ~ s(x), data = d, method = "REML") janusplot_shape_metrics(fit, x_name = "x", newdata = d)
Run a full-factorial sensitivity sweep for the janusplot 24-category
shape classifier. For each combination of ground-truth shape, sample
size n, noise level sigma, and replicate, the sweep:
Generates n points from the noiseless canonical curve on
[0, 1] + Gaussian noise with SD = sigma (fraction of the
y-range, so signal-to-noise is comparable across shapes).
Fits mgcv::gam(y ~ s(x), method = "REML").
Runs janusplot_shape_metrics() to classify the fitted smooth.
Records correctness at both the fine (24-category) and archetype (7-family) levels.
The function is the package-native implementation of
simulation/scripts/scenario_4_shape_recognition.R. A small
precomputed dataset is shipped as shape_sensitivity_demo for
downstream examples without requiring users to re-run the sweep.
janusplot_shape_sensitivity( shapes = NULL, n_grid = c(50L, 100L, 200L, 500L), sigma_grid = c(0.02, 0.05, 0.1, 0.2, 0.4), n_rep = 200L, cutoffs = janusplot_shape_cutoffs(), parallel = FALSE, seed = 2026L, verbose = interactive() )janusplot_shape_sensitivity( shapes = NULL, n_grid = c(50L, 100L, 200L, 500L), sigma_grid = c(0.02, 0.05, 0.1, 0.2, 0.4), n_rep = 200L, cutoffs = janusplot_shape_cutoffs(), parallel = FALSE, seed = 2026L, verbose = interactive() )
shapes |
Character vector of ground-truth names from
|
n_grid |
Integer vector of sample sizes. Default
|
sigma_grid |
Numeric vector of noise levels (fraction of the
y-range). Default |
n_rep |
Integer. Replicates per cell. Default |
cutoffs |
Named list of classification thresholds; see
|
parallel |
Logical. If |
seed |
Integer. Base seed — each fit uses |
verbose |
Logical. Print progress messages to the console.
Default is |
A data frame with one row per fit. Columns:
truthGround-truth shape name.
nSample size for this fit.
sigmaNoise level for this fit.
seedRNG seed used.
predictedClassifier output at the fine (24-category) level.
correctLogical — does predicted == truth?
archetype_truthExpected archetype for truth.
archetype_predArchetype of predicted.
archetype_correctLogical — archetype-level correctness.
monotonicity_indexMonotonicity index M (see
janusplot_shape_metrics()).
convexity_indexConvexity index C (see
janusplot_shape_metrics()).
n_turn, n_inflect
Recovered turning-point and inflection counts.
error"gam_fit_failed" when mgcv::gam() errored;
NA otherwise.
janusplot_shape_sensitivity_summary(),
janusplot_shape_sensitivity_plot(),
janusplot_shape_sensitivity_shapes(), shape_sensitivity_demo.
Other shape-sensitivity:
janusplot_shape_sensitivity_plot(),
janusplot_shape_sensitivity_shapes(),
janusplot_shape_sensitivity_summary()
# Tiny-run smoke test (< 2 seconds): 3 shapes x 2 n x 2 sigma x 5 reps. res <- janusplot_shape_sensitivity( shapes = c("linear_up", "u_shape", "wave"), n_grid = c(100L, 200L), sigma_grid = c(0.05, 0.20), n_rep = 5L, verbose = FALSE ) head(res) janusplot_shape_sensitivity_summary(res, level = "archetype")# Tiny-run smoke test (< 2 seconds): 3 shapes x 2 n x 2 sigma x 5 reps. res <- janusplot_shape_sensitivity( shapes = c("linear_up", "u_shape", "wave"), n_grid = c(100L, 200L), sigma_grid = c(0.05, 0.20), n_rep = 5L, verbose = FALSE ) head(res) janusplot_shape_sensitivity_summary(res, level = "archetype")
Produce one of four diagnostic plots from the raw data frame returned
by janusplot_shape_sensitivity():
"confusion_fine"24 x (|shapes|) confusion matrix at the
fine category level — rows = ground truth, columns = predicted,
cells coloured by P(pred | truth).
"confusion_archetype"7 x 7 confusion matrix at the archetype level.
"accuracy_grid"per-shape heatmap of archetype-level
accuracy across the (n, sigma) design.
"recovery_curves"accuracy as a function of sigma, one line per sample size, faceted by shape.
janusplot_shape_sensitivity_plot( results, type = c("confusion_fine", "confusion_archetype", "accuracy_grid", "recovery_curves") )janusplot_shape_sensitivity_plot( results, type = c("confusion_fine", "confusion_archetype", "accuracy_grid", "recovery_curves") )
results |
Data frame from |
type |
One of |
A ggplot2::ggplot object.
Other shape-sensitivity:
janusplot_shape_sensitivity(),
janusplot_shape_sensitivity_shapes(),
janusplot_shape_sensitivity_summary()
data("shape_sensitivity_demo", package = "janusplot") janusplot_shape_sensitivity_plot(shape_sensitivity_demo, "recovery_curves")data("shape_sensitivity_demo", package = "janusplot") janusplot_shape_sensitivity_plot(shape_sensitivity_demo, "recovery_curves")
Return the names of every canonical ground-truth shape that
janusplot_shape_sensitivity() can simulate from. Fourteen shapes
spanning five archetypes (monotone_linear, monotone_curved,
unimodal, wave, multimodal). The chaotic and degenerate
archetypes are out of scope (no realistic deterministic generator).
janusplot_shape_sensitivity_shapes()janusplot_shape_sensitivity_shapes()
Character vector of length 14 — the generator names.
janusplot_shape_sensitivity(), janusplot_shape_hierarchy().
Other shape-sensitivity:
janusplot_shape_sensitivity(),
janusplot_shape_sensitivity_plot(),
janusplot_shape_sensitivity_summary()
janusplot_shape_sensitivity_shapes()janusplot_shape_sensitivity_shapes()
Aggregate the raw output of janusplot_shape_sensitivity() into a
per-cell mean-accuracy table at either the fine (24-category) or
archetype (7-family) level.
janusplot_shape_sensitivity_summary(results, level = c("fine", "archetype"))janusplot_shape_sensitivity_summary(results, level = c("fine", "archetype"))
results |
Data frame returned by |
level |
One of |
A data frame with columns truth, n, sigma, accuracy.
Other shape-sensitivity:
janusplot_shape_sensitivity(),
janusplot_shape_sensitivity_plot(),
janusplot_shape_sensitivity_shapes()
data("shape_sensitivity_demo", package = "janusplot") head(janusplot_shape_sensitivity_summary(shape_sensitivity_demo, level = "archetype"))data("shape_sensitivity_demo", package = "janusplot") head(janusplot_shape_sensitivity_summary(shape_sensitivity_demo, level = "archetype"))
Raw output from a small-footprint invocation of
janusplot_shape_sensitivity(). Shipped so users can explore the
sensitivity API and regenerate every figure in the
shape-recognition-sensitivity vignette without having to re-run
the sweep themselves. Regenerated via
data-raw/shape_sensitivity_demo.R.
Design:
Shapes (6, one per non-degenerate archetype):
linear_up, concave_up, u_shape, inverted_u, wave,
bimodal.
Sample sizes (3): c(100, 200, 500).
Noise levels (4): c(0.05, 0.10, 0.20, 0.40) fraction
of y-range.
Replicates: 30.
Total fits: 2160.
Seed: 2026.
shape_sensitivity_demoshape_sensitivity_demo
A data frame with 2160 rows and 14 columns — see the
"Value" section of janusplot_shape_sensitivity() for the
column schema.
janusplot_shape_sensitivity(),
janusplot_shape_sensitivity_plot(),
janusplot_shape_sensitivity_summary().
data("shape_sensitivity_demo", package = "janusplot") head(shape_sensitivity_demo) janusplot_shape_sensitivity_plot(shape_sensitivity_demo, "recovery_curves")data("shape_sensitivity_demo", package = "janusplot") head(shape_sensitivity_demo) janusplot_shape_sensitivity_plot(shape_sensitivity_demo, "recovery_curves")