Skip to content

merge master back in #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 24, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ export(label_both)
export(label_bquote)
export(label_parsed)
export(label_value)
export(label_wrap_gen)
export(labeller)
export(labs)
export(last_plot)
export(layer)
Expand Down
12 changes: 12 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ ggplot2 0.9.3.1.99
* Add `"none"` to documentation of `theme()` for parameter `legend.position`
(@krlmlr, #829).

* The outliers of geom_boxplot() use the default colour, size and shape from
geom_point(). Changing the defaults of geom_point() with
update_geom_defaults() will apply the same changes to the outliers of
geom_boxplot(). Changing the defaults for the outliers was previously not
possible. (@ThierryO, #757)
* Added helper function `labeller` for formatting faceting values.
(@stefanedwards, #910)

* Added `label_wrap_gen` based on
https://github.com/hadley/ggplot2/wiki/labeller#writing-new-labellers
(@stefanedwards, #910)

ggplot2 0.9.3.1
----------------------------------------------------------------

Expand Down
122 changes: 122 additions & 0 deletions R/facet-labels.r
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,128 @@ label_bquote <- function(expr = beta ^ .(x)) {
}
}

#' Label facets with a word wrapped label.
#'
#' Uses \code{\link[base]{strwrap}} for line wrapping.
#' @param width integer, target column width for output.
#' @export
#' @seealso , \code{\link{labeller}}
label_wrap_gen <- function(width = 25) {
function(variable, values) {
vapply(strwrap(as.character(values), width = width, simplify = FALSE),
paste, vector('character', 1), collapse = "\n")
}
}

#' Generic labeller function for facets
#'
#' One-step function for providing methods or named character vectors
#' for displaying labels in facets.
#'
#' The provided methods are checked for number of arguments.
#' If the provided method takes less than two
#' (e.g. \code{\link[Hmisc]{capitalize}}),
#' the method is passed \code{values}.
#' Else (e.g. \code{\link{label_both}}),
#' it is passed \code{variable} and \code{values} (in that order).
#' If you want to be certain, use e.g. an anonymous function.
#' If errors are returned such as ``argument ".." is missing, with no default''
#' or ``unused argument (variable)'', matching the method's arguments does not
#' work as expected; make a wrapper function.
#'
#'
#' @param ... Named arguments of the form \code{variable=values},
#' where \code{values} could be a vector or method.
#' @param keep.as.numeric logical, default TRUE. When FALSE, converts numeric
#' values supplied as margins to the facet to characters.
#' @family facet labeller
#' @return Function to supply to
#' \code{\link{facet_grid}} for the argument \code{labeller}.
#' @export
#' @examples
#'
#' data(mpg)
#'
#' p1 <- ggplot(mpg, aes(cty, hwy)) + geom_point()
#'
#'
#' p1 + facet_grid(cyl ~ class, labeller=label_both)
#'
#' p1 + facet_grid(cyl ~ class, labeller=labeller(cyl=label_both))
#'
#' ggplot(mtcars, aes(x = mpg, y = wt)) + geom_point() +
#' facet_grid(vs + am ~ gear, margins=TRUE,
#' labeller=labeller(vs=label_both, am=label_both))
#'
#'
#'
#' data(msleep)
#' capitalize <- function(string) {
#' substr(string, 1, 1) <- toupper(substr(string, 1, 1))
#' string
#' }
#' conservation_status <- c('cd'='Conservation Dependent',
#' 'en'='Endangered',
#' 'lc'='Least concern',
#' 'nt'='Near Threatened',
#' 'vu'='Vulnerable',
#' 'domesticated'='Domesticated')
#' ## Source: http://en.wikipedia.org/wiki/Uncyclopedia:Conservation_status
#'
#' p2 <- ggplot(msleep, aes(x=sleep_total, y=awake)) + geom_point() +
#' p2 + facet_grid(vore ~ conservation, labeller=labeller(vore=capitalize))
#'
#' p2 + facet_grid(vore ~ conservation,
#' labeller=labeller(vore=capitalize, conservation=conservation_status ))
#'
#' # We could of course have renamed the levels;
#' # then we can apply another nifty function:
#' library(plyr)
#' msleep$conservation2 <- revalue(msleep$conservation, conservation_status)
#'
#' p2 + facet_grid(vore ~ conservation2, labeller=labeller(vore=capitalize))
#'
#' p2 + facet_grid(vore ~ conservation2,
#' labeller=labeller(conservation2=label_wrap_gen(10) ))
#'
labeller <- function(..., keep.as.numeric=FALSE) {
args <- list(...)

function(variable, values) {
if (is.logical(values)) {
values <- as.integer(values) + 1
} else if (is.factor(values)) {
values <- as.character(values)
} else if (is.numeric(values) & !keep.as.numeric) {
values <- as.character(values)
}

res <- args[[variable]]

if (is.null(res)) {
# If the facetting margin (i.e. `variable`) was not specified when calling
# labeller, default to use the actual values.
result <- values

} else if (is.function(res)) {
# How should `variable` and `values` be passed to a function? ------------
arguments <- length(formals(res))
if (arguments < 2) {
result <- res(values)
} else {
result <- res(variable, values)
}

} else {
result <- res[values]
}

return(result)
}
}



# Grob for strip labels
ggstrip <- function(text, horizontal=TRUE, theme) {
text_theme <- if (horizontal) "strip.text.x" else "strip.text.y"
Expand Down
33 changes: 25 additions & 8 deletions R/geom-boxplot.r
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
#' continuous variable, \code{\link{geom_jitter}} for another way to look
#' at conditional distributions"
#' @inheritParams geom_point
#' @param outlier.colour colour for outlying points
#' @param outlier.shape shape of outlying points
#' @param outlier.size size of outlying points
#' @param outlier.colour colour for outlying points. Uses the default from geom_point().
#' @param outlier.shape shape of outlying points. Uses the default from geom_point().
#' @param outlier.size size of outlying points. Uses the default from geom_point().
#' @param notch if \code{FALSE} (default) make a standard box plot. If
#' \code{TRUE}, make a notched box plot. Notches are used to compare groups;
#' if the notches of two boxes do not overlap, this is strong evidence that
Expand Down Expand Up @@ -100,13 +100,30 @@
#' # Using varwidth
#' p + geom_boxplot(varwidth = TRUE)
#' qplot(factor(cyl), mpg, data = mtcars, geom = "boxplot", varwidth = TRUE)
#'
#' # Update the defaults for the outliers by changing the defaults for geom_point
#'
#' p <- ggplot(mtcars, aes(factor(cyl), mpg))
#' p + geom_boxplot()
#'
#' update_geom_defaults("point", list(shape = 1, colour = "red", size = 5))
#' p + geom_boxplot()
#' }
geom_boxplot <- function (mapping = NULL, data = NULL, stat = "boxplot", position = "dodge",
outlier.colour = "black", outlier.shape = 16, outlier.size = 2,
notch = FALSE, notchwidth = .5, varwidth = FALSE, ...) {
geom_boxplot <- function (mapping = NULL, data = NULL, stat = "boxplot",
position = "dodge", outlier.colour = NULL,
outlier.shape = NULL, outlier.size = NULL,
notch = FALSE, notchwidth = .5, ...) {

outlier_defaults <- Geom$find('point')$default_aes()

outlier.colour <- outlier.colour %||% outlier_defaults$colour
outlier.shape <- outlier.shape %||% outlier_defaults$shape
outlier.size <- outlier.size %||% outlier_defaults$size

GeomBoxplot$new(mapping = mapping, data = data, stat = stat,
position = position, outlier.colour = outlier.colour, outlier.shape = outlier.shape,
outlier.size = outlier.size, notch = notch, notchwidth = notchwidth, varwidth = varwidth, ...)
position = position, outlier.colour = outlier.colour,
outlier.shape = outlier.shape, outlier.size = outlier.size, notch = notch,
notchwidth = notchwidth, ...)
}

GeomBoxplot <- proto(Geom, {
Expand Down
2 changes: 1 addition & 1 deletion R/scale-datetime.r
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#' returns a vector of breaks, or a character vector, specifying the width
#' between breaks. For more information about the first two, see
#' \code{\link{continuous_scale}}, for more information about the last,
#' see \code{\link[scales]{date_breaks}}`.
#' see \code{\link[scales]{date_breaks}}.
#' @param minor_breaks Either \code{NULL} for no minor breaks, \code{waiver()}
#' for the default breaks (one minor break between each major break), a
#' numeric vector of positions, or a function that given the limits returns
Expand Down
8 changes: 5 additions & 3 deletions R/stat-summary.r
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#' Summarise y values at every unique x.
#'
#' \code{stat_summary} allows for tremendous flexibilty in the specification
#' of summary functions. The summary function can either operate on a data
#' frame (with argument name \code{fun.data}) or on a vector (\code{fun.y},
#' \code{fun.ymax}, \code{fun.ymin}).
#' of summary functions. The summary function can either supply individual
#' summary functions for each of y, ymin and ymax (with \code{fun.y},
#' \code{fun.ymax}, \code{fun.ymin}), or return a data frame containing any
#' number of aesthetiics with with \code{fun.data}. All summary functions
#' are called with a single vector of values, \code{x}.
#'
#' A simple vector function is easiest to work with as you can return a single
#' number, but is somewhat less flexible. If your summary function operates
Expand Down
19 changes: 13 additions & 6 deletions man/geom_boxplot.Rd
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@
\title{Box and whiskers plot.}
\usage{
geom_boxplot(mapping = NULL, data = NULL, stat = "boxplot",
position = "dodge", outlier.colour = "black", outlier.shape = 16,
outlier.size = 2, notch = FALSE, notchwidth = 0.5, varwidth = FALSE,
...)
position = "dodge", outlier.colour = NULL, outlier.shape = NULL,
outlier.size = NULL, notch = FALSE, notchwidth = 0.5, ...)
}
\arguments{
\item{outlier.colour}{colour for outlying points}
\item{outlier.colour}{colour for outlying points. Uses the default from geom_point().}

\item{outlier.shape}{shape of outlying points}
\item{outlier.shape}{shape of outlying points. Uses the default from geom_point().}

\item{outlier.size}{size of outlying points}
\item{outlier.size}{size of outlying points. Uses the default from geom_point().}

\item{notch}{if \code{FALSE} (default) make a standard box plot. If
\code{TRUE}, make a notched box plot. Notches are used to compare groups;
Expand Down Expand Up @@ -126,6 +125,14 @@ b + geom_boxplot(aes(fill = X1), stat = "identity")
# Using varwidth
p + geom_boxplot(varwidth = TRUE)
qplot(factor(cyl), mpg, data = mtcars, geom = "boxplot", varwidth = TRUE)

# Update the defaults for the outliers by changing the defaults for geom_point

p <- ggplot(mtcars, aes(factor(cyl), mpg))
p + geom_boxplot()

update_geom_defaults("point", list(shape = 1, colour = "red", size = 5))
p + geom_boxplot()
}
}
\references{
Expand Down
17 changes: 17 additions & 0 deletions man/label_wrap_gen.Rd
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
% Generated by roxygen2 (4.0.0): do not edit by hand
\name{label_wrap_gen}
\alias{label_wrap_gen}
\title{Label facets with a word wrapped label.}
\usage{
label_wrap_gen(width = 25)
}
\arguments{
\item{width}{integer, target column width for output.}
}
\description{
Uses \code{\link[base]{strwrap}} for line wrapping.
}
\seealso{
, \code{\link{labeller}}
}

82 changes: 82 additions & 0 deletions man/labeller.Rd
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
% Generated by roxygen2 (4.0.0): do not edit by hand
\name{labeller}
\alias{labeller}
\title{Generic labeller function for facets}
\usage{
labeller(..., keep.as.numeric = FALSE)
}
\arguments{
\item{...}{Named arguments of the form
\code{variable=values}, where \code{values} could be a
vector or method.}

\item{keep.as.numeric}{logical, default TRUE. When FALSE,
converts numeric values supplied as margins to the facet
to characters.}
}
\value{
Function to supply to
\code{\link{facet_grid}} for the argument \code{labeller}.
}
\description{
One-step function for providing methods or named character vectors
for displaying labels in facets.
}
\details{
The provided methods are checked for number of arguments.
If the provided method takes less than two
(e.g. \code{\link[Hmisc]{capitalize}}),
the method is passed \code{values}.
Else (e.g. \code{\link{label_both}}),
it is passed \code{variable} and \code{values} (in that order).
If you want to be certain, use e.g. an anonymous function.
If errors are returned such as ``argument ".." is missing, with no default''
or ``unused argument (variable)'', matching the method's arguments does not
work as expected; make a wrapper function.
}
\examples{
data(mpg)

p1 <- ggplot(mpg, aes(cty, hwy)) + geom_point()


p1 + facet_grid(cyl ~ class, labeller=label_both)

p1 + facet_grid(cyl ~ class, labeller=labeller(cyl=label_both))

ggplot(mtcars, aes(x = mpg, y = wt)) + geom_point() +
facet_grid(vs + am ~ gear, margins=TRUE,
labeller=labeller(vs=label_both, am=label_both))



data(msleep)
capitalize <- function(string) {
substr(string, 1, 1) <- toupper(substr(string, 1, 1))
string
}
conservation_status <- c('cd'='Conservation Dependent',
'en'='Endangered',
'lc'='Least concern',
'nt'='Near Threatened',
'vu'='Vulnerable',
'domesticated'='Domesticated')
## Source: http://en.wikipedia.org/wiki/Uncyclopedia:Conservation_status

p2 <- ggplot(msleep, aes(x=sleep_total, y=awake)) + geom_point() +
p2 + facet_grid(vore ~ conservation, labeller=labeller(vore=capitalize))

p2 + facet_grid(vore ~ conservation,
labeller=labeller(vore=capitalize, conservation=conservation_status ))

# We could of course have renamed the levels;
# then we can apply another nifty function:
library(plyr)
msleep$conservation2 <- revalue(msleep$conservation, conservation_status)

p2 + facet_grid(vore ~ conservation2, labeller=labeller(vore=capitalize))

p2 + facet_grid(vore ~ conservation2,
labeller=labeller(conservation2=label_wrap_gen(10) ))
}

Loading