% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/api-plotting-anchor-qc.R
\name{plot_anchor_drift}
\alias{plot_anchor_drift}
\title{Plot anchor drift or a screened linking chain}
\usage{
plot_anchor_drift(
  x,
  type = c("drift", "chain", "heatmap", "forest"),
  facet = NULL,
  ci_level = 0.95,
  preset = c("standard", "publication", "compact", "monochrome"),
  draw = TRUE,
  ...
)
}
\arguments{
\item{x}{An \code{mfrm_anchor_drift} or \code{mfrm_equating_chain} object.}

\item{type}{Plot type: \code{"drift"} (dot plot of element drift),
\code{"chain"} (cumulative offset line plot), \code{"heatmap"}
(wave-by-element drift heatmap), or \code{"forest"} (per-(Facet, Level,
Wave) anchor estimate with \verb{+/- z * SE} whiskers; requires
\code{mfrm_anchor_drift}).}

\item{facet}{Optional character vector to filter drift plots to specific
facets.}

\item{ci_level}{Confidence level used by \code{type = "forest"} for the
anchor-estimate whiskers (default \code{0.95}). Ignored for other
plot types.}

\item{preset}{Visual preset (\code{"standard"}, \code{"publication"}, \code{"compact"}, or \code{"monochrome"}).}

\item{draw}{If \code{FALSE}, return the plot data invisibly without drawing.}

\item{...}{Additional graphical parameters passed to base plotting
functions.}
}
\value{
A plotting-data object of class \code{mfrm_plot_data}. With
\code{draw = FALSE}, \code{result$data$table} contains the filtered drift or chain
table, \code{result$data$matrix} contains the heatmap matrix when requested,
and the returned plot data includes package-native \code{title}, \code{subtitle},
\code{legend}, and \code{reference_lines}.
}
\description{
Creates base-R plots for inspecting anchor drift across calibration waves
or visualising the cumulative offset in a screened linking chain.
}
\details{
Three plot types are supported:
\itemize{
\item \strong{\code{"drift"}} (for \code{mfrm_anchor_drift} objects): A dot plot of each
element's drift value, grouped by facet.  Horizontal reference lines
mark the drift threshold.  Red points indicate flagged elements.
\item \strong{\code{"heatmap"}} (for \code{mfrm_anchor_drift} objects): A wave-by-element
heat matrix showing drift magnitude.  Darker cells represent larger
absolute drift.  Useful for spotting systematic patterns (e.g., all
criteria shifting in the same direction).
\item \strong{\code{"chain"}} (for \code{mfrm_equating_chain} objects): A line plot of
cumulative offsets across the screened linking chain. A flatter line
indicates smaller between-wave shifts; steep segments suggest larger
link offsets that deserve review.
}
}
\section{Which plot should I use?}{

\itemize{
\item Use \code{type = "drift"} with an \code{mfrm_anchor_drift} object to review flagged
elements directly.
\item Use \code{type = "heatmap"} with an \code{mfrm_anchor_drift} object to spot
wave-by-element patterns.
\item Use \code{type = "chain"} with an \code{mfrm_equating_chain} object after
\code{\link[=build_equating_chain]{build_equating_chain()}} to inspect cumulative offsets across waves.
}
}

\section{Interpreting plots}{

\strong{Drift} is the change in an element's estimated measure between
calibration waves, after accounting for the screened common-element link
offset. An
element is flagged when its absolute drift exceeds a threshold
(typically 0.5 logits) \strong{and} the drift-to-SE ratio exceeds a
secondary criterion (typically 2.0), ensuring that only
practically noticeable and relatively precise shifts are flagged.
\itemize{
\item In drift and heatmap plots, red or dark-shaded elements exceed
both thresholds.  Common causes include rater drift over time,
item exposure effects, or curriculum changes.
\item In chain plots, uneven spacing between waves suggests differential
shifts in the screened linking offsets. The \eqn{y}-axis shows cumulative
logit-scale offsets; flatter segments indicate more stable adjacent links.
Steep segments should be checked alongside \code{LinkSupportAdequate} and the
retained common-element counts before making longitudinal claims.
\item For drift objects, it is usually best to read \code{summary(x)} first
and then use the plot to see where the flagged values sit.
}
}

\section{Typical workflow}{

\enumerate{
\item Build a drift or screened-linking object with \code{\link[=detect_anchor_drift]{detect_anchor_drift()}} or
\code{\link[=build_equating_chain]{build_equating_chain()}}.
\item Start with \code{draw = FALSE} if you want the plotting data for custom
reporting.
\item Use the base-R plot for quick screening and then inspect the underlying
tables for exact values.
}
}

\section{Further guidance}{

For a plot-selection guide and a longer walkthrough, see
\link{mfrmr_visual_diagnostics} and
\code{vignette("mfrmr-visual-diagnostics", package = "mfrmr")}.
}

\examples{
\donttest{
toy <- load_mfrmr_data("example_core")
people <- unique(toy$Person)
d1 <- toy[toy$Person \%in\% people[1:12], , drop = FALSE]
d2 <- toy[toy$Person \%in\% people[13:24], , drop = FALSE]
fit1 <- fit_mfrm(d1, "Person", c("Rater", "Criterion"), "Score",
                 method = "JML", maxit = 30)
fit2 <- fit_mfrm(d2, "Person", c("Rater", "Criterion"), "Score",
                 method = "JML", maxit = 30)
drift <- detect_anchor_drift(list(W1 = fit1, W2 = fit2))
drift_plot <- plot_anchor_drift(drift, type = "drift", draw = FALSE)
class(drift_plot)
names(drift_plot$data)
chain <- build_equating_chain(list(F1 = fit1, F2 = fit2))
chain_plot <- plot_anchor_drift(chain, type = "chain", draw = FALSE)
head(chain_plot$data$table)
if (interactive()) {
  plot_anchor_drift(drift, type = "heatmap", preset = "publication")
}
}
}
\seealso{
\code{\link[=detect_anchor_drift]{detect_anchor_drift()}}, \code{\link[=build_equating_chain]{build_equating_chain()}},
\code{\link[=plot_dif_heatmap]{plot_dif_heatmap()}}, \code{\link[=plot_bubble]{plot_bubble()}}, \link{mfrmr_visual_diagnostics}
}
\concept{confidence intervals}
\concept{linking}
\concept{visual diagnostics}
