diff --git a/R/modify_columns.R b/R/modify_columns.R
index e11ff4f58..294bc6913 100644
--- a/R/modify_columns.R
+++ b/R/modify_columns.R
@@ -2755,7 +2755,7 @@ cols_add <- function(
#' sales for a selection of days. By converting the string-time 24-hour-clock
#' time values to the number of seconds elapsed in a day, we get continuous
#' values that can be incorporated into each box plot. And, by supplying a
-#' function to the `y_val_fmt_fn` argument within `nanoplot_options()`, we can
+#' function to the `y_val_fmt_fn` argument within [nanoplot_options()], we can
#' transform the integer seconds values back to clock times for display on
#' hover.
#'
diff --git a/R/utils_plots.R b/R/utils_plots.R
index 820d6408c..bcec3010c 100644
--- a/R/utils_plots.R
+++ b/R/utils_plots.R
@@ -1211,26 +1211,40 @@ generate_nanoplot <- function(
box_thickness <- data_point_radius[1] * 6
# Calculate statistics for boxplot
- stat_p05 <- unname(stats::quantile(y_vals, probs = 0.05, na.rm = TRUE))
stat_q_1 <- unname(stats::quantile(y_vals, probs = 0.25, na.rm = TRUE))
stat_med <- unname(stats::quantile(y_vals, probs = 0.50, na.rm = TRUE))
stat_q_3 <- unname(stats::quantile(y_vals, probs = 0.75, na.rm = TRUE))
- stat_p95 <- unname(stats::quantile(y_vals, probs = 0.95, na.rm = TRUE))
+ stat_iqr <- stats::IQR(y_vals, na.rm = TRUE)
- if (length(y_vals) > 25) {
+ low_outliers <- y_vals[y_vals < stat_q_1 - (1.5 * stat_iqr)]
+ high_outliers <- y_vals[y_vals > stat_q_3 + (1.5 * stat_iqr)]
+
+ stat_min_excl_low_outliers <-
+ min(base::setdiff(y_vals, low_outliers), na.rm = TRUE)
+
+ stat_max_excl_high_outliers <-
+ max(base::setdiff(y_vals, high_outliers), na.rm = TRUE)
+
+ plot_only_outliers <- length(y_vals) >= 20
+
+ if (plot_only_outliers) {
# Plot only outliers since the number of data values is sufficiently high
- y_vals_plot <- y_vals[y_vals < stat_p05 | y_vals > stat_p95]
+ y_vals_plot <- c(low_outliers, high_outliers)
data_point_radius <- 4
data_point_stroke_width <- 2
- data_point_stroke_color <- adjust_luminance(data_bar_stroke_color[1], steps = 0.75)
- data_point_fill_color <- adjust_luminance(data_point_stroke_color[1], steps = 1.75)
+
+ data_point_stroke_color <-
+ adjust_luminance(data_bar_stroke_color[1], steps = 0.75)
+
+ data_point_fill_color <-
+ adjust_luminance(data_point_stroke_color[1], steps = 1.75)
} else {
# Plot all data values but diminish the visibility of the data points
- # as the number approaches 25
+ # as the number approaches 20
y_vals_plot <- y_vals
if (length(y_vals) < 10) {
@@ -1241,7 +1255,9 @@ generate_nanoplot <- function(
data_point_stroke_width <- 2
}
- data_point_stroke_color <- adjust_luminance("black", steps = length(y_vals) / 25)
+ data_point_stroke_color <-
+ adjust_luminance("black", steps = length(y_vals) / 25)
+
data_point_fill_color <- "transparent"
}
@@ -1251,42 +1267,53 @@ generate_nanoplot <- function(
vals = y_vals,
all_vals = all_y_vals,
y_vals_plot = y_vals_plot,
- stat_low = stat_p05,
+ stat_min = stat_min_excl_low_outliers,
stat_qlow = stat_q_1,
stat_med = stat_med,
stat_qup = stat_q_3,
- stat_high = stat_p95
+ stat_max = stat_max_excl_high_outliers
)
y_proportions <- y_proportions_list[["vals"]]
y_proportions_plot <- y_proportions_list[["y_vals_plot"]]
- y_stat_p05 <- y_proportions_list[["stat_low"]]
+ y_stat_min <- y_proportions_list[["stat_min"]]
y_stat_q_1 <- y_proportions_list[["stat_qlow"]]
y_stat_med <- y_proportions_list[["stat_med"]]
y_stat_q_3 <- y_proportions_list[["stat_qup"]]
- y_stat_p95 <- y_proportions_list[["stat_high"]]
+ y_stat_max <- y_proportions_list[["stat_max"]]
# Calculate boxplot x values
- fence_start <- y_stat_p05 * data_x_width
+ fence_start <- y_stat_min * data_x_width
box_start <- y_stat_q_1 * data_x_width
median_x <- y_stat_med * data_x_width
box_end <- y_stat_q_3 * data_x_width
- fence_end <- y_stat_p95 * data_x_width
+ fence_end <- y_stat_max * data_x_width
box_width <- (y_stat_q_3 - y_stat_q_1) * data_x_width
# Establish positions for plottable x and y values
plotted_x_vals <- y_proportions_plot * data_x_width
if (length(y_vals) == 1) {
+
plotted_y_vals <- bottom_y / 2
+
} else {
- plotted_y_vals <- jitter(rep(bottom_y / 2, length(plotted_x_vals)), factor = 10)
+
+ if (plot_only_outliers) {
+
+ plotted_y_vals <- rep(bottom_y / 2, length(plotted_x_vals))
+
+ } else {
+
+ plotted_y_vals <-
+ jitter(rep(bottom_y / 2, length(plotted_x_vals)), factor = 10)
+ }
}
# Format numbers compactly
- stat_p05_value <-
+ stat_min_value <-
format_number_compactly(
- val = stat_p05,
+ val = stat_min_excl_low_outliers,
currency = currency,
fn = y_val_fmt_fn
)
@@ -1308,9 +1335,9 @@ generate_nanoplot <- function(
currency = currency,
fn = y_val_fmt_fn
)
- stat_p95_value <-
+ stat_max_value <-
format_number_compactly(
- val = stat_p95,
+ val = stat_max_excl_high_outliers,
currency = currency,
fn = y_val_fmt_fn
)
@@ -1358,7 +1385,7 @@ generate_nanoplot <- function(
"font-size=\"30px\" ",
"text-anchor=\"end\"",
">",
- stat_p05_value,
+ stat_min_value,
"",
"",
- stat_p95_value,
+ stat_max_value,
""
)
}
diff --git a/images/man_cols_nanoplot_7.png b/images/man_cols_nanoplot_7.png
index 8c91a8cd2..7bcba1dba 100644
Binary files a/images/man_cols_nanoplot_7.png and b/images/man_cols_nanoplot_7.png differ
diff --git a/man/cols_nanoplot.Rd b/man/cols_nanoplot.Rd
index 155b31099..8f3e7e51f 100644
--- a/man/cols_nanoplot.Rd
+++ b/man/cols_nanoplot.Rd
@@ -681,7 +681,7 @@ dataset, we will create a simple table that displays a box plot of pizza
sales for a selection of days. By converting the string-time 24-hour-clock
time values to the number of seconds elapsed in a day, we get continuous
values that can be incorporated into each box plot. And, by supplying a
-function to the \code{y_val_fmt_fn} argument within \code{nanoplot_options()}, we can
+function to the \code{y_val_fmt_fn} argument within \code{\link[=nanoplot_options]{nanoplot_options()}}, we can
transform the integer seconds values back to clock times for display on
hover.
diff --git a/man/info_date_style.Rd b/man/info_date_style.Rd
index 90d064f4a..b26af97a0 100644
--- a/man/info_date_style.Rd
+++ b/man/info_date_style.Rd
@@ -7,7 +7,15 @@
info_date_style(locale = NULL)
}
\arguments{
-\item{locale}{A locale.}
+\item{locale}{\emph{Locale identifier}
+
+\verb{scalar} // \emph{default:} \code{NULL} (\code{optional})
+
+An optional locale identifier that can be used for displaying formatted
+date values according the locale's rules. Examples include \code{"en"} for
+English (United States) and \code{"fr"} for French (France). We can call
+\code{\link[=info_locales]{info_locales()}} for a useful reference for all of the locales that are
+supported.}
}
\value{
An object of class \code{gt_tbl}.