% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/api-plotting.R
\name{plot_bubble}
\alias{plot_bubble}
\title{Bubble chart of measure estimates and fit statistics}
\usage{
plot_bubble(
  x,
  diagnostics = NULL,
  fit_stat = c("Infit", "Outfit"),
  view = c("measure", "infit_outfit"),
  bubble_size = NULL,
  facets = NULL,
  fit_range = c(0.5, 1.5),
  top_n = 60,
  main = NULL,
  palette = NULL,
  draw = TRUE,
  preset = c("standard", "publication", "compact", "monochrome")
)
}
\arguments{
\item{x}{Output from \code{\link{fit_mfrm}} or \code{\link{diagnose_mfrm}}.}

\item{diagnostics}{Optional output from \code{\link{diagnose_mfrm}} when
\code{x} is an \code{mfrm_fit} object. If omitted, diagnostics are
computed automatically.}

\item{fit_stat}{Fit statistic for the y-axis: \code{"Infit"} (default) or
\code{"Outfit"}. Ignored when \code{view = "infit_outfit"} because
that view always plots Infit on x and Outfit on y.}

\item{view}{Layout. \code{"measure"} (default, the historical
mfrmr layout) plots Measure (logit) on x and the chosen
\code{fit_stat} MnSq on y. \code{"infit_outfit"} plots Infit MnSq
on x and Outfit MnSq on y, matching the Winsteps Table 30.2
"Most-misfitting Persons / Items" scatter that many MFRM and
Rasch users expect, and defaults \code{bubble_size = "N"}.}

\item{bubble_size}{Variable controlling bubble radius: \code{"SE"} (default
for \code{view = "measure"}), \code{"N"} (observation count;
default for \code{view = "infit_outfit"}), or \code{"equal"}
(uniform size).}

\item{facets}{Character vector of facets to include. \code{NULL} (default)
includes all non-person facets.}

\item{fit_range}{Numeric length-2 vector defining the heuristic fit-review band
shown as a shaded region (default \code{c(0.5, 1.5)}).}

\item{top_n}{Maximum number of elements to plot (default 60).}

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

\item{palette}{Optional named colour vector keyed by facet name.}

\item{draw}{If \code{TRUE} (default), render the plot using base graphics.}

\item{preset}{Visual preset (\code{"standard"}, \code{"publication"}, \code{"compact"}, or \code{"monochrome"}).}
}
\value{
Invisibly, an object of class \code{mfrm_plot_data}.
}
\description{
Produces a Rasch-convention bubble chart where each element is a circle
positioned at its measure estimate (x) and fit mean-square (y).
Bubble radius reflects approximate measurement precision or sample size.
}
\details{
When \code{x} is an \code{mfrm_fit} object and \code{diagnostics} is omitted,
the function computes diagnostics internally via \code{\link{diagnose_mfrm}()}.
For repeated plotting in the same workflow, passing a precomputed diagnostics
object avoids that extra work.

The x-axis shows element measure estimates on the \strong{logit} scale
(one logit = one unit change in log-odds of responding in a higher
category).  The y-axis shows the selected fit mean-square statistic.
A shaded band between \code{fit_range[1]} and \code{fit_range[2]}
highlights a common heuristic review range.

Bubble radius options:
\itemize{
\item \code{"SE"}: inversely proportional to standard error---larger
circles indicate more precisely estimated elements under the current
SE approximation.
\item \code{"N"}: proportional to observation count---larger
circles indicate elements with more data.
\item \code{"equal"}: uniform size, useful when SE or N differences
distract from the fit pattern.
}

Person estimates are excluded by default because they typically
outnumber facet elements and obscure the display.
}
\section{Interpreting the plot}{

Points near the horizontal reference line at 1.0 are closer to model
expectation on the selected MnSq scale.
Points above 1.5 suggest underfit relative to common review heuristics;
these elements may have inconsistent scoring.
Points below 0.5 suggest overfit relative to common review heuristics;
these may indicate redundancy or restricted range.
Points are colored by facet for easy identification.
}

\section{Typical workflow}{

\enumerate{
\item Fit a model with \code{\link{fit_mfrm}()}.
\item Compute diagnostics once with \code{\link{diagnose_mfrm}()}.
\item Call \code{plot_bubble(fit, diagnostics = diag)} to inspect the most extreme elements.
}
}

\examples{
toy <- load_mfrmr_data("example_core")
fit <- fit_mfrm(toy, "Person", c("Rater", "Criterion"), "Score",
                method = "JML", model = "RSM", maxit = 30)
diag <- diagnose_mfrm(fit, residual_pca = "none")
p <- plot_bubble(fit, diagnostics = diag, draw = FALSE)
head(p$data$table[, c("Facet", "Level", "Estimate", "Infit", "Outfit")])
# Look for (default `view = "measure"`): bubbles inside the shaded
#   0.5-1.5 fit-review band. Bubbles above the band are underfit
#   (noisy elements); below the band are overfit (overly predictable).
#
# For the Winsteps Table 30 layout pass `view = "infit_outfit"`:
p_io <- plot_bubble(fit, diagnostics = diag, view = "infit_outfit",
                     draw = FALSE)
p_io$data$view
# Look for: bubbles clustered inside the central [0.5, 1.5] x [0.5, 1.5]
#   square. Points outside the upper-right corner have both Infit
#   AND Outfit > 1.5 (consistent underfit); points outside the
#   lower-left have both < 0.5 (consistent overfit). Bubble size in
#   this view defaults to N (observation count) so the visual
#   weighting matches how seriously the misfit should be taken.
}
\seealso{
\code{\link{diagnose_mfrm}}, \code{\link{plot_unexpected}},
\code{\link{plot_fair_average}}
}
