Skip to content

Commit

Permalink
Improved q-q plot error bands (#299)
Browse files Browse the repository at this point in the history
* init

* Update DESCRIPTION

* more details

* add example

* Update labeling and defaults

- Make titles for p-p plots parallel to those for q-q plots
- Change default to `type = "qq"`
- Add details for the `type` argument to documentation (and add similar details for functions that previously imported the `type` argument from `plot.see_check_normality`

* detrend without qqplotr

* Update NEWS.md

* fix global variable issue

* version bump

---------

Co-authored-by: Brenton M. Wiernik <[email protected]>
Co-authored-by: Daniel <[email protected]>
  • Loading branch information
3 people authored Aug 30, 2023
1 parent d95dbbb commit b32cec8
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 44 deletions.
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: see
Title: Model Visualisation Toolbox for 'easystats' and 'ggplot2'
Version: 0.8.0.2
Version: 0.8.0.3
Authors@R:
c(person(given = "Daniel",
family = "Lüdecke",
Expand Down Expand Up @@ -97,7 +97,7 @@ Suggests:
patchwork,
poorman,
psych,
qqplotr,
qqplotr (>= 0.0.6),
randomForest,
rlang,
rmarkdown,
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

* The `print()` method for `performance::check_model()` now also evaluates the
default plot type for posterior predictive checks.
* QQ/PP-plots now default to drawing simultaneous testing bands (when the
`qqplotr` package is available). Previous behavior can be restored by setting
`method = "pointwise"`.
* Plot method for `performance::check_normality()` now default to a detrended
QQ-plot. Previous behavior can be restored by setting `type = "density"`.

# see 0.8.0

Expand Down
97 changes: 66 additions & 31 deletions R/plot.check_normality.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@
#' function.
#'
#' @param type Character vector, indicating the type of plot.
#' Options are `"qq"` (default) for quantile-quantile (Q-Q) plots,
#' `"pp"` for probability-probability (P-P) plots, or
#' `"density"` for density overlay plots.
#' @param size_line Numeric value specifying size of line geoms.
#' @param dot_alpha Numeric value specifying alpha level of the point geoms.
#' @param alpha Numeric value specifying alpha level of the confidence bands.
#' @param colors Character vector of length two, indicating the colors (in
#' hex-format) for points and line.
#' @param detrend Logical that decides if the plot should be detrended.
#' @param detrend Logical that decides if Q-Q and P-P plots should be de-trended
#' (also known as _worm plots_).
#' @param method The method used for estimating the qq/pp bands. Default to
#' `"ell"` (equal local levels / simultaneous testing - recommended). Can also
#' be one of `"pointwise"` or `"boot"` for pointwise confidence bands, or
#' `"ks"` or `"ts"` for simultaneous testing. See `qqplotr::stat_qq_band()`
#' for details.
#' @inheritParams data_plot
#' @inheritParams plot.see_bayesfactor_parameters
#'
Expand All @@ -21,16 +30,21 @@
#' m <<- lm(mpg ~ wt + cyl + gear + disp, data = mtcars)
#' result <- check_normality(m)
#' plot(result)
#'
#' @examplesIf require("performance") && require("qqplotr")
#' plot(result, type = "qq", detrend = TRUE)
#'
#' @export
plot.see_check_normality <- function(x,
type = c("density", "qq", "pp"),
type = c("qq", "pp", "density"),
data = NULL,
size_line = 0.8,
size_point = 2,
alpha = 0.2,
dot_alpha = 0.8,
colors = c("#3aaf85", "#1b6ca8"),
detrend = FALSE,
detrend = TRUE,
method = "ell",
...) {
type <- match.arg(type)

Expand Down Expand Up @@ -75,7 +89,8 @@ plot.see_check_normality <- function(x,
alpha_level = alpha,
detrend = detrend,
dot_alpha_level = dot_alpha,
model_info = model_info
model_info = model_info,
method = method
)
} else if (type == "density") {
r <- suppressMessages(stats::residuals(model))
Expand All @@ -95,7 +110,8 @@ plot.see_check_normality <- function(x,
size_line = size_line,
alpha_level = alpha,
detrend = detrend,
dot_alpha_level = dot_alpha
dot_alpha_level = dot_alpha,
method = method
)
}
}
Expand Down Expand Up @@ -145,6 +161,7 @@ plot.see_check_normality <- function(x,
size_line,
alpha_level = 0.2,
detrend = FALSE,
method = "ell",
theme_style = theme_lucid,
colors = unname(social_colors(c("green", "blue", "red"))),
dot_alpha_level = 0.8,
Expand Down Expand Up @@ -175,7 +192,8 @@ plot.see_check_normality <- function(x,
qq_stuff <- list(
qqplotr::stat_qq_band(
alpha = alpha_level,
detrend = detrend
detrend = detrend,
bandType = method
),
qqplotr::stat_qq_point(
shape = 16,
Expand All @@ -191,32 +209,47 @@ plot.see_check_normality <- function(x,
detrend = detrend
)
)
y_lab <- "Sample Quantiles"
if (detrend) {
y_lab <- "Sample Quantile Deviations"
} else {
y_lab <- "Sample Quantiles"
}
} else {
insight::format_alert(
paste0(
"For confidence bands",
if (isTRUE(detrend)) " and detrending",
", please install `qqplotr`."
)
)
insight::format_alert("For confidence bands, please install `qqplotr`.")

gg_init <- ggplot2::ggplot(x, ggplot2::aes(sample = .data$y))

qq_stuff <- list(
ggplot2::geom_qq_line(
linewidth = size_line,
colour = colors[1],
na.rm = TRUE
),
if (detrend) {
ggplot2::geom_hline(
yintercept = 0,
linewidth = size_line,
colour = colors[1],
na.rm = TRUE
)
} else {
ggplot2::geom_qq_line(
linewidth = size_line,
colour = colors[1],
na.rm = TRUE
)
}
,
ggplot2::geom_qq(
mapping = if (detrend) ggplot2::aes(y = ggplot2::after_stat("sample") - ggplot2::after_stat("theoretical")),
shape = 16,
na.rm = TRUE,
stroke = 0,
size = size_point,
colour = colors[2] # "#2c3e50"
)
)
y_lab <- "Sample Quantiles"

if (detrend) {
y_lab <- "Sample Quantile Deviations"
} else {
y_lab <- "Sample Quantiles"
}
}

if (!isTRUE(show_dots)) {
Expand Down Expand Up @@ -246,12 +279,13 @@ plot.see_check_normality <- function(x,
size_line,
alpha_level = 0.2,
detrend = FALSE,
method = "ell",
theme_style = theme_lucid,
colors = unname(social_colors(c("green", "blue", "red"))),
dot_alpha_level = 0.8) {
if (requireNamespace("qqplotr", quietly = TRUE)) {
p_plot <- ggplot2::ggplot(x, ggplot2::aes(sample = .data$res)) +
qqplotr::stat_pp_band(alpha = alpha_level, detrend = detrend) +
qqplotr::stat_pp_band(alpha = alpha_level, detrend = detrend, bandType = method) +
qqplotr::stat_pp_line(
linewidth = size_line,
colour = colors[1],
Expand All @@ -265,37 +299,38 @@ plot.see_check_normality <- function(x,
detrend = detrend
)
} else if (requireNamespace("MASS", quietly = TRUE)) {
message(
"For confidence bands",
if (isTRUE(detrend)) " and detrending",
", please install `qqplotr`."
)
insight::format_alert("For confidence bands, please install `qqplotr`.")

x$probs <- stats::ppoints(x$res)
dparms <- MASS::fitdistr(x$res, densfun = "normal")
x$y <- do.call(stats::pnorm, c(list(q = x$res), dparms$estimate))

p_plot <- ggplot2::ggplot(x, ggplot2::aes(x = .data$probs, y = .data$y)) +
ggplot2::geom_abline(
slope = 1,
slope = if (detrend) 0 else 1,
linewidth = size_line,
colour = colors[1]
) +
geom_point2(
mapping = if (detrend) ggplot2::aes(y = .data$y - .data$probs),
colour = colors[2],
size = size_point,
alpha = dot_alpha_level
) # "#2c3e50"
} else {
stop("Package 'qqplotr' OR 'MASS' required for PP-plots. Please install one of them.", call. = FALSE)
insight::format_error("Package 'qqplotr' OR 'MASS' required for P-P plots. Please install one of them.")
}


y_lab <- "Sample Cummulative Probability"
if (detrend) y_lab <- paste0(y_lab, " Deviations")

p_plot +
ggplot2::labs(
title = "Normality of Residuals (PP plot)",
title = "Normality of Residuals",
subtitle = "Dots should fall along the line",
y = "Cummulative Probability",
x = "Probability Points"
y = y_lab,
x = "Standard Normal Cumulative Probability"
) +
theme_style(
base_size = 10,
Expand Down
6 changes: 6 additions & 0 deletions R/plot.check_outliers.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
#' The `plot()` method for the `performance::check_outliers()`
#' function.
#'
#' @param type Character vector, indicating the type of plot.
#' Options are `"dots"` (default) for a scatterplot of leverage (hat) values
#' versus residuals, with Cook's Distance contours for evaluating influential
#' points, or `"bars"` for a bar chart of (rescaled) outlier statistic values
#' for each data point. Only used for outlier plots of fitted models; for
#' outlier plots of raw data values, `type = "bars"` is always used.
#' @param show_labels Logical. If `TRUE`, text labels are displayed.
#' @param size_text Numeric value specifying size of text labels.
#' @param rescale_distance Logical. If `TRUE`, distance values are rescaled
Expand Down
6 changes: 6 additions & 0 deletions R/plot.n_factors.R
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ data_plot.n_clusters <- data_plot.n_factors
#'
#' The `plot()` method for the `parameters::n_factors()` and `parameters::n_clusters()`
#'
#' @param type Character vector, indicating the type of plot.
#' Options are three different shapes to illustrate the degree of consensus
#' between dimensionality methods for each number of factors;
#' `"bar"` (default) for a bar chart,
#' `"line"` for a horizontal point and line chart, or
#' `"area"` for an area chart (frequency polygon).
#' @param size Depending on `type`, a numeric value specifying size of bars,
#' lines, or segments.
#' @inheritParams data_plot
Expand Down
4 changes: 4 additions & 0 deletions R/plot.parameters_pca.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ data_plot.parameters_efa <- data_plot.parameters_pca
#'
#' The `plot()` method for the `parameters::principal_components()` function.
#'
#' @param type Character vector, indicating the type of plot.
#' Options are three different shapes to represent component loadings;
#' `"bar"` (default) for a horizontal bar chart, or
#' `"line"` for a horizontal point and line chart.
#' @param text_color Character specifying color of text labels.
#' @inheritParams data_plot
#' @inheritParams plot.see_bayesfactor_parameters
Expand Down
22 changes: 18 additions & 4 deletions man/plot.see_check_normality.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion man/plot.see_check_outliers.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion man/plot.see_n_factors.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion man/plot.see_parameters_pca.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b32cec8

Please sign in to comment.