When what = "hierarchy" (default), renders the layered bass-ackwards
hierarchy as a ggplot2 diagram. A factor is a summary variable standing in
for a group of items that move together. Factors appear as labelled boxes
arranged in levels. Level 1 sits at the top and level k at the bottom by
default. Set direction = "horizontal" for a left-to-right layout.
Between-level edges below cut_show are hidden. Two aesthetics carry the
edge information, each explained by its own legend: sign
(positive/negative) is shown by sign_by (edge colour by default) and
magnitude (|r|) by magnitude_by (line thickness by default). No
aesthetic is ever mapped without a matching legend.
Usage
# S3 method for class 'ackwards'
autoplot(
object,
what = c("hierarchy", "fit"),
sign_by = c("color", "linetype", "both", "none"),
magnitude_by = c("linewidth", "none"),
cut_show = NULL,
color_pos = "#2166AC",
color_neg = "#D6604D",
color_edge = "black",
colour_pos = NULL,
colour_neg = NULL,
colour_edge = NULL,
node_width = 0.8,
node_height = 0.4,
min_sep = 1,
order = NULL,
show_items = FALSE,
n_items = 5,
item_cut = 0.3,
show_skip = NULL,
curvature = 0.2,
color_pruned = "grey80",
colour_pruned = NULL,
show_r = FALSE,
r_digits = 2L,
r_label_size = 2.5,
mono = FALSE,
edge_linewidth = NULL,
cut_strong = NULL,
direction = c("vertical", "horizontal"),
show_level_labels = TRUE,
level_label_size = 3,
node_labels = NULL,
primary_only = FALSE,
drop_pruned = FALSE,
compress_levels = FALSE,
show_secondary = FALSE,
show_arrows = TRUE,
legend = TRUE,
...
)
# S3 method for class 'ackwards'
plot(x, ...)Arguments
- object
An
ackwardsobject.- what
One of
"hierarchy"(default) or"fit". Controls which visualisation is produced. All other parameters are ignored whenwhat = "fit".- sign_by
How edge sign (positive vs negative correlation) is encoded. There are four choices. The default
"color"draws positive edges incolor_posand negative edges incolor_neg. Option"linetype"draws positive as solid and negative as dashed. Option"both"uses colour and linetype, with negative drawn as a distinct double-dash so it reads clearly in greyscale. Option"none"does not encode sign and draws all edgescolor_edgeand solid. Whichever channel is used gets a "Direction" legend. Colour is the default because it reads sign at a glance and leaves linetype free. Switch to"linetype"or"both"for greyscale or colour-blind-safe figures.- magnitude_by
How edge magnitude (
|r|) is encoded. One of"linewidth"(the default, where thicker = stronger, with a|r|legend) or"none"(constant width). A numericedge_linewidthalso forces constant width at that value.- cut_show
Edges with
|r| < cut_showare not drawn. Defaults to the value used when the object was created (x$meta$cut_show, typically 0.3).- color_pos, colour_pos
Colour for positive edges when
sign_byuses colour. Default"#2166AC"(blue).colour_posis an accepted British alias.- color_neg, colour_neg
Colour for negative edges when
sign_byuses colour. Default"#D6604D"(red).colour_negis an accepted British alias.- color_edge, colour_edge
Single colour for all edges when
sign_bydoes not use colour ("linetype"or"none"). Default"black".colour_edgeis an accepted British alias.- node_width
Width of factor boxes in layout units. Either a single value applied to every box (default
0.8), or a named numeric vector keyed by factor ID (e.g.c(m5f1 = 1.6)) giving a per-box width. Boxes not named fall back to the0.8default. Use a per-box width to fit a long manualnode_labelsstring. Names matching no factor ID warn.- node_height
Height of factor boxes in layout units. Either a single value applied to every box (default
0.4), or a named numeric vector keyed by factor ID for a per-box height (unnamed boxes fall back to0.4). This helps with multi-line manual labels. Names matching no factor ID warn.- min_sep
Minimum horizontal separation between nodes, passed to
ba_layout(). Default1.0.- order
Optional manual left-to-right ordering of the deepest (
k_max) level, passed toba_layout(). Supply a character vector of that level's factor IDs, or a named list keyed by the level number. That fixes the leaf order, and every upper factor re-centres above its primary children. Use it to untangle a figure by hand.NULL(default) uses the automatic ordering.- show_items
When
TRUE, lists the salient observed items beneath each deepest-level (k_max) factor box, so a publication figure shows what each most-granular factor is made of. Items are the topn_itemsby loading (the correlation between an item and a factor), taken in absolute value at or aboveitem_cut. The extraction is the same as intop_items(). Variable labels are shown when the fit carried them, else the item IDs. Listed below the boxes in a vertical layout, and to their right in a horizontal one. DefaultFALSE.- n_items
Maximum number of items listed per deepest-level factor when
show_items = TRUE.NULLlists every item meetingitem_cut. Default5.- item_cut
Absolute-loading threshold for
show_items: only items with|loading| >= item_cutare listed. Default0.3.- show_skip
Whether to draw skip-level (non-adjacent) edges.
NULL(default) auto-detects:TRUEwhen the object was run withpairs = "all",FALSEotherwise. Ignored whendrop_pruned = TRUE.- curvature
Curvature of skip-level edge arcs. Passed to
ggplot2::geom_curve(). Positive values curve right. Default0.2. Ignored whendrop_pruned = TRUE.- color_pruned, colour_pruned
Fill colour for nodes flagged as pruned or redundant (a factor that persists across levels without changing). Default
"grey80". Only applied when the object carries pruning annotations (x$pruneis non-NULL) anddrop_pruned = FALSE(pruned nodes are omitted entirely whendrop_pruned = TRUE).colour_prunedis an accepted British alias.- show_r
Whether to label each drawn edge with its correlation coefficient. Default
FALSE. WhenTRUE, labels are formatted in APA style (leading zero stripped, e.g..23,-.30) and placed beside each edge using a white-background label that clears the arrowhead.- r_digits
Number of decimal places for edge labels when
show_r = TRUE. Default2L.- r_label_size
Font size for edge correlation labels when
show_r = TRUE. Passed toggplot2::geom_label()assize. Default2.5.- mono
Monochrome convenience wrapper. When
TRUE, equivalent tosign_by = "linetype"with black edges (it overridessign_byand the colour arguments).magnitude_bystill applies. DefaultFALSE.- edge_linewidth
NULL(default) usesmagnitude_byto decide edge width. A numeric value forces every edge to that constant width (implyingmagnitude_by = "none") and drops the|r|legend. Forbes figures use uniform thin lines (about 0.5 to 0.6).- cut_strong
Deprecated in M35 and ignored (with a warning). Edge magnitude is now shown by
magnitude_by(linewidth) and sign bysign_by, because the old strong/weak linetype split double-encoded magnitude. Retained only so existing calls do not error.- direction
Layout orientation.
"vertical"(default) stacks levels top-to-bottom, with level 1 at top."horizontal"lays them out left-to-right, with level 1 at left, which suits wide slides or posters. Level-axis labels move to the bottom margin under"horizontal".- show_level_labels
Whether to draw level axis labels ("1 factor", "2 factors", ...) to the left of the diagram. Default
TRUE. Sometimes the object carries pruning annotations (x$prunenon-NULL) anddrop_pruned = FALSE. Then a level whose factors are all pruned has its axis label rendered in italic to denote its status. The italic matches the grey node fill. Partially-pruned levels keep a plain label.- level_label_size
Font size for level axis labels. Default
3.- node_labels
A named character vector mapping factor IDs (e.g.
"m5f1") to custom display strings (e.g."General"). Unspecified factors keep any label attached withset_factor_labels(), falling back to the defaultm{k}f{j}ID. Entries here override a stored factor label for that node, so this argument is a per-call last word over the persistent labels. A warning is issued for names that match no factor ID in the object. DefaultNULL.- primary_only
When
TRUE, only primary-parent edges (is_primary == TRUE) are drawn. Because skip-level edges are never primary, this also suppresses skip arcs. Ignored whendrop_pruned = TRUE. DefaultFALSE.- drop_pruned
When
TRUE, activates the Forbes (2023) pruned-view rendering path. Pruned nodes are removed from the diagram entirely. Each retained node is connected to its single strongest kept ancestor by a straight arrow, even across level gaps. This requires the object to carry pruning annotations (piped throughprune()), and errors if not. Overridesshow_skip,curvature, andprimary_only. DefaultFALSE.- compress_levels
When
TRUEunderdrop_pruned = TRUE, closes vertical gaps left by pruned levels so retained levels are evenly spaced. Level axis labels (d) still show the original level numbers. Ignored whendrop_pruned = FALSE. DefaultFALSE.- show_secondary
When
TRUEunderdrop_pruned = TRUE, also draws the between-level correlation edges the single-strongest-ancestor primary view hides: every kept cross-level factor pair with|r| >= cut_showthat is not already a primary edge. This includes cross-branch second parents and same-lineage skip arcs (a direct skip-levelris a distinct, non-transitive fact, not implied by the primary path). Secondary edges render in a channel deliberately distinct from the primary edges. They are dimmed (reduced opacity) and thinner, with plain line ends. They still inherit the sign encoding (sign_by), so the sign colour or linetype is never confused with the secondary channel. By construction each node's secondaries are weaker than its primary edge, so a secondary edge never appears while that node's primary is belowcut_show. Ignored whendrop_pruned = FALSE. DefaultFALSE.- show_arrows
When
FALSE, edges are drawn with plain line ends instead of closed arrowheads (arrow = NULL). Applies to both straight and curved edge layers. DefaultTRUE. Forbes (2023) figures use plain line ends.- legend
When
FALSE, suppresses all plot legends (legend.position = "none"). Useful whencolor_pos == color_neg(e.g. both"black") to remove an otherwise redundant Direction key. DefaultTRUE.- ...
Ignored.
- x
An
ackwardsobject.
Details
When what = "fit", renders a two-panel line plot of per-level fit indices.
CFI and TLI go in the top panel, RMSEA and SRMR in the bottom panel.
Horizontal reference lines mark the conventional Hu & Bentler (1999)
thresholds. The anchor level (k = 1, saturated and always fits perfectly) is
excluded. This needs the EFA (exploratory factor analysis) or ESEM
(exploratory structural equation modeling) engine. It returns an informative
empty plot for PCA (principal component analysis), which has no model-fit
indices.
Requires the ggplot2 package.
Saving plots
autoplot() returns a standard ggplot object, so save it with
ggplot2::ggsave():
ggsave() is not re-exported by ackwards, because that would move
ggplot2 from Suggests into Imports. Call it from ggplot2
directly. For a wide slide or poster, pair it with
direction = "horizontal".
See also
ba_layout(), plot.ackwards()
Examples
# \donttest{
if (requireNamespace("ggplot2", quietly = TRUE)) {
# sim16 has a known 1 -> 2 -> 4 hierarchy (continuous; pearson basis)
x <- ackwards(sim16, k_max = 5)
autoplot(x)
autoplot(x, color_pos = "steelblue")
# Encode sign by linetype instead of colour, or by both
autoplot(x, sign_by = "linetype")
autoplot(x, sign_by = "both")
# Left-to-right layout (wide slides / posters)
autoplot(x, direction = "horizontal")
# List the top items under each deepest-level factor
autoplot(x, show_items = TRUE, n_items = 4)
# Per-level fit index chart (EFA or ESEM only)
x_efa <- ackwards(sim16, k_max = 5, engine = "efa")
autoplot(x_efa, what = "fit")
# Monochrome with correlation labels (for greyscale figures)
autoplot(x, mono = TRUE, show_r = TRUE)
# Custom node labels for the 5-factor level
autoplot(x, node_labels = c(m5f1 = "Factor A", m5f2 = "Factor B"))
# Widen two boxes to fit long manual labels (per-box sizing)
autoplot(x,
node_labels = c(m5f1 = "Conscientiousness"),
node_width = c(m5f1 = 1.8)
)
# Primary links only -- clean hierarchy tree
autoplot(x, primary_only = TRUE)
# Manually order the deepest level to untangle the figure by hand
ids5 <- paste0("m5f", c(2, 1, 3, 5, 4))
autoplot(x, order = ids5)
# Forbes pruned view: omit redundant nodes, straight spanning arrows
xp <- ackwards(sim16, k_max = 5) |> prune("redundant")
autoplot(xp, drop_pruned = TRUE)
autoplot(xp, drop_pruned = TRUE, show_r = TRUE)
autoplot(xp, drop_pruned = TRUE, compress_levels = TRUE)
# Add the secondary between-level correlations the primary view hides
# (dimmed + thinner, drawn beneath the primary edges)
autoplot(xp, drop_pruned = TRUE, show_secondary = TRUE)
# Plain line ends without arrowheads
autoplot(x, show_arrows = FALSE)
# Uniform edge width (no |r| scaling)
autoplot(x, edge_linewidth = 0.5)
# Suppress legend
autoplot(x, legend = FALSE)
# Forbes (2023) publication style: black lines, uniform width, no arrowheads
autoplot(xp,
drop_pruned = TRUE,
color_pos = "black", color_neg = "black",
edge_linewidth = 0.6, show_arrows = FALSE, legend = FALSE
)
}
#> Warning: `min_sep` (1) is less than the widest box (1.8); adjacent boxes may overlap.
#> ℹ Redundancy pruning (direct criterion, |r| ≥ 0.9) flagged 7 nodes.
#> ℹ Nodes are retained in the object; inspect with `x$prune$nodes` and
#> `x$prune$chains`.
# }
