Box plots summarize distributions showing median, quartiles, and outliers. They work with either raw array data or pre-computed summary statistics.

TipWhen to Use Boxplots

Best for comparing distribution summaries across groups when you care about:

  • Median and spread
  • Quartile ranges
  • Outliers

Use violin plots instead if you need to see full distribution shapes (bimodality, skewness).

ImportantData Format for Array Columns

Array columns require the I() wrapper to preserve list structure:

# Create a data frame with array column
data <- data.frame(
  group = c("A", "B", "C"),
  values = I(list(
    c(1, 2, 3, 4, 5),
    c(2, 4, 6, 8, 10),
    c(3, 5, 7, 9, 11)
  ))
)

Without I(), R will try to unlist the vectors and fail.

From Array Data

When your data contains arrays of values per row, boxplot stats are computed automatically:

Code
set.seed(42)
boxplot_data <- data.frame(
  treatment = c("Control", "Low Dose", "Medium Dose", "High Dose"),
  response = I(list(
    rnorm(50, mean = 100, sd = 15),
    rnorm(50, mean = 110, sd = 18),
    rnorm(50, mean = 125, sd = 20),
    rnorm(50, mean = 140, sd = 25)
  )),
  n = c(50, 50, 50, 50)
)

tabviz(boxplot_data, label = "treatment",
  columns = list(
    col_n("n"),
    viz_boxplot(
      effect_boxplot(data = "response", color = "#8b5cf6"),
      header = "Response Distribution",
      width = 250,
      show_outliers = TRUE
    )
  ),
  title = "Dose-Response Distribution"
)

From Pre-computed Statistics

If you already have quartile statistics computed, map them directly:

Code
summary_data <- data.frame(
  study = c("Study A", "Study B", "Study C", "Study D"),
  min = c(45, 52, 38, 60),
  q1 = c(62, 68, 55, 72),
  median = c(78, 82, 71, 85),
  q3 = c(89, 94, 86, 95),
  max = c(105, 112, 98, 108)
)

tabviz(summary_data, label = "study",
  columns = list(
    viz_boxplot(
      effect_boxplot(
        min = "min", q1 = "q1", median = "median", q3 = "q3", max = "max",
        color = "#22c55e"
      ),
      header = "Score Distribution",
      width = 220
    ),
    col_numeric("median", "Median")
  ),
  title = "Study Score Distributions"
)

Multiple Effects

Compare distributions across conditions:

Code
set.seed(123)
multi_box_data <- data.frame(
  timepoint = c("Baseline", "Week 4", "Week 8", "Week 12"),
  placebo = I(list(
    rnorm(40, 50, 12), rnorm(40, 52, 13), rnorm(40, 51, 14), rnorm(40, 53, 12)
  )),
  treatment = I(list(
    rnorm(40, 50, 12), rnorm(40, 62, 14), rnorm(40, 70, 15), rnorm(40, 75, 13)
  ))
)

tabviz(multi_box_data, label = "timepoint",
  columns = list(
    viz_boxplot(
      effect_boxplot(data = "placebo", label = "Placebo", color = "#94a3b8"),
      effect_boxplot(data = "treatment", label = "Treatment", color = "#3b82f6"),
      header = "Score by Treatment Arm",
      width = 280,
      show_outliers = TRUE
    )
  ),
  title = "Treatment Effect Over Time"
)

viz_boxplot() Arguments

Argument Description Default
header Column header text NULL
width Column width in pixels 150
scale "linear" or "log" "linear"
axis_range Fixed axis range c(min, max) Auto
axis_ticks Custom tick positions Auto
axis_gridlines Show vertical gridlines FALSE
show_outliers Display outlier points TRUE
whisker_type "iqr" (1.5×IQR) or "minmax" "iqr"
axis_label Label text below axis "Value"
show_axis Show the axis TRUE

effect_boxplot() Arguments

Argument Description
data Column containing array of values (mode 1)
min, q1, median, q3, max Column names for pre-computed stats (mode 2)
outliers Column containing outlier values (optional, mode 2)
label Display label for legend
color Box fill color
fill_opacity Box fill opacity (default: 0.7)

See Also