From 5719f08a051ef101fafc3aaad38b0e79e976e13d Mon Sep 17 00:00:00 2001 From: nmercadeb Date: Thu, 15 Aug 2024 14:40:25 -0700 Subject: [PATCH 1/7] rename coord_trans to coord_transform, issue #5825 --- NAMESPACE | 1 + NEWS.md | 17 +- R/annotation-logticks.R | 6 +- R/coord-.R | 4 +- R/coord-transform.R | 247 +++++++++----- R/geom-histogram.R | 4 +- R/geom-violin.R | 4 +- R/guide-axis-logticks.R | 4 +- R/stat-summary.R | 2 +- R/summarise-plot.R | 2 +- _pkgdown.yml | 2 +- man/annotation_logticks.Rd | 6 +- man/coord_trans.Rd | 6 +- man/coord_transform.Rd | 114 +++++++ man/geom_histogram.Rd | 4 +- man/geom_violin.Rd | 4 +- man/ggplot2-ggproto.Rd | 4 +- man/guide_axis_logticks.Rd | 4 +- man/stat_summary.Rd | 2 +- man/summarise_plot.Rd | 2 +- tests/testthat/_snaps/coord-transform.md | 2 +- .../basic-coord-trans-plot.svg | 2 +- .../basic-coord-transform-plot.svg | 291 ++++++++++++++++ .../sec-axis-with-coord-trans.svg | 2 +- .../sec-axis-with-coord-transform.svg | 317 ++++++++++++++++++ .../guides/guide-titles-with-coord-trans.svg | 2 +- tests/testthat/test-coord-train.R | 2 +- tests/testthat/test-coord-transform.R | 50 +-- tests/testthat/test-geom-hex.R | 2 +- tests/testthat/test-guides.R | 4 +- tests/testthat/test-plot-summary-api.R | 2 +- 31 files changed, 968 insertions(+), 147 deletions(-) create mode 100644 man/coord_transform.Rd create mode 100644 tests/testthat/_snaps/coord-transform/basic-coord-transform-plot.svg create mode 100644 tests/testthat/_snaps/coord-transform/sec-axis-with-coord-transform.svg diff --git a/NAMESPACE b/NAMESPACE index 6a57c5132d..7f26588e1e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -318,6 +318,7 @@ export(coord_quickmap) export(coord_radial) export(coord_sf) export(coord_trans) +export(coord_transform) export(cut_interval) export(cut_number) export(cut_width) diff --git a/NEWS.md b/NEWS.md index 4c0ea1e891..bc1bddb995 100644 --- a/NEWS.md +++ b/NEWS.md @@ -133,6 +133,7 @@ (@teunbrand, #5938, #4327). * Fixed bug where empty discrete scales weren't recognised as such (@teunbrand, #5945). +* `coord_trans()` renamed to `coord_transform()` (@nmercadeb, #5825). # ggplot2 3.5.1 @@ -750,7 +751,7 @@ gains in rendering speed. * `geom_linerange()` now respects the `na.rm` argument (#4927, @thomasp85) -* Improve the support for `guide_axis()` on `coord_trans()` +* Improve the support for `guide_axis()` on `coord_transform()` (@yutannihilation, #3959) * Added `stat_align()` to align data without common x-coordinates prior to @@ -1194,17 +1195,17 @@ fail. ## Minor improvements and bug fixes -* `coord_trans()` now draws second axes and accepts `xlim`, `ylim`, +* `coord_transform()` 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 +* `coord_transform()` 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()` + which resulted in differences between plots made with `coord_transform()` and those made with `coord_cartesian()`). The expansion for discrete axes - in `coord_trans()` was also updated such that it behaves identically + in `coord_transform()` was also updated such that it behaves identically to that in `coord_cartesian()` (@paleolimbot, #3338). * `expand_scale()` was deprecated in favour of `expansion()` for setting @@ -1544,7 +1545,7 @@ accompanying issue #2890. (@mikmart, #2488). * `geom_hline()`, `geom_vline()`, and `geom_abline()` now work properly - with `coord_trans()` (@clauswilke, #2149, #2812). + with `coord_transform()` (@clauswilke, #2149, #2812). * `geom_text(..., parse = TRUE)` now correctly renders the expected number of items instead of silently dropping items that are empty expressions, e.g. @@ -1987,7 +1988,7 @@ accompanying issue #2890. (@dylan-stark, #2072), and can draw the radius axis on the right (@thomasp85, #2005). -* `coord_trans()` now generates a warning when a transformation generates +* `coord_transform()` now generates a warning when a transformation generates non-finite values (@foo-bar-baz-qux, #2147). ### Themes @@ -2816,7 +2817,7 @@ version of ggplot. * `coord_cartesian()` applies the same expansion factor to limits as for scales. You can suppress with `expand = FALSE` (#1207). -* `coord_trans()` now works when breaks are suppressed (#1422). +* `coord_transform()` now works when breaks are suppressed (#1422). * `cut_number()` gives error message if the number of requested bins can be created because there are two few unique values (#1046). diff --git a/R/annotation-logticks.R b/R/annotation-logticks.R index 33f0a952a4..7deb7684f9 100644 --- a/R/annotation-logticks.R +++ b/R/annotation-logticks.R @@ -24,7 +24,7 @@ #' @param scaled is the data already log-scaled? This should be `TRUE` #' (default) when the data is already transformed with `log10()` or when #' using `scale_y_log10()`. It should be `FALSE` when using -#' `coord_trans(y = "log10")`. +#' `coord_transform(y = "log10")`. #' @param colour Colour of the tick marks. #' @param linewidth Thickness of tick marks, in mm. #' @param linetype Linetype of tick marks (`solid`, `dashed`, etc.) @@ -36,7 +36,7 @@ #' @export #' @seealso [scale_y_continuous()], [scale_y_log10()] for log scale #' transformations. -#' @seealso [coord_trans()] for log coordinate transformations. +#' @seealso [coord_transform()] for log coordinate transformations. #' #' @examples #' # Make a log-log plot (without log ticks) @@ -75,7 +75,7 @@ #' # Using a coordinate transform requires scaled = FALSE #' t <- ggplot(msleep, aes(bodywt, brainwt)) + #' geom_point() + -#' coord_trans(x = "log10", y = "log10") + +#' coord_transform(x = "log10", y = "log10") + #' theme_bw() #' t + annotation_logticks(scaled = FALSE) #' diff --git a/R/coord-.R b/R/coord-.R index 6736059fbc..768af08879 100644 --- a/R/coord-.R +++ b/R/coord-.R @@ -1,6 +1,6 @@ #' @section Coordinate systems: #' -#' All `coord_*()` functions (like `coord_trans()`) return a `Coord*` +#' All `coord_*()` functions (like `coord_transform()`) return a `Coord*` #' object (like `CoordTrans`). #' #' Each of the `Coord*` objects is a [ggproto()] object, @@ -16,7 +16,7 @@ #' - `backtransform_range(panel_params)`: Extracts the panel range provided #' in `panel_params` (created by `setup_panel_params()`, see below) and #' back-transforms to data coordinates. This back-transformation can be needed -#' for coords such as `coord_trans()` where the range in the transformed +#' for coords such as `coord_transform()` where the range in the transformed #' coordinates differs from the range in the untransformed coordinates. Returns #' a list of two ranges, `x` and `y`, and these correspond to the variables #' mapped to the `x` and `y` aesthetics, even for coords such as `coord_flip()` diff --git a/R/coord-transform.R b/R/coord-transform.R index 83ffd7b9ee..69e549ff9f 100644 --- a/R/coord-transform.R +++ b/R/coord-transform.R @@ -1,6 +1,6 @@ #' Transformed Cartesian coordinate system #' -#' `coord_trans()` is different to scale transformations in that it occurs after +#' `coord_transform()` is different to scale transformations in that it occurs after #' statistical transformation and will affect the visual appearance of geoms - there is #' no guarantee that straight lines will continue to be straight. #' @@ -30,7 +30,7 @@ #' # * by transforming the coordinate system: #' ggplot(diamonds, aes(carat, price)) + #' geom_point() + -#' coord_trans(x = "log10", y = "log10") +#' coord_transform(x = "log10", y = "log10") #' #' # The difference between transforming the scales and #' # transforming the coordinate system is that scale @@ -49,7 +49,7 @@ #' ggplot(d, aes(carat, price)) + #' geom_point() + #' geom_smooth(method = "lm") + -#' coord_trans(x = "log10", y = "log10") +#' coord_transform(x = "log10", y = "log10") #' #' # Here I used a subset of diamonds so that the smoothed line didn't #' # drop below zero, which obviously causes problems on the log-transformed @@ -62,7 +62,7 @@ #' geom_smooth(method = "lm") + #' scale_x_log10() + #' scale_y_log10() + -#' coord_trans(x = scales::transform_exp(10), y = scales::transform_exp(10)) +#' coord_transform(x = scales::transform_exp(10), y = scales::transform_exp(10)) #' #' # cf. #' ggplot(diamonds, aes(carat, price)) + @@ -74,17 +74,17 @@ #' df <- data.frame(a = abs(rnorm(26)),letters) #' plot <- ggplot(df,aes(a,letters)) + geom_point() #' -#' plot + coord_trans(x = "log10") -#' plot + coord_trans(x = "sqrt") +#' plot + coord_transform(x = "log10") +#' plot + coord_transform(x = "sqrt") #' } -coord_trans <- function(x = "identity", y = "identity", xlim = NULL, ylim = NULL, - limx = deprecated(), limy = deprecated(), clip = "on", expand = TRUE) { +coord_transform <- function(x = "identity", y = "identity", xlim = NULL, ylim = NULL, + limx = deprecated(), limy = deprecated(), clip = "on", expand = TRUE) { if (lifecycle::is_present(limx)) { - deprecate_warn0("3.3.0", "coord_trans(limx)", "coord_trans(xlim)") + deprecate_warn0("3.3.0", "coord_transform(limx)", "coord_transform(xlim)") xlim <- limx } if (lifecycle::is_present(limy)) { - deprecate_warn0("3.3.0", "coord_trans(limy)", "coord_trans(ylim)") + deprecate_warn0("3.3.0", "coord_transform(limy)", "coord_transform(ylim)") ylim <- limy } @@ -96,91 +96,185 @@ coord_trans <- function(x = "identity", y = "identity", xlim = NULL, ylim = NULL if (is.character(y)) y <- as.transform(y) ggproto(NULL, CoordTrans, - trans = list(x = x, y = y), - limits = list(x = xlim, y = ylim), - expand = expand, - clip = clip + trans = list(x = x, y = y), + limits = list(x = xlim, y = ylim), + expand = expand, + clip = clip ) } +#' Transformed Cartesian coordinate system +#' +#' `r lifecycle::badge("deprecated")` +#' +#' `coord_trans()` is different to scale transformations in that it occurs after +#' statistical transformation and will affect the visual appearance of geoms - there is +#' no guarantee that straight lines will continue to be straight. +#' +#' Transformations only work with continuous values: see +#' [scales::new_transform()] for list of transformations, and instructions +#' on how to create your own. +#' +#' @inheritParams coord_cartesian +#' @param x,y Transformers for x and y axes or their names. +#' @param limx,limy `r lifecycle::badge("deprecated")` use `xlim` and `ylim` instead. +#' @seealso +#' The `r link_book("coord transformations section", "coord#transformations-with-coord_trans")` +#' @export +#' @examples +#' \donttest{ +#' # See ?geom_boxplot for other examples +#' +#' # Three ways of doing transformation in ggplot: +#' # * by transforming the data +#' ggplot(diamonds, aes(log10(carat), log10(price))) + +#' geom_point() +#' # * by transforming the scales +#' ggplot(diamonds, aes(carat, price)) + +#' geom_point() + +#' scale_x_log10() + +#' scale_y_log10() +#' # * by transforming the coordinate system: +#' ggplot(diamonds, aes(carat, price)) + +#' geom_point() + +#' coord_trans(x = "log10", y = "log10") +#' +#' # The difference between transforming the scales and +#' # transforming the coordinate system is that scale +#' # transformation occurs BEFORE statistics, and coordinate +#' # transformation afterwards. Coordinate transformation also +#' # changes the shape of geoms: +#' +#' d <- subset(diamonds, carat > 0.5) +#' +#' ggplot(d, aes(carat, price)) + +#' geom_point() + +#' geom_smooth(method = "lm") + +#' scale_x_log10() + +#' scale_y_log10() +#' +#' ggplot(d, aes(carat, price)) + +#' geom_point() + +#' geom_smooth(method = "lm") + +#' coord_trans(x = "log10", y = "log10") +#' +#' # Here I used a subset of diamonds so that the smoothed line didn't +#' # drop below zero, which obviously causes problems on the log-transformed +#' # scale +#' +#' # With a combination of scale and coordinate transformation, it's +#' # possible to do back-transformations: +#' ggplot(diamonds, aes(carat, price)) + +#' geom_point() + +#' geom_smooth(method = "lm") + +#' scale_x_log10() + +#' scale_y_log10() + +#' coord_trans(x = scales::transform_exp(10), y = scales::transform_exp(10)) +#' +#' # cf. +#' ggplot(diamonds, aes(carat, price)) + +#' geom_point() + +#' geom_smooth(method = "lm") +#' +#' # Also works with discrete scales +#' set.seed(1) +#' df <- data.frame(a = abs(rnorm(26)),letters) +#' plot <- ggplot(df,aes(a,letters)) + geom_point() +#' +#' plot + coord_trans(x = "log10") +#' plot + coord_trans(x = "sqrt") +#' } +coord_trans <- function(x = "identity", y = "identity", xlim = NULL, ylim = NULL, + limx = deprecated(), limy = deprecated(), clip = "on", expand = TRUE) { + deprecate_soft0( + "3.5.2", + "coord_trans()", + "coord_transform()" + ) + + coord_transform( + x = x, y = y, xlim = xlim, ylim = ylim, + limx = limx, limy = limy, clip = clip, expand = expand + ) +} #' @rdname ggplot2-ggproto #' @format NULL #' @usage NULL #' @export CoordTrans <- ggproto("CoordTrans", Coord, - is_free = function() TRUE, - distance = function(self, x, y, panel_params) { - max_dist <- dist_euclidean(panel_params$x.range, panel_params$y.range) - dist_euclidean(self$trans$x$transform(x), self$trans$y$transform(y)) / max_dist - }, + is_free = function() TRUE, + distance = function(self, x, y, panel_params) { + max_dist <- dist_euclidean(panel_params$x.range, panel_params$y.range) + dist_euclidean(self$trans$x$transform(x), self$trans$y$transform(y)) / max_dist + }, - backtransform_range = function(self, panel_params) { - list( - x = self$trans$x$inverse(panel_params$x.range), - y = self$trans$y$inverse(panel_params$y.range) - ) - }, + backtransform_range = function(self, panel_params) { + list( + x = self$trans$x$inverse(panel_params$x.range), + y = self$trans$y$inverse(panel_params$y.range) + ) + }, - range = function(self, panel_params) { - list( - x = panel_params$x.range, - y = panel_params$y.range - ) - }, + range = function(self, panel_params) { + list( + x = panel_params$x.range, + y = panel_params$y.range + ) + }, - transform = function(self, data, panel_params) { - # trans_x() and trans_y() needs to keep Inf values because this can be called - # in guide_transform.axis() - trans_x <- function(data) { - idx <- !is.infinite(data) - data[idx] <- transform_value(self$trans$x, data[idx], panel_params$x.range) - data - } - trans_y <- function(data) { - idx <- !is.infinite(data) - data[idx] <- transform_value(self$trans$y, data[idx], panel_params$y.range) - data - } + transform = function(self, data, panel_params) { + # trans_x() and trans_y() needs to keep Inf values because this can be called + # in guide_transform.axis() + trans_x <- function(data) { + idx <- !is.infinite(data) + data[idx] <- transform_value(self$trans$x, data[idx], panel_params$x.range) + data + } + trans_y <- function(data) { + idx <- !is.infinite(data) + data[idx] <- transform_value(self$trans$y, data[idx], panel_params$y.range) + data + } - new_data <- transform_position(data, trans_x, trans_y) + new_data <- transform_position(data, trans_x, trans_y) - warn_new_infinites(data$x, new_data$x, "x") - warn_new_infinites(data$y, new_data$y, "y") + warn_new_infinites(data$x, new_data$x, "x") + warn_new_infinites(data$y, new_data$y, "y") - transform_position(new_data, squish_infinite, squish_infinite) - }, + transform_position(new_data, squish_infinite, squish_infinite) + }, - setup_panel_params = function(self, scale_x, scale_y, params = list()) { - c( - view_scales_from_scale_with_coord_trans(scale_x, self$limits$x, self$trans$x, self$expand), - view_scales_from_scale_with_coord_trans(scale_y, self$limits$y, self$trans$y, self$expand) - ) - }, + setup_panel_params = function(self, scale_x, scale_y, params = list()) { + c( + view_scales_from_scale_with_coord_trans(scale_x, self$limits$x, self$trans$x, self$expand), + view_scales_from_scale_with_coord_trans(scale_y, self$limits$y, self$trans$y, self$expand) + ) + }, - render_bg = function(panel_params, theme) { - guide_grid( - theme, - panel_params$x.minor, - panel_params$x.major, - panel_params$y.minor, - panel_params$y.major - ) - }, + render_bg = function(panel_params, theme) { + guide_grid( + theme, + panel_params$x.minor, + panel_params$x.major, + panel_params$y.minor, + panel_params$y.major + ) + }, - render_axis_h = function(panel_params, theme) { - list( - top = panel_guides_grob(panel_params$guides, position = "top", theme = theme), - bottom = panel_guides_grob(panel_params$guides, position = "bottom", theme = theme) - ) - }, + render_axis_h = function(panel_params, theme) { + list( + top = panel_guides_grob(panel_params$guides, position = "top", theme = theme), + bottom = panel_guides_grob(panel_params$guides, position = "bottom", theme = theme) + ) + }, - render_axis_v = function(panel_params, theme) { - list( - left = panel_guides_grob(panel_params$guides, position = "left", theme = theme), - right = panel_guides_grob(panel_params$guides, position = "right", theme = theme) - ) - } + render_axis_v = function(panel_params, theme) { + list( + left = panel_guides_grob(panel_params$guides, position = "left", theme = theme), + right = panel_guides_grob(panel_params$guides, position = "right", theme = theme) + ) + } ) transform_value <- function(trans, value, range) { @@ -258,3 +352,4 @@ warn_new_infinites <- function(old_values, new_values, axis, call = caller_env() cli::cli_warn("Transformation introduced infinite values in {axis}-axis", call = call) } } + diff --git a/R/geom-histogram.R b/R/geom-histogram.R index dafc181f15..1f0765bc59 100644 --- a/R/geom-histogram.R +++ b/R/geom-histogram.R @@ -95,11 +95,11 @@ #' # no observations have 0 ratings. #' m + #' geom_histogram(boundary = 0) + -#' coord_trans(x = "log10") +#' coord_transform(x = "log10") #' # Use boundary = 0, to make sure we don't take sqrt of negative values #' m + #' geom_histogram(boundary = 0) + -#' coord_trans(x = "sqrt") +#' coord_transform(x = "sqrt") #' #' # You can also transform the y axis. Remember that the base of the bars #' # has value 0, so log transformations are not appropriate diff --git a/R/geom-violin.R b/R/geom-violin.R index 0ac6cd29df..21cd333455 100644 --- a/R/geom-violin.R +++ b/R/geom-violin.R @@ -75,10 +75,10 @@ #' scale_y_log10() #' m + #' geom_violin() + -#' coord_trans(y = "log10") +#' coord_transform(y = "log10") #' m + #' geom_violin() + -#' scale_y_log10() + coord_trans(y = "log10") +#' scale_y_log10() + coord_transform(y = "log10") #' #' # Violin plots with continuous x: #' # Use the group aesthetic to group observations in violins diff --git a/R/guide-axis-logticks.R b/R/guide-axis-logticks.R index 37273cba06..fd610ebb2d 100644 --- a/R/guide-axis-logticks.R +++ b/R/guide-axis-logticks.R @@ -13,7 +13,7 @@ NULL #' @param prescale.base Base of logarithm used to transform data manually. The #' default, `NULL`, will use the scale transformation to calculate positions. #' Only set `prescale.base` if the data has already been log-transformed. -#' When using a log-transform in the position scale or in `coord_trans()`, +#' When using a log-transform in the position scale or in `coord_transform()`, #' keep the default `NULL` argument. #' @param negative.small When the scale limits include 0 or negative numbers, #' what should be the smallest absolute value that is marked with a tick? @@ -39,7 +39,7 @@ NULL #' scale_y_log10(guide = "axis_logticks") #' #' # Or with log-transformed coordinates -#' p + coord_trans(x = "log10", y = "log10") + +#' p + coord_transform(x = "log10", y = "log10") + #' guides(x = "axis_logticks", y = "axis_logticks") #' #' # When data is transformed manually, one should provide `prescale.base` diff --git a/R/stat-summary.R b/R/stat-summary.R index ddcb7b5ae3..d61ab2dd23 100644 --- a/R/stat-summary.R +++ b/R/stat-summary.R @@ -123,7 +123,7 @@ #' # statistic has been computed. This means we're calculating the summary on the raw data #' # and stretching the geoms onto the log scale. Compare the widths of the #' # standard errors. -#' m2 + coord_trans(y="log10") +#' m2 + coord_transform(y="log10") #' } #' } stat_summary <- function(mapping = NULL, data = NULL, diff --git a/R/summarise-plot.R b/R/summarise-plot.R index 9411c1c586..4c4c1f99f7 100644 --- a/R/summarise-plot.R +++ b/R/summarise-plot.R @@ -33,7 +33,7 @@ #' @section Coord summary: #' #' The function `summarise_coord()` returns information about the log base for -#' coordinates that are log-transformed in `coord_trans()`, and it also indicates +#' coordinates that are log-transformed in `coord_transform()`, and it also indicates #' whether the coord has flipped the x and y axes. #' #' @section Layer summary: diff --git a/_pkgdown.yml b/_pkgdown.yml index 1e4ea6a727..cc542a9071 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -164,7 +164,7 @@ reference: The coordinate system determines how the `x` and `y` aesthetics combine to position elements in the plot. The default coordinate system is Cartesian (`coord_cartesian()`), which can be tweaked with `coord_map()`, - `coord_fixed()`, `coord_flip()`, and `coord_trans()`, or completely + `coord_fixed()`, `coord_flip()`, and `coord_transform()`, or completely replaced with `coord_polar()`. contents: - coord_cartesian diff --git a/man/annotation_logticks.Rd b/man/annotation_logticks.Rd index 490a7d3b17..b37a54560d 100644 --- a/man/annotation_logticks.Rd +++ b/man/annotation_logticks.Rd @@ -35,7 +35,7 @@ of the plot area. Default is off (\code{FALSE}). You will also need to use \item{scaled}{is the data already log-scaled? This should be \code{TRUE} (default) when the data is already transformed with \code{log10()} or when using \code{scale_y_log10()}. It should be \code{FALSE} when using -\code{coord_trans(y = "log10")}.} +\code{coord_transform(y = "log10")}.} \item{short}{a \code{\link[grid:unit]{grid::unit()}} object specifying the length of the short tick marks} @@ -105,7 +105,7 @@ b + annotation_logticks() # Using a coordinate transform requires scaled = FALSE t <- ggplot(msleep, aes(bodywt, brainwt)) + geom_point() + - coord_trans(x = "log10", y = "log10") + + coord_transform(x = "log10", y = "log10") + theme_bw() t + annotation_logticks(scaled = FALSE) @@ -120,5 +120,5 @@ a + annotation_logticks( \code{\link[=scale_y_continuous]{scale_y_continuous()}}, \code{\link[=scale_y_log10]{scale_y_log10()}} for log scale transformations. -\code{\link[=coord_trans]{coord_trans()}} for log coordinate transformations. +\code{\link[=coord_transform]{coord_transform()}} for log coordinate transformations. } diff --git a/man/coord_trans.Rd b/man/coord_trans.Rd index bea5b54716..617b513856 100644 --- a/man/coord_trans.Rd +++ b/man/coord_trans.Rd @@ -36,11 +36,13 @@ the limits to ensure that data and axes don't overlap. If \code{FALSE}, limits are taken exactly from the data or \code{xlim}/\code{ylim}.} } \description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} +} +\details{ \code{coord_trans()} is different to scale transformations in that it occurs after statistical transformation and will affect the visual appearance of geoms - there is no guarantee that straight lines will continue to be straight. -} -\details{ + Transformations only work with continuous values: see \code{\link[scales:new_transform]{scales::new_transform()}} for list of transformations, and instructions on how to create your own. diff --git a/man/coord_transform.Rd b/man/coord_transform.Rd new file mode 100644 index 0000000000..950bf3e06e --- /dev/null +++ b/man/coord_transform.Rd @@ -0,0 +1,114 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/coord-transform.R +\name{coord_transform} +\alias{coord_transform} +\title{Transformed Cartesian coordinate system} +\usage{ +coord_transform( + x = "identity", + y = "identity", + xlim = NULL, + ylim = NULL, + limx = deprecated(), + limy = deprecated(), + clip = "on", + expand = TRUE +) +} +\arguments{ +\item{x, y}{Transformers for x and y axes or their names.} + +\item{xlim, ylim}{Limits for the x and y axes.} + +\item{limx, limy}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} use \code{xlim} and \code{ylim} instead.} + +\item{clip}{Should drawing be clipped to the extent of the plot panel? A +setting of \code{"on"} (the default) means yes, and a setting of \code{"off"} +means no. In most cases, the default of \code{"on"} should not be changed, +as setting \code{clip = "off"} can cause unexpected results. It allows +drawing of data points anywhere on the plot, including in the plot margins. If +limits are set via \code{xlim} and \code{ylim} and some data points fall outside those +limits, then those data points may show up in places such as the axes, the +legend, the plot title, or the plot margins.} + +\item{expand}{If \code{TRUE}, the default, adds a small expansion factor to +the limits to ensure that data and axes don't overlap. If \code{FALSE}, +limits are taken exactly from the data or \code{xlim}/\code{ylim}.} +} +\description{ +\code{coord_transform()} is different to scale transformations in that it occurs after +statistical transformation and will affect the visual appearance of geoms - there is +no guarantee that straight lines will continue to be straight. +} +\details{ +Transformations only work with continuous values: see +\code{\link[scales:new_transform]{scales::new_transform()}} for list of transformations, and instructions +on how to create your own. +} +\examples{ +\donttest{ +# See ?geom_boxplot for other examples + +# Three ways of doing transformation in ggplot: +# * by transforming the data +ggplot(diamonds, aes(log10(carat), log10(price))) + + geom_point() +# * by transforming the scales +ggplot(diamonds, aes(carat, price)) + + geom_point() + + scale_x_log10() + + scale_y_log10() +# * by transforming the coordinate system: +ggplot(diamonds, aes(carat, price)) + + geom_point() + + coord_transform(x = "log10", y = "log10") + +# The difference between transforming the scales and +# transforming the coordinate system is that scale +# transformation occurs BEFORE statistics, and coordinate +# transformation afterwards. Coordinate transformation also +# changes the shape of geoms: + +d <- subset(diamonds, carat > 0.5) + +ggplot(d, aes(carat, price)) + + geom_point() + + geom_smooth(method = "lm") + + scale_x_log10() + + scale_y_log10() + +ggplot(d, aes(carat, price)) + + geom_point() + + geom_smooth(method = "lm") + + coord_transform(x = "log10", y = "log10") + +# Here I used a subset of diamonds so that the smoothed line didn't +# drop below zero, which obviously causes problems on the log-transformed +# scale + +# With a combination of scale and coordinate transformation, it's +# possible to do back-transformations: +ggplot(diamonds, aes(carat, price)) + + geom_point() + + geom_smooth(method = "lm") + + scale_x_log10() + + scale_y_log10() + + coord_transform(x = scales::transform_exp(10), y = scales::transform_exp(10)) + +# cf. +ggplot(diamonds, aes(carat, price)) + + geom_point() + + geom_smooth(method = "lm") + +# Also works with discrete scales +set.seed(1) +df <- data.frame(a = abs(rnorm(26)),letters) +plot <- ggplot(df,aes(a,letters)) + geom_point() + +plot + coord_transform(x = "log10") +plot + coord_transform(x = "sqrt") +} +} +\seealso{ +The \href{https://ggplot2-book.org/coord#transformations-with-coord_trans}{coord transformations section} of the online ggplot2 book. +} diff --git a/man/geom_histogram.Rd b/man/geom_histogram.Rd index 1f290dbcdc..02003284ca 100644 --- a/man/geom_histogram.Rd +++ b/man/geom_histogram.Rd @@ -287,11 +287,11 @@ m + # no observations have 0 ratings. m + geom_histogram(boundary = 0) + - coord_trans(x = "log10") + coord_transform(x = "log10") # Use boundary = 0, to make sure we don't take sqrt of negative values m + geom_histogram(boundary = 0) + - coord_trans(x = "sqrt") + coord_transform(x = "sqrt") # You can also transform the y axis. Remember that the base of the bars # has value 0, so log transformations are not appropriate diff --git a/man/geom_violin.Rd b/man/geom_violin.Rd index 974d1c5bdc..d216c704b3 100644 --- a/man/geom_violin.Rd +++ b/man/geom_violin.Rd @@ -250,10 +250,10 @@ m + scale_y_log10() m + geom_violin() + - coord_trans(y = "log10") + coord_transform(y = "log10") m + geom_violin() + - scale_y_log10() + coord_trans(y = "log10") + scale_y_log10() + coord_transform(y = "log10") # Violin plots with continuous x: # Use the group aesthetic to group observations in violins diff --git a/man/ggplot2-ggproto.Rd b/man/ggplot2-ggproto.Rd index c3384f1e45..cf3325f1f3 100644 --- a/man/ggplot2-ggproto.Rd +++ b/man/ggplot2-ggproto.Rd @@ -213,7 +213,7 @@ See also the \href{https://ggplot2-book.org/extensions#sec-new-geoms}{new geoms \section{Coordinate systems}{ -All \verb{coord_*()} functions (like \code{coord_trans()}) return a \verb{Coord*} +All \verb{coord_*()} functions (like \code{coord_transform()}) return a \verb{Coord*} object (like \code{CoordTrans}). Each of the \verb{Coord*} objects is a \code{\link[=ggproto]{ggproto()}} object, @@ -229,7 +229,7 @@ object, you typically will want to implement one or more of the following: \item \code{backtransform_range(panel_params)}: Extracts the panel range provided in \code{panel_params} (created by \code{setup_panel_params()}, see below) and back-transforms to data coordinates. This back-transformation can be needed -for coords such as \code{coord_trans()} where the range in the transformed +for coords such as \code{coord_transform()} where the range in the transformed coordinates differs from the range in the untransformed coordinates. Returns a list of two ranges, \code{x} and \code{y}, and these correspond to the variables mapped to the \code{x} and \code{y} aesthetics, even for coords such as \code{coord_flip()} diff --git a/man/guide_axis_logticks.Rd b/man/guide_axis_logticks.Rd index b6f7d55737..3f52602db8 100644 --- a/man/guide_axis_logticks.Rd +++ b/man/guide_axis_logticks.Rd @@ -29,7 +29,7 @@ values of the \code{axis.ticks.length} theme setting.} \item{prescale.base}{Base of logarithm used to transform data manually. The default, \code{NULL}, will use the scale transformation to calculate positions. Only set \code{prescale.base} if the data has already been log-transformed. -When using a log-transform in the position scale or in \code{coord_trans()}, +When using a log-transform in the position scale or in \code{coord_transform()}, keep the default \code{NULL} argument.} \item{negative.small}{When the scale limits include 0 or negative numbers, @@ -97,7 +97,7 @@ p + scale_x_log10(guide = "axis_logticks") + scale_y_log10(guide = "axis_logticks") # Or with log-transformed coordinates -p + coord_trans(x = "log10", y = "log10") + +p + coord_transform(x = "log10", y = "log10") + guides(x = "axis_logticks", y = "axis_logticks") # When data is transformed manually, one should provide `prescale.base` diff --git a/man/stat_summary.Rd b/man/stat_summary.Rd index 3ebf979e54..8a990cd8d6 100644 --- a/man/stat_summary.Rd +++ b/man/stat_summary.Rd @@ -299,7 +299,7 @@ m2 + scale_y_log10() # statistic has been computed. This means we're calculating the summary on the raw data # and stretching the geoms onto the log scale. Compare the widths of the # standard errors. -m2 + coord_trans(y="log10") +m2 + coord_transform(y="log10") } } } diff --git a/man/summarise_plot.Rd b/man/summarise_plot.Rd index 6be6635876..39ba6fb7d4 100644 --- a/man/summarise_plot.Rd +++ b/man/summarise_plot.Rd @@ -54,7 +54,7 @@ returned by \code{summarise_plot()}. The function \code{summarise_coord()} returns information about the log base for -coordinates that are log-transformed in \code{coord_trans()}, and it also indicates +coordinates that are log-transformed in \code{coord_transform()}, and it also indicates whether the coord has flipped the x and y axes. } diff --git a/tests/testthat/_snaps/coord-transform.md b/tests/testthat/_snaps/coord-transform.md index def35a0f27..91556ea24a 100644 --- a/tests/testthat/_snaps/coord-transform.md +++ b/tests/testthat/_snaps/coord-transform.md @@ -1,4 +1,4 @@ -# coord_trans() throws error when limits are badly specified +# coord_transform() throws error when limits are badly specified `xlim` must be a vector of length 2, not a object. diff --git a/tests/testthat/_snaps/coord-transform/basic-coord-trans-plot.svg b/tests/testthat/_snaps/coord-transform/basic-coord-trans-plot.svg index 6e150c767f..7b142fed5f 100644 --- a/tests/testthat/_snaps/coord-transform/basic-coord-trans-plot.svg +++ b/tests/testthat/_snaps/coord-transform/basic-coord-trans-plot.svg @@ -286,6 +286,6 @@ suv class hwy -basic coord_trans() plot +basic coord_transform() plot diff --git a/tests/testthat/_snaps/coord-transform/basic-coord-transform-plot.svg b/tests/testthat/_snaps/coord-transform/basic-coord-transform-plot.svg new file mode 100644 index 0000000000..7d103a7626 --- /dev/null +++ b/tests/testthat/_snaps/coord-transform/basic-coord-transform-plot.svg @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +20 +30 +40 + + + + + + + + + + +2seater +compact +midsize +minivan +pickup +subcompact +suv +class +hwy +basic coord_transform() plot + + diff --git a/tests/testthat/_snaps/coord-transform/sec-axis-with-coord-trans.svg b/tests/testthat/_snaps/coord-transform/sec-axis-with-coord-trans.svg index 9a94eed9ae..759323e369 100644 --- a/tests/testthat/_snaps/coord-transform/sec-axis-with-coord-trans.svg +++ b/tests/testthat/_snaps/coord-transform/sec-axis-with-coord-trans.svg @@ -312,6 +312,6 @@ cty hwy log2(hwy) -sec_axis with coord_trans() +sec_axis with coord_transform() diff --git a/tests/testthat/_snaps/coord-transform/sec-axis-with-coord-transform.svg b/tests/testthat/_snaps/coord-transform/sec-axis-with-coord-transform.svg new file mode 100644 index 0000000000..34582434c9 --- /dev/null +++ b/tests/testthat/_snaps/coord-transform/sec-axis-with-coord-transform.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +10 +15 +20 +25 +30 +35 +11.31371 +16.00000 +22.62742 +32.00000 +45.25483 + + + + + + + + + + +3.5 +4.0 +4.5 +5.0 +5.5 + + + + + + +10 +15 +20 +25 +30 +35 +cty +cty +hwy +log2(hwy) +sec_axis with coord_transform() + + diff --git a/tests/testthat/_snaps/guides/guide-titles-with-coord-trans.svg b/tests/testthat/_snaps/guides/guide-titles-with-coord-trans.svg index 4a658436f4..48296d3f9c 100644 --- a/tests/testthat/_snaps/guides/guide-titles-with-coord-trans.svg +++ b/tests/testthat/_snaps/guides/guide-titles-with-coord-trans.svg @@ -75,6 +75,6 @@ x (primary) y (primary) y (secondary) -guide titles with coord_trans() +guide titles with coord_transform() diff --git a/tests/testthat/test-coord-train.R b/tests/testthat/test-coord-train.R index b326fc6fe1..e8d7168ea3 100644 --- a/tests/testthat/test-coord-train.R +++ b/tests/testthat/test-coord-train.R @@ -25,7 +25,7 @@ test_that("NA's don't appear in breaks", { # Check the various types of coords to make sure they don't have NA breaks expect_false(any_NA_major_minor(coord_polar()$setup_panel_params(scale_x, scale_y))) expect_false(any_NA_major_minor(coord_cartesian()$setup_panel_params(scale_x, scale_y))) - expect_false(any_NA_major_minor(coord_trans()$setup_panel_params(scale_x, scale_y))) + expect_false(any_NA_major_minor(coord_transform()$setup_panel_params(scale_x, scale_y))) expect_false(any_NA_major_minor(coord_fixed()$setup_panel_params(scale_x, scale_y))) skip_if_not_installed("mapproj") diff --git a/tests/testthat/test-coord-transform.R b/tests/testthat/test-coord-transform.R index abb05a3cae..53eef402b2 100644 --- a/tests/testthat/test-coord-transform.R +++ b/tests/testthat/test-coord-transform.R @@ -1,11 +1,11 @@ -test_that("warnings are generated when coord_trans() results in new infinite values", { +test_that("warnings are generated when coord_transform() results in new infinite values", { p <- ggplot(head(diamonds, 20)) + geom_bar(aes(x = cut)) + - coord_trans(y = "log10") + coord_transform(y = "log10") p2 <- ggplot(data_frame(a = c(1, 2, 0), b = c(10, 6, 4)), aes(a, b)) + geom_point() + - coord_trans(x = "log") + coord_transform(x = "log") # TODO: These multiple warnings should be summarized nicely. Until this gets # fixed, this test ignores all the following errors than the first one. @@ -18,15 +18,15 @@ test_that("warnings are generated when coord_trans() results in new infinite val test_that("no warnings are generated when original data has Inf values, but no new Inf values created from the transformation", { p <- ggplot(data_frame(x = c(-Inf, 2, 0), y = c(Inf, 6, 4)), aes(x, y)) + geom_point() + - coord_trans(x = 'identity') + coord_transform(x = 'identity') expect_silent(benchplot(p)) }) -test_that("coord_trans() expands axes identically to coord_cartesian()", { +test_that("coord_transform() expands axes identically to coord_cartesian()", { p <- ggplot(mpg, aes(class, hwy)) + geom_point() built_cartesian <- ggplot_build(p + coord_cartesian()) - built_trans <- ggplot_build(p + coord_trans()) + built_trans <- ggplot_build(p + coord_transform()) cartesian_params <- built_cartesian$layout$panel_params[[1]] trans_params <- built_trans$layout$panel_params[[1]] @@ -35,10 +35,10 @@ test_that("coord_trans() expands axes identically to coord_cartesian()", { expect_identical(cartesian_params$y.range, trans_params$y.range) }) -test_that("coord_trans(expand = FALSE) expands axes identically to coord_cartesian(expand = FALSE)", { +test_that("coord_transform(expand = FALSE) expands axes identically to coord_cartesian(expand = FALSE)", { p <- ggplot(mpg, aes(class, hwy)) + geom_point() built_cartesian <- ggplot_build(p + coord_cartesian(expand = FALSE)) - built_trans <- ggplot_build(p + coord_trans(expand = FALSE)) + built_trans <- ggplot_build(p + coord_transform(expand = FALSE)) cartesian_params <- built_cartesian$layout$panel_params[[1]] trans_params <- built_trans$layout$panel_params[[1]] @@ -47,10 +47,10 @@ test_that("coord_trans(expand = FALSE) expands axes identically to coord_cartesi expect_identical(cartesian_params$y.range, trans_params$y.range) }) -test_that("coord_trans(y = 'log10') expands the x axis identically to scale_y_log10()", { +test_that("coord_transform(y = 'log10') expands the x axis identically to scale_y_log10()", { p <- ggplot(mpg, aes(class, hwy)) + geom_point() built_cartesian <- ggplot_build(p + scale_y_log10()) - built_trans <- ggplot_build(p + coord_trans(y = "log10")) + built_trans <- ggplot_build(p + coord_transform(y = "log10")) cartesian_params <- built_cartesian$layout$panel_params[[1]] trans_params <- built_trans$layout$panel_params[[1]] @@ -58,12 +58,12 @@ test_that("coord_trans(y = 'log10') expands the x axis identically to scale_y_lo expect_identical(cartesian_params$y.range, trans_params$y.range) }) -test_that("coord_trans() expands axes outside the domain of the axis trans", { +test_that("coord_transform() expands axes outside the domain of the axis trans", { # transform_sqrt() has a lower limit of 0 df <- data_frame(x = 1, y = c(0, 1, 2)) p <- ggplot(df, aes(x, y)) + geom_point() built_cartesian <- ggplot_build(p + scale_y_sqrt()) - built_trans <- ggplot_build(p + coord_trans(y = "sqrt")) + built_trans <- ggplot_build(p + coord_transform(y = "sqrt")) cartesian_params <- built_cartesian$layout$panel_params[[1]] trans_params <- built_trans$layout$panel_params[[1]] @@ -71,12 +71,12 @@ test_that("coord_trans() expands axes outside the domain of the axis trans", { expect_identical(cartesian_params$y.range, trans_params$y.range) }) -test_that("coord_trans() works with the reverse transformation", { +test_that("coord_transform() works with the reverse transformation", { df <- data_frame(x = c("1-one", "2-two", "3-three"), y = c(20, 30, 40)) p <- ggplot(df, aes(x, y)) + geom_point() built_cartesian <- ggplot_build(p + scale_y_reverse()) - built_trans <- ggplot_build(p + coord_trans(y = "reverse")) + built_trans <- ggplot_build(p + coord_transform(y = "reverse")) cartesian_params <- built_cartesian$layout$panel_params[[1]] trans_params <- built_trans$layout$panel_params[[1]] @@ -84,12 +84,12 @@ test_that("coord_trans() works with the reverse transformation", { expect_identical(cartesian_params$y.range, trans_params$y.range) }) -test_that("coord_trans() can reverse discrete axes", { +test_that("coord_transform() can reverse discrete axes", { df <- data_frame(x = c("1-one", "2-two", "3-three"), y = c(20, 30, 40)) p <- ggplot(df, aes(x, y)) + geom_point() built_cartesian <- ggplot_build(p) - built_trans <- ggplot_build(p + coord_trans(x = "reverse")) + built_trans <- ggplot_build(p + coord_transform(x = "reverse")) cartesian_params <- built_cartesian$layout$panel_params[[1]] trans_params <- built_trans$layout$panel_params[[1]] @@ -97,18 +97,18 @@ test_that("coord_trans() can reverse discrete axes", { expect_identical(cartesian_params$x.range, -rev(trans_params$x.range)) }) -test_that("basic coord_trans() plot displays both continuous and discrete axes", { +test_that("basic coord_transform() plot displays both continuous and discrete axes", { expect_doppelganger( - "basic coord_trans() plot", + "basic coord_transform() plot", ggplot(mpg, aes(class, hwy)) + geom_point() + - coord_trans(y = "log10") + coord_transform(y = "log10") ) }) -test_that("second axes display in coord_trans()", { +test_that("second axes display in coord_transform()", { expect_doppelganger( - "sec_axis with coord_trans()", + "sec_axis with coord_transform()", ggplot(mpg, aes(cty, hwy)) + geom_point() + scale_y_continuous( @@ -120,14 +120,14 @@ test_that("second axes display in coord_trans()", { breaks = 2^c(3.5, 4, 4.5, 5, 5.5) ) + scale_x_continuous(sec.axis = dup_axis()) + - coord_trans(y = "log2") + coord_transform(y = "log2") ) }) -test_that("coord_trans() throws error when limits are badly specified", { +test_that("coord_transform() throws error when limits are badly specified", { # throws error when limit is a Scale object instead of vector - expect_snapshot_error(ggplot() + coord_trans(xlim=xlim(1,1))) + expect_snapshot_error(ggplot() + coord_transform(xlim=xlim(1,1))) # throws error when limit's length is different than two - expect_snapshot_error(ggplot() + coord_trans(ylim=1:3)) + expect_snapshot_error(ggplot() + coord_transform(ylim=1:3)) }) diff --git a/tests/testthat/test-geom-hex.R b/tests/testthat/test-geom-hex.R index 0934f8fd27..498f00d407 100644 --- a/tests/testthat/test-geom-hex.R +++ b/tests/testthat/test-geom-hex.R @@ -33,7 +33,7 @@ test_that("geom_hex works in non-linear coordinate systems", { p <- ggplot(mpg, aes(displ, hwy)) + geom_hex() expect_doppelganger("hex bin plot with sqrt-transformed y", - p + coord_trans(y = "sqrt") + p + coord_transform(y = "sqrt") ) expect_doppelganger("hex bin plot in polar coordinates", p + coord_polar() diff --git a/tests/testthat/test-guides.R b/tests/testthat/test-guides.R index a2e5ae918d..25da50bcd8 100644 --- a/tests/testthat/test-guides.R +++ b/tests/testthat/test-guides.R @@ -715,7 +715,7 @@ test_that("Axis titles won't be blown away by coord_*()", { y.sec = guide_axis(title = "y (secondary)") ) - expect_doppelganger("guide titles with coord_trans()", plot + coord_trans()) + expect_doppelganger("guide titles with coord_transform()", plot + coord_transform()) # TODO # expect_doppelganger("guide titles with coord_polar()", plot + coord_polar()) # TODO @@ -812,7 +812,7 @@ test_that("logticks look as they should", { scale_x_continuous( breaks = c(-100, -10, -1, 0, 1, 10, 100) ) + - coord_trans(x = transform_pseudo_log()) + + coord_transform(x = transform_pseudo_log()) + theme_test() + theme(axis.line = element_line(colour = "black"), panel.border = element_blank(), diff --git a/tests/testthat/test-plot-summary-api.R b/tests/testthat/test-plot-summary-api.R index 2b4704e94c..6d90f9f3ae 100644 --- a/tests/testthat/test-plot-summary-api.R +++ b/tests/testthat/test-plot-summary-api.R @@ -100,7 +100,7 @@ test_that("coord summary - basic", { test_that("coord summary - log transformations", { # Check for coord log transformations (should ignore log scale) - pl <- p + scale_x_log10() + coord_trans(x = "log2") + pl <- p + scale_x_log10() + coord_transform(x = "log2") ll <- summarise_coord(ggplot_build(pl)) expect_identical(ll, list(xlog = 2, ylog = NA_real_, flip = FALSE)) }) From 04728c87815c24d7443e5515a80c9a736783dd79 Mon Sep 17 00:00:00 2001 From: nmercadeb Date: Fri, 16 Aug 2024 08:30:45 -0700 Subject: [PATCH 2/7] Update _pkgdown.yml --- _pkgdown.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index cc542a9071..0b0103cc12 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -172,7 +172,7 @@ reference: - coord_flip - coord_map - coord_polar - - coord_trans + - coord_transform - title: Themes desc: > From f71fdaa15491dd9f4b1c8fb1d9dd0adf8f875427 Mon Sep 17 00:00:00 2001 From: nmercadeb Date: Fri, 16 Aug 2024 22:09:40 -0700 Subject: [PATCH 3/7] add deprecated function to pkgdown --- _pkgdown.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/_pkgdown.yml b/_pkgdown.yml index 0b0103cc12..becca7d487 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -173,6 +173,7 @@ reference: - coord_map - coord_polar - coord_transform + - coord_trans - title: Themes desc: > From 19d2c4eb8d720e32454a50bcedf8ca41b201ffcd Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 27 Aug 2024 11:46:05 +0200 Subject: [PATCH 4/7] revert NEWS.md revision --- NEWS.md | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/NEWS.md b/NEWS.md index bc1bddb995..1ec3f2805c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,27 @@ # ggplot2 (development version) +* Passing empty unmapped aesthetics to layers raises a warning instead of + throwing an error (@teunbrand, #6009). +* Moved {mgcv} from Imports to Suggests (@teunbrand, #5986) +* New `reset_geom_defaults()` and `reset_stat_defaults()` to restore all geom or + stat default aesthetics at once (@teunbrand, #5975). +* `facet_wrap()` can have `space = "free_x"` with 1-row layouts and + `space = "free_y"` with 1-column layouts (@teunbrand) +* Secondary axes respect `n.breaks` setting in continuous scales (@teunbrand, #4483). +* Layers can have names (@teunbrand, #4066). +* (internal) improvements to `pal_qualitative()` (@teunbrand, #5013) +* `coord_radial(clip = "on")` clips to the panel area when the graphics device + supports clipping paths (@teunbrand, #5952). +* (internal) Panel clipping responsibility moved from Facet class to Coord + class through new `Coord$draw_panel()` method. +* `theme(strip.clip)` now defaults to `"on"` and is independent of Coord + clipping (@teunbrand, 5952). +* (internal) rearranged the code of `Facet$draw_paensl()` method (@teunbrand). +* Axis labels are now justified across facet panels (@teunbrand, #5820) +* Fixed bug in `stat_function()` so x-axis title now produced automatically + when no data added. (@phispu, #5647). +* geom_sf now accepts shape names (@sierrajohnson, #5808) +* Added `gg` class to `labs()` (@phispu, #5553). * Missing values from discrete palettes are no longer translated (@teunbrand, #5929). * Fixed bug in `facet_grid(margins = TRUE)` when using expresssions @@ -133,6 +155,13 @@ (@teunbrand, #5938, #4327). * Fixed bug where empty discrete scales weren't recognised as such (@teunbrand, #5945). +* (internal) The summary function of `stat_summary()` and `stat_summary_bin()` + is setup once in total instead of once per group (@teunbrand, #5971) +* `facet_grid(space = "free")` can now be combined with `coord_fixed()` + (@teunbrand, #4584). +* `theme_classic()` now has black ticks and text instead of dark gray. In + addition, `theme_classic()`'s axis line end is `"square"` (@teunbrand, #5978). +* {tibble} is now suggested instead of imported (@teunbrand, #5986) * `coord_trans()` renamed to `coord_transform()` (@nmercadeb, #5825). # ggplot2 3.5.1 @@ -751,7 +780,7 @@ gains in rendering speed. * `geom_linerange()` now respects the `na.rm` argument (#4927, @thomasp85) -* Improve the support for `guide_axis()` on `coord_transform()` +* Improve the support for `guide_axis()` on `coord_trans()` (@yutannihilation, #3959) * Added `stat_align()` to align data without common x-coordinates prior to @@ -1195,17 +1224,17 @@ fail. ## Minor improvements and bug fixes -* `coord_transform()` now draws second axes and accepts `xlim`, `ylim`, +* `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_transform()` now calculates breaks using the expanded range +* `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_transform()` + which resulted in differences between plots made with `coord_trans()` and those made with `coord_cartesian()`). The expansion for discrete axes - in `coord_transform()` was also updated such that it behaves identically + in `coord_trans()` was also updated such that it behaves identically to that in `coord_cartesian()` (@paleolimbot, #3338). * `expand_scale()` was deprecated in favour of `expansion()` for setting @@ -1545,7 +1574,7 @@ accompanying issue #2890. (@mikmart, #2488). * `geom_hline()`, `geom_vline()`, and `geom_abline()` now work properly - with `coord_transform()` (@clauswilke, #2149, #2812). + with `coord_trans()` (@clauswilke, #2149, #2812). * `geom_text(..., parse = TRUE)` now correctly renders the expected number of items instead of silently dropping items that are empty expressions, e.g. @@ -1988,7 +2017,7 @@ accompanying issue #2890. (@dylan-stark, #2072), and can draw the radius axis on the right (@thomasp85, #2005). -* `coord_transform()` now generates a warning when a transformation generates +* `coord_trans()` now generates a warning when a transformation generates non-finite values (@foo-bar-baz-qux, #2147). ### Themes @@ -2817,7 +2846,7 @@ version of ggplot. * `coord_cartesian()` applies the same expansion factor to limits as for scales. You can suppress with `expand = FALSE` (#1207). -* `coord_transform()` now works when breaks are suppressed (#1422). +* `coord_trans()` now works when breaks are suppressed (#1422). * `cut_number()` gives error message if the number of requested bins can be created because there are two few unique values (#1046). From 1f03f493c4d0cacac71921fd2dbb8dc4168528a0 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 27 Aug 2024 11:50:38 +0200 Subject: [PATCH 5/7] simplify alias --- R/coord-transform.R | 93 +++------------------------------------------ 1 file changed, 6 insertions(+), 87 deletions(-) diff --git a/R/coord-transform.R b/R/coord-transform.R index 69e549ff9f..786e117a1a 100644 --- a/R/coord-transform.R +++ b/R/coord-transform.R @@ -8,9 +8,12 @@ #' [scales::new_transform()] for list of transformations, and instructions #' on how to create your own. #' +#' The `coord_trans()` function is deprecated in favour of `coord_transform()`. +#' #' @inheritParams coord_cartesian #' @param x,y Transformers for x and y axes or their names. #' @param limx,limy `r lifecycle::badge("deprecated")` use `xlim` and `ylim` instead. +#' @param ... Arguments forwarded to `coord_transform()`. #' @seealso #' The `r link_book("coord transformations section", "coord#transformations-with-coord_trans")` #' @export @@ -103,99 +106,15 @@ coord_transform <- function(x = "identity", y = "identity", xlim = NULL, ylim = ) } -#' Transformed Cartesian coordinate system -#' -#' `r lifecycle::badge("deprecated")` -#' -#' `coord_trans()` is different to scale transformations in that it occurs after -#' statistical transformation and will affect the visual appearance of geoms - there is -#' no guarantee that straight lines will continue to be straight. -#' -#' Transformations only work with continuous values: see -#' [scales::new_transform()] for list of transformations, and instructions -#' on how to create your own. -#' -#' @inheritParams coord_cartesian -#' @param x,y Transformers for x and y axes or their names. -#' @param limx,limy `r lifecycle::badge("deprecated")` use `xlim` and `ylim` instead. -#' @seealso -#' The `r link_book("coord transformations section", "coord#transformations-with-coord_trans")` +#' @rdname coord_transform #' @export -#' @examples -#' \donttest{ -#' # See ?geom_boxplot for other examples -#' -#' # Three ways of doing transformation in ggplot: -#' # * by transforming the data -#' ggplot(diamonds, aes(log10(carat), log10(price))) + -#' geom_point() -#' # * by transforming the scales -#' ggplot(diamonds, aes(carat, price)) + -#' geom_point() + -#' scale_x_log10() + -#' scale_y_log10() -#' # * by transforming the coordinate system: -#' ggplot(diamonds, aes(carat, price)) + -#' geom_point() + -#' coord_trans(x = "log10", y = "log10") -#' -#' # The difference between transforming the scales and -#' # transforming the coordinate system is that scale -#' # transformation occurs BEFORE statistics, and coordinate -#' # transformation afterwards. Coordinate transformation also -#' # changes the shape of geoms: -#' -#' d <- subset(diamonds, carat > 0.5) -#' -#' ggplot(d, aes(carat, price)) + -#' geom_point() + -#' geom_smooth(method = "lm") + -#' scale_x_log10() + -#' scale_y_log10() -#' -#' ggplot(d, aes(carat, price)) + -#' geom_point() + -#' geom_smooth(method = "lm") + -#' coord_trans(x = "log10", y = "log10") -#' -#' # Here I used a subset of diamonds so that the smoothed line didn't -#' # drop below zero, which obviously causes problems on the log-transformed -#' # scale -#' -#' # With a combination of scale and coordinate transformation, it's -#' # possible to do back-transformations: -#' ggplot(diamonds, aes(carat, price)) + -#' geom_point() + -#' geom_smooth(method = "lm") + -#' scale_x_log10() + -#' scale_y_log10() + -#' coord_trans(x = scales::transform_exp(10), y = scales::transform_exp(10)) -#' -#' # cf. -#' ggplot(diamonds, aes(carat, price)) + -#' geom_point() + -#' geom_smooth(method = "lm") -#' -#' # Also works with discrete scales -#' set.seed(1) -#' df <- data.frame(a = abs(rnorm(26)),letters) -#' plot <- ggplot(df,aes(a,letters)) + geom_point() -#' -#' plot + coord_trans(x = "log10") -#' plot + coord_trans(x = "sqrt") -#' } -coord_trans <- function(x = "identity", y = "identity", xlim = NULL, ylim = NULL, - limx = deprecated(), limy = deprecated(), clip = "on", expand = TRUE) { +coord_trans <- function(...) { deprecate_soft0( "3.5.2", "coord_trans()", "coord_transform()" ) - - coord_transform( - x = x, y = y, xlim = xlim, ylim = ylim, - limx = limx, limy = limy, clip = clip, expand = expand - ) + coord_transform(...) } #' @rdname ggplot2-ggproto From 3bb2df14f0f4ed015d2fdd08a5e4ea5f9b05850f Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 27 Aug 2024 11:53:06 +0200 Subject: [PATCH 6/7] class alias --- R/coord-transform.R | 145 +++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 68 deletions(-) diff --git a/R/coord-transform.R b/R/coord-transform.R index 786e117a1a..0a6ebe8dbd 100644 --- a/R/coord-transform.R +++ b/R/coord-transform.R @@ -98,11 +98,12 @@ coord_transform <- function(x = "identity", y = "identity", xlim = NULL, ylim = if (is.character(x)) x <- as.transform(x) if (is.character(y)) y <- as.transform(y) - ggproto(NULL, CoordTrans, - trans = list(x = x, y = y), - limits = list(x = xlim, y = ylim), - expand = expand, - clip = clip + ggproto( + NULL, CoordTransform, + trans = list(x = x, y = y), + limits = list(x = xlim, y = ylim), + expand = expand, + clip = clip ) } @@ -121,81 +122,89 @@ coord_trans <- function(...) { #' @format NULL #' @usage NULL #' @export -CoordTrans <- ggproto("CoordTrans", Coord, - is_free = function() TRUE, - distance = function(self, x, y, panel_params) { - max_dist <- dist_euclidean(panel_params$x.range, panel_params$y.range) - dist_euclidean(self$trans$x$transform(x), self$trans$y$transform(y)) / max_dist - }, +CoordTransform <- ggproto( + "CoordTransform", Coord, + is_free = function() TRUE, + distance = function(self, x, y, panel_params) { + max_dist <- dist_euclidean(panel_params$x.range, panel_params$y.range) + dist_euclidean(self$trans$x$transform(x), self$trans$y$transform(y)) / max_dist + }, - backtransform_range = function(self, panel_params) { - list( - x = self$trans$x$inverse(panel_params$x.range), - y = self$trans$y$inverse(panel_params$y.range) - ) - }, + backtransform_range = function(self, panel_params) { + list( + x = self$trans$x$inverse(panel_params$x.range), + y = self$trans$y$inverse(panel_params$y.range) + ) + }, - range = function(self, panel_params) { - list( - x = panel_params$x.range, - y = panel_params$y.range - ) - }, + range = function(self, panel_params) { + list( + x = panel_params$x.range, + y = panel_params$y.range + ) + }, - transform = function(self, data, panel_params) { - # trans_x() and trans_y() needs to keep Inf values because this can be called - # in guide_transform.axis() - trans_x <- function(data) { - idx <- !is.infinite(data) - data[idx] <- transform_value(self$trans$x, data[idx], panel_params$x.range) - data - } - trans_y <- function(data) { - idx <- !is.infinite(data) - data[idx] <- transform_value(self$trans$y, data[idx], panel_params$y.range) - data - } + transform = function(self, data, panel_params) { + # trans_x() and trans_y() needs to keep Inf values because this can be called + # in guide_transform.axis() + trans_x <- function(data) { + idx <- !is.infinite(data) + data[idx] <- transform_value(self$trans$x, data[idx], panel_params$x.range) + data + } + trans_y <- function(data) { + idx <- !is.infinite(data) + data[idx] <- transform_value(self$trans$y, data[idx], panel_params$y.range) + data + } - new_data <- transform_position(data, trans_x, trans_y) + new_data <- transform_position(data, trans_x, trans_y) - warn_new_infinites(data$x, new_data$x, "x") - warn_new_infinites(data$y, new_data$y, "y") + warn_new_infinites(data$x, new_data$x, "x") + warn_new_infinites(data$y, new_data$y, "y") - transform_position(new_data, squish_infinite, squish_infinite) - }, + transform_position(new_data, squish_infinite, squish_infinite) + }, - setup_panel_params = function(self, scale_x, scale_y, params = list()) { - c( - view_scales_from_scale_with_coord_trans(scale_x, self$limits$x, self$trans$x, self$expand), - view_scales_from_scale_with_coord_trans(scale_y, self$limits$y, self$trans$y, self$expand) - ) - }, + setup_panel_params = function(self, scale_x, scale_y, params = list()) { + c( + view_scales_from_scale_with_coord_trans(scale_x, self$limits$x, self$trans$x, self$expand), + view_scales_from_scale_with_coord_trans(scale_y, self$limits$y, self$trans$y, self$expand) + ) + }, - render_bg = function(panel_params, theme) { - guide_grid( - theme, - panel_params$x.minor, - panel_params$x.major, - panel_params$y.minor, - panel_params$y.major - ) - }, + render_bg = function(panel_params, theme) { + guide_grid( + theme, + panel_params$x.minor, + panel_params$x.major, + panel_params$y.minor, + panel_params$y.major + ) + }, - render_axis_h = function(panel_params, theme) { - list( - top = panel_guides_grob(panel_params$guides, position = "top", theme = theme), - bottom = panel_guides_grob(panel_params$guides, position = "bottom", theme = theme) - ) - }, + render_axis_h = function(panel_params, theme) { + list( + top = panel_guides_grob(panel_params$guides, position = "top", theme = theme), + bottom = panel_guides_grob(panel_params$guides, position = "bottom", theme = theme) + ) + }, - render_axis_v = function(panel_params, theme) { - list( - left = panel_guides_grob(panel_params$guides, position = "left", theme = theme), - right = panel_guides_grob(panel_params$guides, position = "right", theme = theme) - ) - } + render_axis_v = function(panel_params, theme) { + list( + left = panel_guides_grob(panel_params$guides, position = "left", theme = theme), + right = panel_guides_grob(panel_params$guides, position = "right", theme = theme) + ) + } ) +# TODO: deprecate this some time in the future +#' @rdname ggplot2-ggproto +#' @format NULL +#' @usage NULL +#' @export +CoordTrans <- ggproto("CoordTrans", CoordTransform) + transform_value <- function(trans, value, range) { if (is.null(value)) return(value) From b88da1dd27ae002eeeba8dd647e20c2c66b33631 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 27 Aug 2024 11:53:47 +0200 Subject: [PATCH 7/7] reoxygenate --- NAMESPACE | 1 + man/coord_trans.Rd | 116 ----------------------------------------- man/coord_transform.Rd | 7 +++ man/ggplot2-ggproto.Rd | 1 + 4 files changed, 9 insertions(+), 116 deletions(-) delete mode 100644 man/coord_trans.Rd diff --git a/NAMESPACE b/NAMESPACE index 7f26588e1e..d88a110a93 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -167,6 +167,7 @@ export(CoordQuickmap) export(CoordRadial) export(CoordSf) export(CoordTrans) +export(CoordTransform) export(Facet) export(FacetGrid) export(FacetNull) diff --git a/man/coord_trans.Rd b/man/coord_trans.Rd deleted file mode 100644 index 617b513856..0000000000 --- a/man/coord_trans.Rd +++ /dev/null @@ -1,116 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/coord-transform.R -\name{coord_trans} -\alias{coord_trans} -\title{Transformed Cartesian coordinate system} -\usage{ -coord_trans( - x = "identity", - y = "identity", - xlim = NULL, - ylim = NULL, - limx = deprecated(), - limy = deprecated(), - clip = "on", - expand = TRUE -) -} -\arguments{ -\item{x, y}{Transformers for x and y axes or their names.} - -\item{xlim, ylim}{Limits for the x and y axes.} - -\item{limx, limy}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} use \code{xlim} and \code{ylim} instead.} - -\item{clip}{Should drawing be clipped to the extent of the plot panel? A -setting of \code{"on"} (the default) means yes, and a setting of \code{"off"} -means no. In most cases, the default of \code{"on"} should not be changed, -as setting \code{clip = "off"} can cause unexpected results. It allows -drawing of data points anywhere on the plot, including in the plot margins. If -limits are set via \code{xlim} and \code{ylim} and some data points fall outside those -limits, then those data points may show up in places such as the axes, the -legend, the plot title, or the plot margins.} - -\item{expand}{If \code{TRUE}, the default, adds a small expansion factor to -the limits to ensure that data and axes don't overlap. If \code{FALSE}, -limits are taken exactly from the data or \code{xlim}/\code{ylim}.} -} -\description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} -} -\details{ -\code{coord_trans()} is different to scale transformations in that it occurs after -statistical transformation and will affect the visual appearance of geoms - there is -no guarantee that straight lines will continue to be straight. - -Transformations only work with continuous values: see -\code{\link[scales:new_transform]{scales::new_transform()}} for list of transformations, and instructions -on how to create your own. -} -\examples{ -\donttest{ -# See ?geom_boxplot for other examples - -# Three ways of doing transformation in ggplot: -# * by transforming the data -ggplot(diamonds, aes(log10(carat), log10(price))) + - geom_point() -# * by transforming the scales -ggplot(diamonds, aes(carat, price)) + - geom_point() + - scale_x_log10() + - scale_y_log10() -# * by transforming the coordinate system: -ggplot(diamonds, aes(carat, price)) + - geom_point() + - coord_trans(x = "log10", y = "log10") - -# The difference between transforming the scales and -# transforming the coordinate system is that scale -# transformation occurs BEFORE statistics, and coordinate -# transformation afterwards. Coordinate transformation also -# changes the shape of geoms: - -d <- subset(diamonds, carat > 0.5) - -ggplot(d, aes(carat, price)) + - geom_point() + - geom_smooth(method = "lm") + - scale_x_log10() + - scale_y_log10() - -ggplot(d, aes(carat, price)) + - geom_point() + - geom_smooth(method = "lm") + - coord_trans(x = "log10", y = "log10") - -# Here I used a subset of diamonds so that the smoothed line didn't -# drop below zero, which obviously causes problems on the log-transformed -# scale - -# With a combination of scale and coordinate transformation, it's -# possible to do back-transformations: -ggplot(diamonds, aes(carat, price)) + - geom_point() + - geom_smooth(method = "lm") + - scale_x_log10() + - scale_y_log10() + - coord_trans(x = scales::transform_exp(10), y = scales::transform_exp(10)) - -# cf. -ggplot(diamonds, aes(carat, price)) + - geom_point() + - geom_smooth(method = "lm") - -# Also works with discrete scales -set.seed(1) -df <- data.frame(a = abs(rnorm(26)),letters) -plot <- ggplot(df,aes(a,letters)) + geom_point() - -plot + coord_trans(x = "log10") -plot + coord_trans(x = "sqrt") -} -} -\seealso{ -The \href{https://ggplot2-book.org/coord#transformations-with-coord_trans}{coord transformations section} of the online ggplot2 book. -} diff --git a/man/coord_transform.Rd b/man/coord_transform.Rd index 950bf3e06e..5235051d46 100644 --- a/man/coord_transform.Rd +++ b/man/coord_transform.Rd @@ -2,6 +2,7 @@ % Please edit documentation in R/coord-transform.R \name{coord_transform} \alias{coord_transform} +\alias{coord_trans} \title{Transformed Cartesian coordinate system} \usage{ coord_transform( @@ -14,6 +15,8 @@ coord_transform( clip = "on", expand = TRUE ) + +coord_trans(...) } \arguments{ \item{x, y}{Transformers for x and y axes or their names.} @@ -34,6 +37,8 @@ legend, the plot title, or the plot margins.} \item{expand}{If \code{TRUE}, the default, adds a small expansion factor to the limits to ensure that data and axes don't overlap. If \code{FALSE}, limits are taken exactly from the data or \code{xlim}/\code{ylim}.} + +\item{...}{Arguments forwarded to \code{coord_transform()}.} } \description{ \code{coord_transform()} is different to scale transformations in that it occurs after @@ -44,6 +49,8 @@ no guarantee that straight lines will continue to be straight. Transformations only work with continuous values: see \code{\link[scales:new_transform]{scales::new_transform()}} for list of transformations, and instructions on how to create your own. + +The \code{coord_trans()} function is deprecated in favour of \code{coord_transform()}. } \examples{ \donttest{ diff --git a/man/ggplot2-ggproto.Rd b/man/ggplot2-ggproto.Rd index cf3325f1f3..c08fe3e542 100644 --- a/man/ggplot2-ggproto.Rd +++ b/man/ggplot2-ggproto.Rd @@ -47,6 +47,7 @@ \alias{CoordPolar} \alias{CoordQuickmap} \alias{CoordRadial} +\alias{CoordTransform} \alias{CoordTrans} \alias{Facet} \alias{FacetGrid}