Skip to content

Consolidate coordinate scale expansion and limiting code #3380

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
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6fefc89
move expantion-related functions to their own file
paleolimbot Jun 20, 2019
913e440
fix spelling of expansion in filenames, move expand_default to scale-…
paleolimbot Jun 21, 2019
12e3e8a
remove scale_range(), fix scale_dimension() tests
paleolimbot Jun 21, 2019
586d271
move all scale expansion to Scale$dimension()
paleolimbot Jun 21, 2019
348b90b
have coord polar and coord map use expansion
paleolimbot Jun 21, 2019
c7310de
add functions to expand continuous and discrete scale limits with tra…
paleolimbot Jun 23, 2019
1890252
apply new expansion strategy to coord_trans()
paleolimbot Jun 23, 2019
5d5b679
have all expansion take place using functions in scale-expansion.r
paleolimbot Jun 23, 2019
1c4adcd
get second axes to work with coord_trans()
paleolimbot Jun 23, 2019
dfd89de
ensure that the reverse/reciprocal transformations work with coord_tr…
paleolimbot Jun 23, 2019
be2a229
add news bullets
paleolimbot Jun 23, 2019
6c79a04
remove all coord limiting/expansion code from scale functions
paleolimbot Jun 23, 2019
5041427
change argument order: should always be limits, expansion, coord_limits
paleolimbot Jun 23, 2019
3f52a42
mention removal of `xtrans` and `ytrans` arguments in `coord_trans()`
paleolimbot Jun 24, 2019
a4f5bb9
explicitly noRd expand_range4() (not exported), fix PR review comment…
paleolimbot Jun 24, 2019
3f06b3e
loudly deprecate limx and limy
paleolimbot Jun 24, 2019
f72bd7b
calculate expansion prior to calling expand_limits_scale()
paleolimbot Jun 24, 2019
d60d0a1
clarify coord_limits param in expand_limits_scale()
paleolimbot Jun 24, 2019
cb31615
fix assign operator for expand_scale
paleolimbot Jun 24, 2019
16f57c2
remove last reference to gg_dep (#3057)
paleolimbot Jun 25, 2019
9f92894
rename expand_default to default_expansion
paleolimbot Jul 1, 2019
73125a8
rename `expand_scale()` to `expansion()`
paleolimbot Jul 1, 2019
7acadc5
add news bullet for expand_scale deprecation
paleolimbot Jul 1, 2019
2df6bdb
fix typo in expansion doc
paleolimbot Jul 1, 2019
18220cc
add deprecation warning for expand_scale()
paleolimbot Jul 1, 2019
7773fc6
fix dep notice
paleolimbot Jul 1, 2019
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
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Suggests:
rpart,
sf (>= 0.7-3),
svglite (>= 1.2.0.9001),
testthat (>= 0.11.0),
testthat (>= 2.1.0),
vdiffr (>= 0.3.0)
Enhances: sp
License: GPL-2 | file LICENSE
Expand Down Expand Up @@ -190,6 +190,7 @@ Collate:
'scale-continuous.r'
'scale-date.r'
'scale-discrete-.r'
'scale-expansion.r'
'scale-gradient.r'
'scale-grey.r'
'scale-hue.r'
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ export(ensym)
export(ensyms)
export(expand_limits)
export(expand_scale)
export(expansion)
export(expr)
export(facet_grid)
export(facet_null)
Expand Down
23 changes: 23 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
# ggplot2 (development version)

* `expand_scale()` was deprecated in favour of `expansion()` for setting
the `expand` argument of `x` and `y` scales (@paleolimbot).

* `coord_trans()` now draws second axes and accepts `xlim`, `ylim`,
and `expand` arguments to bring it up to feature parity with
`coord_cartesian()`. The `xtrans` and `ytrans` arguments that were
deprecated in version 1.0.1 in favour of `x` and `y`
were removed (@paleolimbot, #2990).

* `coord_trans()` now calculates breaks using the expanded range
(previously these were calculated using the unexpanded range,
which resulted in differences between plots made with `coord_trans()`
and those made with `coord_cartesian()`). The expansion for discrete axes
in `coord_trans()` was also updated such that it behaves identically
to that in `coord_cartesian()` (@paleolimbot, #3338).

* All `coord_*()` functions with `xlim` and `ylim` arguments now accept
vectors with `NA` as a placeholder for the minimum or maximum value
(e.g., `ylim = c(0, NA)` would zoom the y-axis from 0 to the
maximum value observed in the data). This mimics the behaviour
of the `limits` argument in continuous scale functions
(@paleolimbot, #2907).

* `geom_abline()`, `geom_hline()`, and `geom_vline()` now issue
more informative warnings when supplied with set aesthetics
(i.e., `slope`, `intercept`, `yintercept`, and/or `xintercept`)
Expand Down
50 changes: 39 additions & 11 deletions R/axis-secondary.R
Original file line number Diff line number Diff line change
Expand Up @@ -187,21 +187,49 @@ AxisSecondary <- ggproto("AxisSecondary", NULL,

# patch for date and datetime scales just to maintain functionality
# works only for linear secondary transforms that respect the time or date transform
if (scale$trans$name %in% c("date", "time")){
if (scale$trans$name %in% c("date", "time")) {
temp_scale <- self$create_scale(new_range, trans = scale$trans)
range_info <- temp_scale$break_info()
names(range_info) <- paste0("sec.", names(range_info))
return(range_info)
}
old_val_trans <- rescale(range_info$major, from = c(0, 1), to = range)
old_val_minor_trans <- rescale(range_info$minor, from = c(0, 1), to = range)
} else {
temp_scale <- self$create_scale(new_range)
range_info <- temp_scale$break_info()

temp_scale <- self$create_scale(new_range)
range_info <- temp_scale$break_info()
# Map the break values back to their correct position on the primary scale
old_val <- lapply(range_info$major_source, function(x) which.min(abs(full_range - x)))
old_val <- old_range[unlist(old_val)]
old_val_trans <- scale$trans$transform(old_val)

old_val_minor <- lapply(range_info$minor_source, function(x) which.min(abs(full_range - x)))
old_val_minor <- old_range[unlist(old_val_minor)]
old_val_minor_trans <- scale$trans$transform(old_val_minor)

# rescale values from 0 to 1
range_info$major[] <- round(
rescale(
scale$map(old_val_trans, range(old_val_trans)),
from = range
),
digits = 3
)

range_info$minor[] <- round(
rescale(
scale$map(old_val_minor_trans, range(old_val_minor_trans)),
from = range
),
digits = 3
)
}

# Map the break values back to their correct position on the primary scale
old_val <- lapply(range_info$major_source, function(x) which.min(abs(full_range - x)))
old_val <- old_range[unlist(old_val)]
old_val_trans <- scale$trans$transform(old_val)
range_info$major[] <- round(rescale(scale$map(old_val_trans, range(old_val_trans)), from = range), digits = 3)
# The _source values should be in (primary) scale_transformed space,
# so that the coord doesn't have to know about the secondary scale transformation
# when drawing the axis. The values in user space are useful for testing.
range_info$major_source_user <- range_info$major_source
range_info$minor_source_user <- range_info$minor_source
range_info$major_source[] <- old_val_trans
range_info$minor_source[] <- old_val_minor_trans

names(range_info) <- paste0("sec.", names(range_info))
range_info
Expand Down
2 changes: 1 addition & 1 deletion R/bin.R
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ bin_breaks_bins <- function(x_range, bins = 30, center = NULL,
if (bins < 1) {
stop("Need at least one bin.", call. = FALSE)
} else if (zero_range(x_range)) {
# 0.1 is the same width as the expansion `expand_default()` gives for 0-width data
# 0.1 is the same width as the expansion `default_expansion()` gives for 0-width data
width <- 0.1
} else if (bins == 1) {
width <- diff(x_range)
Expand Down
4 changes: 0 additions & 4 deletions R/coord-.r
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,6 @@ Coord <- ggproto("Coord",
#' @keywords internal
is.Coord <- function(x) inherits(x, "Coord")

expand_default <- function(scale, discrete = c(0, 0.6, 0, 0.6), continuous = c(0.05, 0, 0.05, 0)) {
scale$expand %|W|% if (scale$is_discrete()) discrete else continuous
}

# Renders an axis with the correct orientation or zeroGrob if no axis should be
# generated
render_axis <- function(panel_params, axis, scale, position, theme) {
Expand Down
11 changes: 2 additions & 9 deletions R/coord-cartesian-.r
Original file line number Diff line number Diff line change
Expand Up @@ -137,16 +137,9 @@ CoordCartesian <- ggproto("CoordCartesian", Coord,
)

view_scales_from_scale <- function(scale, coord_limits = NULL, expand = TRUE) {
expansion <- if (expand) expand_default(scale) else expand_scale(0, 0)
expansion <- default_expansion(scale, expand = expand)
limits <- scale$get_limits()

if (is.null(coord_limits)) {
continuous_range <- scale$dimension(expansion, limits)
} else {
continuous_range <- range(scale$transform(coord_limits))
continuous_range <- expand_range4(continuous_range, expansion)
}

continuous_range <- expand_limits_scale(scale, expansion, limits, coord_limits = coord_limits)
aesthetic <- scale$aesthetics[1]

view_scales <- list(
Expand Down
7 changes: 1 addition & 6 deletions R/coord-map.r
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,7 @@ CoordMap <- ggproto("CoordMap", Coord,
for (n in c("x", "y")) {
scale <- get(paste0("scale_", n))
limits <- self$limits[[n]]

if (is.null(limits)) {
range <- scale$dimension(expand_default(scale))
} else {
range <- range(scale$transform(limits))
}
range <- expand_limits_scale(scale, default_expansion(scale), coord_limits = limits)
ranges[[n]] <- range
}

Expand Down
16 changes: 6 additions & 10 deletions R/coord-polar.r
Original file line number Diff line number Diff line change
Expand Up @@ -111,25 +111,21 @@ CoordPolar <- ggproto("CoordPolar", Coord,
scale <- get(paste0("scale_", n))
limits <- self$limits[[n]]

if (is.null(limits)) {
if (self$theta == n) {
expand <- expand_default(scale, c(0, 0.5), c(0, 0))
} else {
expand <- expand_default(scale, c(0, 0), c(0, 0))
}
range <- scale$dimension(expand)
if (self$theta == n) {
expansion <- default_expansion(scale, c(0, 0.5), c(0, 0))
} else {
range <- range(scale_transform(scale, limits))
expansion <- default_expansion(scale, c(0, 0), c(0, 0))
}
range <- expand_limits_scale(scale, expansion, coord_limits = limits)

out <- scale$break_info(range)
ret[[n]]$range <- out$range
ret[[n]]$major <- out$major_source
ret[[n]]$minor <- out$minor_source
ret[[n]]$labels <- out$labels
ret[[n]]$sec.range <- out$sec.range
ret[[n]]$sec.major <- out$sec.major_source
ret[[n]]$sec.minor <- out$sec.minor_source
ret[[n]]$sec.major <- out$sec.major_source_user
ret[[n]]$sec.minor <- out$sec.minor_source_user
ret[[n]]$sec.labels <- out$sec.labels
}

Expand Down
17 changes: 4 additions & 13 deletions R/coord-sf.R
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,10 @@ CoordSf <- ggproto("CoordSf", CoordCartesian,

setup_panel_params = function(self, scale_x, scale_y, params = list()) {
# Bounding box of the data
x_range <- scale_range(scale_x, self$limits$x, self$expand)
y_range <- scale_range(scale_y, self$limits$y, self$expand)
expansion_x <- default_expansion(scale_x, expand = self$expand)
x_range <- expand_limits_scale(scale_x, expansion_x, coord_limits = self$limits$x)
expansion_y <- default_expansion(scale_y, expand = self$expand)
y_range <- expand_limits_scale(scale_y, expansion_y, coord_limits = self$limits$y)
bbox <- c(
x_range[1], y_range[1],
x_range[2], y_range[2]
Expand Down Expand Up @@ -466,14 +468,3 @@ parse_axes_labeling <- function(x) {
labs = unlist(strsplit(x, ""))
list(top = labs[1], right = labs[2], bottom = labs[3], left = labs[4])
}

scale_range <- function(scale, limits = NULL, expand = TRUE) {
expansion <- if (expand) expand_default(scale) else expand_scale(0, 0)

if (is.null(limits)) {
scale$dimension(expansion)
} else {
continuous_range <- range(scale$transform(limits))
expand_range4(continuous_range, expansion)
}
}
102 changes: 52 additions & 50 deletions R/coord-transform.r
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,9 @@
#' [scales::trans_new()] for list of transformations, and instructions
#' on how to create your own.
#'
#' @param x,y transformers for x and y axes
#' @param xtrans,ytrans Deprecated; use `x` and `y` instead.
#' @param limx,limy limits for x and y axes. (Named so for backward
#' compatibility)
#' @param clip Should drawing be clipped to the extent of the plot panel? A
#' setting of `"on"` (the default) means yes, and a setting of `"off"`
#' means no. For details, please see [`coord_cartesian()`].
#' @inheritParams coord_cartesian
#' @param x,y Transformers for x and y axes or their names.
#' @param limx,limy **Deprecated**: use `xlim` and `ylim` instead.
#' @export
#' @examples
#' \donttest{
Expand Down Expand Up @@ -78,31 +74,25 @@
#' plot + coord_trans(x = "log10")
#' plot + coord_trans(x = "sqrt")
#' }
coord_trans <- function(x = "identity", y = "identity", limx = NULL, limy = NULL, clip = "on",
xtrans, ytrans)
{
if (!missing(xtrans)) {
gg_dep("1.0.1", "`xtrans` arguments is deprecated; please use `x` instead.")
x <- xtrans
coord_trans <- function(x = "identity", y = "identity", xlim = NULL, ylim = NULL,
limx = "DEPRECATED", limy = "DEPRECATED", clip = "on", expand = TRUE) {
if (!missing(limx)) {
warning("`limx` argument is deprecated; please use `xlim` instead.", call. = FALSE)
xlim <- limx
}
if (!missing(ytrans)) {
gg_dep("1.0.1", "`ytrans` arguments is deprecated; please use `y` instead.")
y <- ytrans
if (!missing(limy)) {
warning("`limy` argument is deprecated; please use `ylim` instead.", call. = FALSE)
ylim <- limy
}

# @kohske
# Now limits are implemented.
# But for backward compatibility, xlim -> limx, ylim -> ylim
# Because there are many examples such as
# > coord_trans(x = "log10", y = "log10")
# Maybe this is changed.
# resolve transformers
if (is.character(x)) x <- as.trans(x)
if (is.character(y)) y <- as.trans(y)


ggproto(NULL, CoordTrans,
trans = list(x = x, y = y),
limits = list(x = limx, y = limy),
limits = list(x = xlim, y = ylim),
expand = expand,
clip = clip
)
}
Expand Down Expand Up @@ -147,8 +137,8 @@ CoordTrans <- ggproto("CoordTrans", Coord,

setup_panel_params = function(self, scale_x, scale_y, params = list()) {
c(
train_trans(scale_x, self$limits$x, self$trans$x, "x"),
train_trans(scale_y, self$limits$y, self$trans$y, "y")
train_trans(scale_x, self$limits$x, self$trans$x, "x", self$expand),
train_trans(scale_y, self$limits$y, self$trans$y, "y", self$expand)
)
},

Expand Down Expand Up @@ -187,39 +177,51 @@ transform_value <- function(trans, value, range) {
rescale(trans$transform(value), 0:1, range)
}


train_trans <- function(scale, limits, trans, name) {
# first, calculate the range that is the numerical limits in data space

# expand defined by scale OR coord
# @kohske
# Expansion of data range sometimes go beyond domain,
# so in trans, expansion takes place at the final stage.
if (is.null(limits)) {
range <- scale$dimension()
train_trans <- function(scale, coord_limits, trans, name, expand = TRUE) {
expansion <- default_expansion(scale, expand = expand)
scale_trans <- scale$trans %||% identity_trans()
coord_limits <- coord_limits %||% scale_trans$inverse(c(NA, NA))

if (scale$is_discrete()) {
continuous_ranges <- expand_limits_discrete_trans(
scale$get_limits(),
expansion,
coord_limits,
trans,
range_continuous = scale$range_c$range
)
} else {
range <- range(scale$transform(limits))
# transform user-specified limits to scale transformed space
coord_limits <- scale$trans$transform(coord_limits)
continuous_ranges <- expand_limits_continuous_trans(
scale$get_limits(),
expansion,
coord_limits,
trans
)
}

# breaks on data space
out <- scale$break_info(range)

# trans'd range
out$range <- trans$transform(out$range)
# calculate break information
out <- scale$break_info(continuous_ranges$continuous_range)

# expansion if limits are not specified
if (is.null(limits)) {
expand <- expand_default(scale)
out$range <- expand_range(out$range, expand[1], expand[2])
}
# range in coord space has already been calculated
# needs to be in increasing order for transform_value() to work
out$range <- range(continuous_ranges$continuous_range_coord)

# major and minor values in plot space
# major and minor values in coordinate data
out$major_source <- transform_value(trans, out$major_source, out$range)
out$minor_source <- transform_value(trans, out$minor_source, out$range)
out$sec.major_source <- transform_value(trans, out$sec.major_source, out$range)
out$sec.minor_source <- transform_value(trans, out$sec.minor_source, out$range)

out <- list(
range = out$range, labels = out$labels,
major = out$major_source, minor = out$minor_source
range = out$range,
labels = out$labels,
major = out$major_source,
minor = out$minor_source,
sec.labels = out$sec.labels,
sec.major = out$sec.major_source,
sec.minor = out$sec.minor_source
)
names(out) <- paste(name, names(out), sep = ".")
out
Expand Down
Loading