Skip to content

Version comparisons #5367

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

Closed
wants to merge 15 commits into from
Closed
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: 1 addition & 1 deletion .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ jobs:
cache-version: 3
extra-packages: >
any::rcmdcheck,
Hmisc=?ignore-before-r=3.6.0,
Hmisc=?ignore-before-r=4.1.0,
quantreg=?ignore-before-r=3.6.0,
needs: check

Expand Down
4 changes: 1 addition & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Package: ggplot2
Version: 3.4.2
Version: 3.4.2.9000
Title: Create Elegant Data Visualisations Using the Grammar of Graphics
Authors@R: c(
person("Hadley", "Wickham", , "[email protected]", role = "aut",
Expand Down Expand Up @@ -52,7 +52,6 @@ Suggests:
hexbin,
Hmisc,
knitr,
lattice,
mapproj,
maps,
maptools,
Expand All @@ -63,7 +62,6 @@ Suggests:
quantreg,
ragg,
RColorBrewer,
rgeos,
rmarkdown,
rpart,
sf (>= 0.7-3),
Expand Down
27 changes: 27 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,30 @@
# ggplot2 (development version)

* To improve `width` calculation in bar plots with empty factor levels,
`resolution()` considers `mapped_discrete` values as having resolution 1
(@teunbrand, #5211)
* When `geom_path()` has aesthetics varying within groups, the `arrow()` is
applied to groups instead of individual segments (@teunbrand, #4935).
* The default width of `geom_bar()` is now based on panel-wise resolution of
the data, rather than global resolution (@teunbrand, #4336).
* To apply dodging more consistently in violin plots, `stat_ydensity()` now
has a `drop` argument to keep or discard groups with 1 observation.
* Aesthetics listed in `geom_*()` and `stat_*()` layers now point to relevant
documentation (@teunbrand, #5123).
* `coord_flip()` has been marked as superseded. The recommended alternative is
to swap the `x` and `y` aesthetic and/or using the `orientation` argument in
a layer (@teunbrand, #5130).
* `stat_align()` is now applied per panel instead of globally, preventing issues
when facets have different ranges (@teunbrand, #5227).
* A stacking bug in `stat_align()` was fixed (@teunbrand, #5176).
* `stat_contour()` and `stat_contour_filled()` now warn about and remove
duplicated coordinates (@teunbrand, #5215).

# ggplot2 3.4.3

This hotfix release addresses a version comparison change in r-devel. There are
no user-facing or breaking changes.

# ggplot2 3.4.2
This is a hotfix release anticipating changes in r-devel, but folds in upkeep
changes and a few bug fixes as well.
Expand Down
12 changes: 10 additions & 2 deletions R/aes-colour-fill-alpha.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
#'
#' @section Colour and fill:
#'
#' The `colour` aesthetic is used to draw lines and strokes, such as in
#' [`geom_point()`] and [`geom_line()`], but also the line contours of
#' [`geom_rect()`] and [`geom_polygon()`]. The `fill` aesthetic is used to
#' colour the inside areas of geoms, such as [`geom_rect()`] and
#' [`geom_polygon()`], but also the insides of shapes 21-25 of [`geom_point()`].
#'
#' Colours and fills can be specified in the following ways:
#' * A name, e.g., `"red"`. R has 657 built-in named colours, which can be
#' listed with [grDevices::colors()].
Expand Down Expand Up @@ -38,9 +44,11 @@
#' [scale_fill_gradient()], [scale_fill_grey()],
#' [scale_fill_hue()], [scale_fill_identity()],
#' [scale_fill_manual()], [scale_fill_viridis_d()]
#' * Other options for modifying alpha: [scale_alpha()]
#' * Run `vignette("ggplot2-specs")` to see an overview of other aesthestics that
#' * Other options for modifying alpha:
#' [scale_alpha()], [scale_alpha_manual()], [scale_alpha_identity()]
#' * Run `vignette("ggplot2-specs")` to see an overview of other aesthetics that
#' can be modified.
#' @family aesthetics documentation
#'
#' @name aes_colour_fill_alpha
#' @aliases colour color fill
Expand Down
11 changes: 10 additions & 1 deletion R/aes-group-order.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,23 @@
#' and/or `linetype`. This is demonstrated in the examples below.
#'
#' There are three common cases where the default does not display the data correctly.
#' 1. `geom_line()` where there are multiple individuals and the plot tries to
#' connect every observation, even across individuals, with a line.
#' 1. `geom_line()` where a discrete x-position implies groups, whereas observations
#' span the discrete x-positions.
#' 1. When the grouping needs to be different over different layers, for example
#' when computing a statistic on all observations when another layer shows
#' individuals.
#'
#' The examples below use a longitudinal dataset, `Oxboys`, from the nlme package to demonstrate
#' these cases. `Oxboys` records the heights (height) and centered ages (age) of 26 boys (Subject),
#' measured on nine occasions (Occasion).
#'
#' @seealso
#' * Geoms commonly used with groups: [geom_bar()], [geom_histogram()], [geom_line()]
#' * Run `vignette("ggplot2-specs")` to see an overview of other aesthestics that
#' * Run `vignette("ggplot2-specs")` to see an overview of other aesthetics that
#' can be modified.
#' @family aesthetics documentation
#'
#' @examples
#' \donttest{
Expand Down
44 changes: 33 additions & 11 deletions R/aes-linetype-size-shape.R
Original file line number Diff line number Diff line change
@@ -1,32 +1,48 @@
#' Differentiation related aesthetics: linetype, size, shape
#'
#' @description
#' The `linetype`, `size`, and `shape` aesthetics modify the appearance of
#' lines and/or points. They also apply to the outlines of polygons (`linetype`
#' and `size`) or to text (`size`).
#' The `linetype`, `linewidth`, `size`, and `shape` aesthetics modify the
#' appearance of lines and/or points. They also apply to the outlines of
#' polygons (`linetype` and `linewidth`) or to text (`size`).
#'
#' @section Linetype:
#' The `linetype` aesthetic can be specified with either an integer (0-6), a
#' name (0 = blank, 1 = solid, 2 = dashed, 3 = dotted, 4 = dotdash, 5 = longdash,
#' 6 = twodash), a mapping to a discrete variable, or a string of an even number
#' (up to eight) of hexadecimal digits which give the lengths in consecutive
#' positions in the string. See examples for a hex string demonstration.
#'
#' The `size` aesthetic can be specified with a numerical value (in millimetres)
#' or via a mapping to a continuous variable.
#' @section Linewidth and stroke:
#' The `linewidth` aesthetic sets the widths of lines, and can be specified
#' with a numeric value (for historical reasons, these units are about 0.75
#' millimetres). Alternatively, they can also be set via mapping to a continuous
#' variable. The `stroke` aesthetic serves the same role for points, but is
#' distinct for discriminating points from lines in geoms such as
#' [`geom_pointrange()`].
#'
#' The `shape` aesthetic can be specified with an integer (between 0 and 25),
#' a single character (which uses that character as the plotting symbol),
#' a `.` to draw the smallest rectangle that is visible (i.e., about one pixel),
#' an `NA` to draw nothing, or a mapping to a discrete variable. Symbols and
#' filled shapes are described in the examples below.
#' @section Size:
#' The `size` aesthetic control the size of points and text, and can be
#' specified with a numerical value (in millimetres) or via a mapping to a
#' continuous variable.
#'
#' @section Shape:
#' The `shape` aesthetic controls the symbols of points, and can be specified
#' with an integer (between 0 and 25), a single character (which uses that
#' character as the plotting symbol), a `.` to draw the smallest rectangle that
#' is visible (i.e., about one pixel), an `NA` to draw nothing, or a mapping to
#' a discrete variable. Symbols and filled shapes are described in the examples
#' below.
#'
#' @seealso
#' * [geom_line()] and [geom_point()] for geoms commonly used
#' with these aesthetics.
#' * [aes_group_order()] for using `linetype`, `size`, or
#' `shape` for grouping.
#' * Run `vignette("ggplot2-specs")` to see an overview of other aesthestics that
#' * Scales that can be used to modify these aesthetics: [`scale_linetype()`],
#' [`scale_linewidth()`], [`scale_size()`], and [`scale_shape()`].
#' * Run `vignette("ggplot2-specs")` to see an overview of other aesthetics that
#' can be modified.
#' @family aesthetics documentation
#' @name aes_linetype_size_shape
#' @aliases linetype size shape
#' @examples
Expand All @@ -45,6 +61,12 @@
#' ggplot(economics_long, aes(date, value01)) +
#' geom_line(aes(linetype = variable))
#'
#' # Linewidth examples
#' ggplot(economics, aes(date, unemploy)) +
#' geom_line(linewidth = 2, lineend = "round")
#' ggplot(economics, aes(date, unemploy)) +
#' geom_line(aes(linewidth = uempmed), lineend = "round")
#'
#' # Size examples
#' p <- ggplot(mtcars, aes(wt, mpg))
#' p + geom_point(size = 4)
Expand Down
12 changes: 12 additions & 0 deletions R/aes-position.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
#' `xmin`, `xmax`, `ymin` and `ymax` can be used to specify the position of
#' annotations and to represent rectangular areas.
#'
#' In addition, there are position aesthetics that are contextual to the
#' geometry that they're used in. These are `xintercept`, `yintercept`,
#' `xmin_final`, `ymin_final`, `xmax_final`, `ymax_final`, `xlower`, `lower`,
#' `xmiddle`, `middle`, `xupper`, `upper`, `x0` and `y0`. Many of these are used
#' and automatically computed in [`geom_boxplot()`].
#'
#' @name aes_position
#' @aliases x y xmin xmax ymin ymax xend yend
#'
Expand All @@ -20,7 +26,13 @@
#' [geom_curve()], [geom_errorbar()], [geom_line()], [geom_linerange()],
#' [geom_path()], [geom_point()], [geom_pointrange()], [geom_rect()],
#' [geom_segment()]
#' * Scales that can be used to modify positions:
#' [`scale_continuous()`][scale_x_continuous()],
#' [`scale_discrete()`][scale_x_discrete()],
#' [`scale_binned()`][scale_x_binned()],
#' [`scale_date()`][scale_x_date()].
#' * See also [annotate()] for placing annotations.
#' @family aesthetics documentation
#' @examples
#'
#' # Generate data: means and standard errors of means for prices
Expand Down
5 changes: 5 additions & 0 deletions R/aes.R
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ NULL
#' @seealso [vars()] for another quoting function designed for
#' faceting specifications.
#'
#' Run `vignette("ggplot2-specs")` to see an overview of other aesthetics
#' that can be modified.
#'
#' [Delayed evaluation][aes_eval] for working with computed variables.
#'
#' @family aesthetics documentation
#' @return A list with class `uneval`. Components of the list are either
#' quosures or constants.
#' @export
Expand Down
4 changes: 2 additions & 2 deletions R/backports.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Backport fix from R 3.3:
# https://github.com/wch/r-source/commit/4efc81c98d262f93de9e7911aaa910f5c63cd00f
if (getRversion() < 3.3) {
if (getRversion() < "3.3") {
absolute.units <- getFromNamespace("absolute.units", "grid")
absolute.units.unit <- getFromNamespace("absolute.units.unit", "grid")
absolute.units.unit.list <- getFromNamespace("absolute.units.unit.list", "grid")
Expand All @@ -18,6 +18,6 @@ if (getRversion() < 3.3) {
on_load(backport_unit_methods())

# isFALSE() is available on R (>=3.5)
if (getRversion() < 3.5) {
if (getRversion() < "3.5") {
isFALSE <- function(x) is.logical(x) && length(x) == 1L && !is.na(x) && !x
}
48 changes: 33 additions & 15 deletions R/coord-flip.R
Original file line number Diff line number Diff line change
@@ -1,30 +1,48 @@
#' Cartesian coordinates with x and y flipped
#'
#' Flip cartesian coordinates so that horizontal becomes vertical, and
#' vertical, horizontal. This is primarily useful for converting geoms and
#' statistics which display y conditional on x, to x conditional on y.
#' @description
#' `r lifecycle::badge("superseded")`
#'
#' This function is superseded because in many cases, `coord_flip()` can easily
#' be replaced by swapping the x and y aesthetics, or optionally setting the
#' `orientation` argument in geom and stat layers.
#'
#' `coord_flip()` is useful for geoms and statistics that do not support
#' the `orientation` setting, and converting the display of y conditional on x,
#' to x conditional on y.
#'
#' @export
#' @inheritParams coord_cartesian
#' @examples
#' # Very useful for creating boxplots, and other interval
#' # geoms in the horizontal instead of vertical position.
#' # The preferred method of creating horizontal instead of vertical boxplots
#' ggplot(diamonds, aes(price, cut)) +
#' geom_boxplot()
#'
#' # Using `coord_flip()` to make the same plot
#' ggplot(diamonds, aes(cut, price)) +
#' geom_boxplot() +
#' coord_flip()
#'
#' h <- ggplot(diamonds, aes(carat)) +
#' geom_histogram()
#' h
#' h + coord_flip()
#' h + coord_flip() + scale_x_reverse()
#' # With swapped aesthetics, the y-scale controls the left axis
#' ggplot(diamonds, aes(y = carat)) +
#' geom_histogram() +
#' scale_y_reverse()
#'
#' # In `coord_flip()`, the x-scale controls the left axis
#' ggplot(diamonds, aes(carat)) +
#' geom_histogram() +
#' coord_flip() +
#' scale_x_reverse()
#'
#' # You can also use it to flip line and area plots:
#' df <- data.frame(x = 1:5, y = (1:5) ^ 2)
#' ggplot(df, aes(x, y)) +
#' geom_area()
#' last_plot() + coord_flip()
#' # In line and area plots, swapped aesthetics require an explicit orientation
#' df <- data.frame(a = 1:5, b = (1:5) ^ 2)
#' ggplot(df, aes(b, a)) +
#' geom_area(orientation = "y")
#'
#' # The same plot with `coord_flip()`
#' ggplot(df, aes(a, b)) +
#' geom_area() +
#' coord_flip()
coord_flip <- function(xlim = NULL, ylim = NULL, expand = TRUE, clip = "on") {
ggproto(NULL, CoordFlip,
limits = list(x = xlim, y = ylim),
Expand Down
5 changes: 4 additions & 1 deletion R/geom-bar.R
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,10 @@ GeomBar <- ggproto("GeomBar", GeomRect,
data$flipped_aes <- params$flipped_aes
data <- flip_data(data, params$flipped_aes)
data$width <- data$width %||%
params$width %||% (resolution(data$x, FALSE) * 0.9)
params$width %||% (min(vapply(
split(data$x, data$PANEL),
resolution, numeric(1), zero = FALSE
)) * 0.9)
data$just <- params$just %||% 0.5
data <- transform(data,
ymin = pmin(y, 0), ymax = pmax(y, 0),
Expand Down
40 changes: 40 additions & 0 deletions R/geom-path.R
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ GeomPath <- ggproto("GeomPath", Geom,
end <- c(group_diff, TRUE)

if (!constant) {

arrow <- repair_segment_arrow(arrow, munched$group)

segmentsGrob(
munched$x[!end], munched$y[!end], munched$x[!start], munched$y[!start],
default.units = "native", arrow = arrow,
Expand Down Expand Up @@ -363,3 +366,40 @@ stairstep <- function(data, direction = "hv") {

data_frame0(x = x, y = y, data_attr)
}

repair_segment_arrow <- function(arrow, group) {
# Early exit if there is no arrow
if (is.null(arrow)) {
return(arrow)
}

# Get group parameters
rle <- vec_group_rle(group) # handles NAs better than base::rle()
n_groups <- length(rle)
rle_len <- field(rle, "length") - 1 # segments have 1 member less than lines
rle_end <- cumsum(rle_len)
rle_start <- rle_end - rle_len + 1

# Recycle ends and lengths
ends <- rep(rep(arrow$ends, length.out = n_groups), rle_len)
len <- rep(rep(arrow$length, length.out = n_groups), rle_len)

# Repair ends
# Convert 'both' ends to first/last in multi-member groups
is_both <- which(ends == 3)
ends[setdiff(intersect(rle_start, is_both), rle_end)] <- 1L
ends[setdiff(intersect(rle_end, is_both), rle_start)] <- 2L
arrow$ends <- ends

# Repair lengths
zero <- unit(0, "mm")
# Set length of first segment to zero when ends is 'last'
len[intersect(setdiff(rle_start, rle_end), which(ends == 2))] <- zero
# Set length of last segment to zero when ends is 'first'
len[intersect(setdiff(rle_end, rle_start), which(ends == 1))] <- zero
# Set length of middle pieces to zero
len[setdiff(seq_along(len), c(rle_start, rle_end))] <- zero
arrow$length <- len

return(arrow)
}
5 changes: 5 additions & 0 deletions R/scale-alpha.R
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
#' breaks, labels and so forth.
#' @param range Output range of alpha values. Must lie between 0 and 1.
#' @family colour scales
#' @family alpha scales
#' @seealso
#' The documentation on [colour aesthetics][aes_colour_fill_alpha].
#'
#' Other alpha scales: [scale_alpha_manual()], [scale_alpha_identity()].
#' @export
#' @examples
#' p <- ggplot(mpg, aes(displ, hwy)) +
Expand Down
2 changes: 2 additions & 0 deletions R/scale-binned.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#' @inheritParams binned_scale
#'
#' @family position scales
#' @seealso
#' The [position documentation][aes_position].
#' @name scale_binned
#' @aliases NULL
#'
Expand Down
Loading