Skip to content

Commit 1a7f86d

Browse files
author
Tomas Sieger
committed
Add parameter "varwidth" to geom_boxplot
1 parent ae175ae commit 1a7f86d

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

R/geom-boxplot.r

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
#' the medians differ.
3333
#' @param notchwidth for a notched box plot, width of the notch relative to
3434
#' the body (default 0.5)
35+
#' @param varwidth if \code{FALSE} (default) make a standard box plot. If
36+
#' \code{TRUE}, boxes are drawn with widths proportional to the
37+
#' square-roots of the number of observations in the groups (possibly
38+
#' weighted).
3539
#' @export
3640
#'
3741
#' @references McGill, R., Tukey, J. W. and Larsen, W. A. (1978) Variations of
@@ -92,13 +96,17 @@
9296
#' b + geom_boxplot(stat = "identity")
9397
#' b + geom_boxplot(stat = "identity") + coord_flip()
9498
#' b + geom_boxplot(aes(fill = X1), stat = "identity")
99+
#'
100+
#' # Using varwidth
101+
#' p + geom_boxplot(varwidth = TRUE)
102+
#' qplot(factor(cyl), mpg, data = mtcars, geom = "boxplot", varwidth = TRUE)
95103
#' }
96104
geom_boxplot <- function (mapping = NULL, data = NULL, stat = "boxplot", position = "dodge",
97105
outlier.colour = "black", outlier.shape = 16, outlier.size = 2,
98-
notch = FALSE, notchwidth = .5, ...) {
106+
notch = FALSE, notchwidth = .5, varwidth = FALSE, ...) {
99107
GeomBoxplot$new(mapping = mapping, data = data, stat = stat,
100108
position = position, outlier.colour = outlier.colour, outlier.shape = outlier.shape,
101-
outlier.size = outlier.size, notch = notch, notchwidth = notchwidth, ...)
109+
outlier.size = outlier.size, notch = notch, notchwidth = notchwidth, varwidth = varwidth, ...)
102110
}
103111

104112
GeomBoxplot <- proto(Geom, {
@@ -118,14 +126,27 @@ GeomBoxplot <- proto(Geom, {
118126
df$ymax_final <- pmax(out_max, df$ymax)
119127
}
120128

121-
transform(df,
122-
xmin = x - width / 2, xmax = x + width / 2, width = NULL
123-
)
129+
# if varwidth not requested or not available, don't use it
130+
if(is.null(params) || is.null(params$varwidth) || !params$varwidth || is.null(df$relvarwidth)) {
131+
if (is.null(df$relvarwidth)) {
132+
transform(df,
133+
xmin = x - width / 2, xmax = x + width / 2, width = NULL
134+
)
135+
} else {
136+
transform(df,
137+
xmin = x - width / 2, xmax = x + width / 2, width = NULL, relvarwidth = NULL
138+
)
139+
}
140+
} else {
141+
transform(df,
142+
xmin = x - relvarwidth * width / 2, xmax = x + relvarwidth * width / 2, width = NULL, relvarwidth = NULL
143+
)
144+
}
124145

125146
}
126147

127148
draw <- function(., data, ..., fatten = 2, outlier.colour = NULL, outlier.shape = NULL, outlier.size = 2,
128-
notch = FALSE, notchwidth = .5) {
149+
notch = FALSE, notchwidth = .5, varwidth = FALSE) {
129150
common <- data.frame(
130151
colour = data$colour,
131152
size = data$size,

R/stat-boxplot.r

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ StatBoxplot <- proto(Stat, {
7676

7777
transform(df,
7878
x = if (is.factor(x)) x[1] else mean(range(x)),
79-
width = width
79+
width = width,
80+
relvarwidth = sqrt(n)
8081
)
8182
})
8283
}

man/geom_boxplot.Rd

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
\usage{
66
geom_boxplot(mapping = NULL, data = NULL, stat = "boxplot",
77
position = "dodge", outlier.colour = "black", outlier.shape = 16,
8-
outlier.size = 2, notch = FALSE, notchwidth = 0.5, ...)
8+
outlier.size = 2, notch = FALSE, notchwidth = 0.5, varwidth = FALSE,
9+
...)
910
}
1011
\arguments{
1112
\item{outlier.colour}{colour for outlying points}
@@ -23,6 +24,11 @@ geom_boxplot(mapping = NULL, data = NULL, stat = "boxplot",
2324
\item{notchwidth}{for a notched box plot, width of the
2425
notch relative to the body (default 0.5)}
2526

27+
\item{varwidth}{if \code{FALSE} (default) make a standard
28+
box plot. If \code{TRUE}, boxes are drawn with widths
29+
proportional to the square-roots of the number of
30+
observations in the groups (possibly weighted).}
31+
2632
\item{mapping}{The aesthetic mapping, usually constructed
2733
with \code{\link{aes}} or \code{\link{aes_string}}. Only
2834
needs to be set at the layer level if you are overriding
@@ -119,6 +125,10 @@ b <- ggplot(abc, aes(x = X1, ymin = `0\%`, lower = `25\%`, middle = `50\%`, uppe
119125
b + geom_boxplot(stat = "identity")
120126
b + geom_boxplot(stat = "identity") + coord_flip()
121127
b + geom_boxplot(aes(fill = X1), stat = "identity")
128+
129+
# Using varwidth
130+
p + geom_boxplot(varwidth = TRUE)
131+
qplot(factor(cyl), mpg, data = mtcars, geom = "boxplot", varwidth = TRUE)
122132
}
123133
}
124134
\references{

0 commit comments

Comments
 (0)