% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/api-plotting.R
\name{plot_unexpected}
\alias{plot_unexpected}
\title{Plot unexpected responses using base R}
\usage{
plot_unexpected(
  x,
  diagnostics = NULL,
  abs_z_min = 2,
  prob_max = 0.3,
  top_n = 100,
  rule = c("either", "both"),
  plot_type = c("scatter", "severity"),
  main = NULL,
  palette = NULL,
  label_angle = 45,
  preset = c("standard", "publication", "compact", "monochrome"),
  draw = TRUE
)
}
\arguments{
\item{x}{Output from \code{\link[=fit_mfrm]{fit_mfrm()}} or \code{\link[=unexpected_response_table]{unexpected_response_table()}}.}

\item{diagnostics}{Optional output from \code{\link[=diagnose_mfrm]{diagnose_mfrm()}} when \code{x} is \code{mfrm_fit}.}

\item{abs_z_min}{Absolute standardized-residual cutoff.}

\item{prob_max}{Maximum observed-category probability cutoff.}

\item{top_n}{Maximum rows used from the unexpected table.}

\item{rule}{Flagging rule (\code{"either"} or \code{"both"}).}

\item{plot_type}{\code{"scatter"} or \code{"severity"}.}

\item{main}{Optional custom plot title.}

\item{palette}{Optional named color overrides (\code{higher}, \code{lower}, \code{bar}).}

\item{label_angle}{X-axis label angle for \code{"severity"} bar plot.}

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

\item{draw}{If \code{TRUE}, draw with base graphics.}
}
\value{
A plotting-data object of class \code{mfrm_plot_data}.
}
\description{
Plot unexpected responses using base R
}
\details{
This helper visualizes flagged observations from \code{\link[=unexpected_response_table]{unexpected_response_table()}}.
An observation is "unexpected" when its standardised residual and/or
observed-category probability exceed user-specified cutoffs.

The \strong{severity index} is a composite ranking metric that combines the
absolute standardised residual \eqn{|Z|} and the negative log
probability \eqn{-\log_{10} P_{\mathrm{obs}}}.  Higher severity
indicates responses that are more surprising under the fitted model.

The \code{rule} parameter controls flagging logic:
\itemize{
\item \code{"either"}: flag if \eqn{|Z| \ge} \code{abs_z_min} \strong{or}
\eqn{P_{\mathrm{obs}} \le} \code{prob_max}.
\item \code{"both"}: flag only if \strong{both} conditions hold simultaneously.
}

Under common thresholds, many well-behaved runs will produce relatively few
flagged observations, but the flagged proportion is design- and
model-dependent. Treat the output as a screening display rather than a
calibrated goodness-of-fit test.
}
\section{Plot types}{

\describe{
\item{\code{"scatter"} (default)}{X-axis: standardized residual \eqn{Z}.
Y-axis: \eqn{-\log_{10}(P_{\mathrm{obs}})} (negative log of
observed-category probability; higher = more surprising).
Points colored orange when the observed score is \emph{higher} than
expected, teal when \emph{lower}.  Dashed lines mark \code{abs_z_min} and
\code{prob_max} thresholds.  Clusters of points in the upper corners
indicate systematic misfit patterns worth investigating.}
\item{\code{"severity"}}{Ranked bar chart of the composite severity index
for the \code{top_n} most unexpected responses.  Bar length reflects
the combined unexpectedness; labels identify the specific
person-facet combination.  Use for QC triage and case-level
prioritization.}
}
}

\section{Interpreting output}{

Scatter plot: farther from zero on x-axis = larger residual mismatch;
higher y-axis = lower observed-category probability.  A uniform
scatter with few points beyond the threshold lines indicates fewer locally
surprising responses under the current thresholds.

Severity plot: focuses on the most extreme observations for targeted
case review.  Look for recurring persons or facet levels among the
top entries---repeated appearances may signal rater misuse, scoring
errors, or model misspecification.
}

\section{Typical workflow}{

\enumerate{
\item Fit model and run \code{\link[=diagnose_mfrm]{diagnose_mfrm()}}.
\item Start with \code{"scatter"} to assess global unexpected pattern.
\item Switch to \code{"severity"} for case prioritization.
}
}

\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{
toy <- load_mfrmr_data("example_core")
fit <- fit_mfrm(toy, "Person", c("Rater", "Criterion"), "Score", method = "JML", maxit = 30)
p <- plot_unexpected(fit, abs_z_min = 1.5, prob_max = 0.4, top_n = 10, draw = FALSE)
if (interactive()) {
  plot_unexpected(
    fit,
    abs_z_min = 1.5,
    prob_max = 0.4,
    top_n = 10,
    plot_type = "severity",
    preset = "publication",
    main = "Unexpected Response Severity (Customized)",
    palette = c(higher = "#d95f02", lower = "#1b9e77", bar = "#2b8cbe"),
    label_angle = 45
  )
}
}
\seealso{
\code{\link[=unexpected_response_table]{unexpected_response_table()}}, \code{\link[=plot_fair_average]{plot_fair_average()}}, \code{\link[=plot_displacement]{plot_displacement()}},
\code{\link[=plot_qc_dashboard]{plot_qc_dashboard()}}, \link{mfrmr_visual_diagnostics}
}
