Skip to content

Commit e6aa935

Browse files
committed
resolve merge conflict
Merge branch 'main' into scale_name_function # Conflicts: # R/labels.R
2 parents 627e25a + e30642b commit e6aa935

File tree

220 files changed

+4488
-1799
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

220 files changed

+4488
-1799
lines changed

DESCRIPTION

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Imports:
4444
vctrs (>= 0.6.0),
4545
withr (>= 2.5.0)
4646
Suggests:
47+
broom,
4748
covr,
4849
dplyr,
4950
ggplot2movies,
@@ -126,15 +127,15 @@ Collate:
126127
'facet-grid-.R'
127128
'facet-null.R'
128129
'facet-wrap.R'
129-
'fortify-lm.R'
130130
'fortify-map.R'
131-
'fortify-multcomp.R'
131+
'fortify-models.R'
132132
'fortify-spatial.R'
133133
'fortify.R'
134134
'stat-.R'
135135
'geom-abline.R'
136136
'geom-rect.R'
137137
'geom-bar.R'
138+
'geom-tile.R'
138139
'geom-bin2d.R'
139140
'geom-blank.R'
140141
'geom-boxplot.R'
@@ -167,7 +168,6 @@ Collate:
167168
'geom-smooth.R'
168169
'geom-spoke.R'
169170
'geom-text.R'
170-
'geom-tile.R'
171171
'geom-violin.R'
172172
'geom-vline.R'
173173
'ggplot2-package.R'
@@ -242,6 +242,7 @@ Collate:
242242
'scales-.R'
243243
'stat-align.R'
244244
'stat-bin.R'
245+
'stat-summary-2d.R'
245246
'stat-bin2d.R'
246247
'stat-bindot.R'
247248
'stat-binhex.R'
@@ -254,6 +255,7 @@ Collate:
254255
'stat-ellipse.R'
255256
'stat-function.R'
256257
'stat-identity.R'
258+
'stat-manual.R'
257259
'stat-qq-line.R'
258260
'stat-qq.R'
259261
'stat-quantilemethods.R'
@@ -262,7 +264,6 @@ Collate:
262264
'stat-smooth-methods.R'
263265
'stat-smooth.R'
264266
'stat-sum.R'
265-
'stat-summary-2d.R'
266267
'stat-summary-bin.R'
267268
'stat-summary-hex.R'
268269
'stat-summary.R'
@@ -273,6 +274,7 @@ Collate:
273274
'theme.R'
274275
'theme-defaults.R'
275276
'theme-current.R'
277+
'theme-sub.R'
276278
'utilities-break.R'
277279
'utilities-grid.R'
278280
'utilities-help.R'

NAMESPACE

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ S3method(makeContext,dotstackGrob)
9494
S3method(merge_element,default)
9595
S3method(merge_element,element)
9696
S3method(merge_element,element_blank)
97+
S3method(merge_element,margin)
9798
S3method(pattern_alpha,GridPattern)
9899
S3method(pattern_alpha,GridTilingPattern)
99100
S3method(pattern_alpha,default)
@@ -172,6 +173,7 @@ export(GeomAbline)
172173
export(GeomAnnotationMap)
173174
export(GeomArea)
174175
export(GeomBar)
176+
export(GeomBin2d)
175177
export(GeomBlank)
176178
export(GeomBoxplot)
177179
export(GeomCol)
@@ -263,6 +265,7 @@ export(StatEcdf)
263265
export(StatEllipse)
264266
export(StatFunction)
265267
export(StatIdentity)
268+
export(StatManual)
266269
export(StatQq)
267270
export(StatQqLine)
268271
export(StatQuantile)
@@ -493,6 +496,8 @@ export(layer_sf)
493496
export(lims)
494497
export(map_data)
495498
export(margin)
499+
export(margin_auto)
500+
export(margin_part)
496501
export(max_height)
497502
export(max_width)
498503
export(mean_cl_boot)
@@ -687,6 +692,7 @@ export(stat_ecdf)
687692
export(stat_ellipse)
688693
export(stat_function)
689694
export(stat_identity)
695+
export(stat_manual)
690696
export(stat_qq)
691697
export(stat_qq_line)
692698
export(stat_quantile)
@@ -719,7 +725,19 @@ export(theme_linedraw)
719725
export(theme_minimal)
720726
export(theme_replace)
721727
export(theme_set)
728+
export(theme_sub_axis)
729+
export(theme_sub_axis_bottom)
730+
export(theme_sub_axis_left)
731+
export(theme_sub_axis_right)
732+
export(theme_sub_axis_top)
733+
export(theme_sub_axis_x)
734+
export(theme_sub_axis_y)
735+
export(theme_sub_legend)
736+
export(theme_sub_panel)
737+
export(theme_sub_plot)
738+
export(theme_sub_strip)
722739
export(theme_test)
740+
export(theme_transparent)
723741
export(theme_update)
724742
export(theme_void)
725743
export(transform_position)

NEWS.md

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,52 @@
22

33
* Scale names, guide titles and aesthetic labels can now accept functions
44
(@teunbrand, #4313)
5+
* Binned scales with zero-width data expand the default limits by 0.1
6+
(@teunbrand, #5066)
7+
* New default `geom_qq_line(geom = "abline")` for better clipping in the
8+
vertical direction. In addition, `slope` and `intercept` are new computed
9+
variables in `stat_qq_line()` (@teunbrand, #6087).
10+
* Position adjustments can now have auxiliary aesthetics (@teunbrand).
11+
* `position_nudge()` gains `nudge_x` and `nudge_y` aesthetics (#3026, #5445).
12+
* `position_dodge()` gains `order` aesthetic (#3022, #3345)
13+
* More stability for vctrs-based palettes (@teunbrand, #6117).
14+
* Fixed regression in `guide_bins(reverse = TRUE)` (@teunbrand, #6183).
15+
* New function family for setting parts of a theme. For example, you can now use
16+
`theme_sub_axis(line, text, ticks, ticks.length, line)` as a substitute for
17+
`theme(axis.line, axis.text, axis.ticks, axis.ticks.length, axis.line)`. This
18+
should allow slightly terser and more organised theme declarations
19+
(@teunbrand, #5301).
20+
* `scale_{x/y}_discrete(continuous.limits)` is a new argument to control the
21+
display range of discrete scales (@teunbrand, #4174, #6259).
22+
* `geom_ribbon()` now appropriately warns about, and removes, missing values
23+
(@teunbrand, #6243).
24+
* `guide_*()` can now accept two inside legend theme elements:
25+
`legend.position.inside` and `legend.justification.inside`, allowing inside
26+
legends to be placed at different positions. Only inside legends with the same
27+
position and justification will be merged (@Yunuuuu, #6210).
28+
* New stat: `stat_manual()` for arbitrary computations (@teunbrand, #3501)
29+
* Reversal of a dimension, typically 'x' or 'y', is now controlled by the
30+
`reverse` argument in `coord_cartesian()`, `coord_fixed()`, `coord_radial()`
31+
and `coord_sf()`. In `coord_radial()`, this replaces the older `direction`
32+
argument (#4021, @teunbrand).
33+
* `coord_radial()` displays minor gridlines now (@teunbrand).
34+
* (internal) `continuous_scale()` and `binned_scale()` sort the `limits`
35+
argument internally (@teunbrand).
36+
* Theme margins can have NA-units to inherit from parent elements. The new
37+
function `margin_part()` has NA-units as default (@teunbrand, #6115)
38+
* New `margin_auto()` specification for theme margins.
39+
* New argument `labs(dictionary)` to label based on variable name rather than
40+
based on aesthetic (@teunbrand, #5178)
41+
* Fixed bug in out-of-bounds binned breaks (@teunbrand, #6054)
42+
* Binned guides now accept expressions as labels (@teunbrand, #6005)
43+
* (internal) `Scale$get_labels()` format expressions as lists.
44+
* In non-orthogonal coordinate systems (`coord_sf()`, `coord_polar()` and
45+
`coord_radial()`), using 'AsIs' variables escape transformation when
46+
both `x` and `y` is an 'AsIs' variable (@teunbrand, #6205).
47+
* The following methods have been deprecated: `fortify.lm()`, `fortify.glht()`,
48+
`fortify.confint.glht()`, `fortify.summary.glht()` and `fortify.cld()`. It
49+
is recommend to use `broom::augment()` and `broom::tidy()` instead
50+
(@teunbrand, #3816).
551
* Custom and raster annotation now respond to scale transformations, and can
652
use AsIs variables for relative placement (@teunbrand based on
753
@yutannihilation's prior work, #3120)
@@ -17,6 +63,13 @@
1763
(@teunbrand, #4320)
1864
* `geom_boxplot()` gains additional arguments to style the colour, linetype and
1965
linewidths of the box, whiskers, median line and staples (@teunbrand, #5126)
66+
* `geom_violin()` gains additional arguments to style the colour, linetype and
67+
linewidths of the quantiles, which replace the now-deprecated `draw_quantiles`
68+
argument (#5912).
69+
* (breaking) `geom_violin(quantiles)` now has actual quantiles based on
70+
the data, rather than inferred quantiles based on the computed density. The
71+
`quantiles` parameter that replaces `draw_quantiles` now belongs to
72+
`stat_ydensity()` instead of `geom_violin()` (@teunbrand, #4120).
2073
* (internal) Using `after_scale()` in the `Geom*$default_aes()` field is now
2174
evaluated in the context of data (@teunbrand, #6135)
2275
* Fixed bug where binned scales wouldn't simultaneously accept transformations
@@ -205,8 +258,28 @@
205258
* The ellipsis argument is now checked in `fortify()`, `get_alt_text()`,
206259
`labs()` and several guides (@teunbrand, #3196).
207260
* `stat_summary_bin()` no longer ignores `width` parameter (@teunbrand, #4647).
208-
* Added `keep.zeroes` argument to `stat_bin()` (@teunbrand, #3449)
261+
* Reintroduced `drop` argument to `stat_bin()` (@teunbrand, #3449)
262+
* (internal) removed barriers for using 2D structures as aesthetics
263+
(@teunbrand, #4189).
209264
* `coord_sf()` no longer errors when dealing with empty graticules (@teunbrand, #6052)
265+
* Added `theme_transparent()` with transparent backgrounds (@topepo).
266+
* New theme elements `palette.{aes}.discrete` and `palette.{aes}.continuous`.
267+
Theme palettes replace palettes in scales where `palette = NULL`, which is
268+
the new default in many scales (@teunbrand, #4696).
269+
* `guide_axis()` no longer reserves space for blank ticks
270+
(@teunbrand, #4722, #6069).
271+
* `geom_abline()` clips to the panel range in the vertical direction too
272+
(@teunbrand, #6086).
273+
* Added `panel.widths` and `panel.heights` to `theme()` (#5338, @teunbrand).
274+
* Standardised the calculation of `width`, which are now implemented as
275+
aesthetics (@teunbrand, #2800).
276+
* Stricter check on `register_theme_elements(element_tree)` (@teunbrand, #6162)
277+
* Added `weight` aesthetic for `stat_ellipse()` (@teunbrand, #5272)
278+
* Fixed a bug where the `guide_custom(order)` wasn't working (@teunbrand, #6195)
279+
* All binning stats now use the `boundary`/`center` parametrisation rather
280+
than `origin`, following in `stat_bin()`'s footsteps (@teunbrand).
281+
* `stat_summary_2d()` and `stat_bin_2d()` now deal with zero-range data
282+
more elegantly (@teunbrand, #6207).
210283

211284
# ggplot2 3.5.1
212285

R/aes.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ NULL
3838
#'
3939
#' [Delayed evaluation][aes_eval] for working with computed variables.
4040
#'
41+
#' @note
42+
#' Using `I()` to create objects of class 'AsIs' causes scales to ignore the
43+
#' variable and assumes the wrapped variable is direct input for the grid
44+
#' package. Please be aware that variables are sometimes combined, like in
45+
#' some stats or position adjustments, that may yield unexpected results with
46+
#' 'AsIs' variables.
47+
#'
4148
#' @family aesthetics documentation
4249
#' @return A list with class `uneval`. Components of the list are either
4350
#' quosures or constants.

R/bin.R

Lines changed: 94 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,12 @@ bin_breaks <- function(breaks, closed = c("right", "left")) {
5454

5555
bin_breaks_width <- function(x_range, width = NULL, center = NULL,
5656
boundary = NULL, closed = c("right", "left")) {
57-
check_length(x_range, 2L)
5857

59-
# binwidth seems to be the argument name supplied to width. (stat-bin and stat-bindot)
60-
check_number_decimal(width, min = 0, allow_infinite = FALSE, arg = "binwidth")
61-
62-
if (!is.null(boundary) && !is.null(center)) {
63-
cli::cli_abort("Only one of {.arg boundary} and {.arg center} may be specified.")
64-
} else if (is.null(boundary)) {
58+
if (is.null(boundary)) {
6559
if (is.null(center)) {
6660
# If neither edge nor center given, compute both using tile layer's
6761
# algorithm. This puts min and max of data in outer half of their bins.
6862
boundary <- width / 2
69-
7063
} else {
7164
# If center given but not boundary, compute boundary.
7265
boundary <- center - width / 2
@@ -75,9 +68,6 @@ bin_breaks_width <- function(x_range, width = NULL, center = NULL,
7568

7669
# Find the left side of left-most bin: inputs could be Dates or POSIXct, so
7770
# coerce to numeric first.
78-
x_range <- as.numeric(x_range)
79-
width <- as.numeric(width)
80-
boundary <- as.numeric(boundary)
8171
shift <- floor((x_range[1] - boundary) / width)
8272
origin <- boundary + shift * width
8373

@@ -104,9 +94,7 @@ bin_breaks_width <- function(x_range, width = NULL, center = NULL,
10494

10595
bin_breaks_bins <- function(x_range, bins = 30, center = NULL,
10696
boundary = NULL, closed = c("right", "left")) {
107-
check_length(x_range, 2L)
10897

109-
check_number_whole(bins, min = 1)
11098
if (zero_range(x_range)) {
11199
# 0.1 is the same width as the expansion `default_expansion()` gives for 0-width data
112100
width <- 0.1
@@ -128,6 +116,56 @@ bin_breaks_bins <- function(x_range, bins = 30, center = NULL,
128116

129117
# Compute bins ------------------------------------------------------------
130118

119+
compute_bins <- function(x, scale = NULL, breaks = NULL, binwidth = NULL, bins = NULL,
120+
center = NULL, boundary = NULL,
121+
closed = c("right", "left")) {
122+
123+
range <- if (is.scale(scale)) scale$dimension() else range(x)
124+
check_length(range, 2L)
125+
126+
if (!is.null(breaks)) {
127+
breaks <- allow_lambda(breaks)
128+
if (is.function(breaks)) {
129+
breaks <- breaks(x)
130+
}
131+
if (is.scale(scale) && !scale$is_discrete()) {
132+
breaks <- scale$transform(breaks)
133+
}
134+
check_numeric(breaks)
135+
bins <- bin_breaks(breaks, closed)
136+
return(bins)
137+
}
138+
139+
check_number_decimal(boundary, allow_infinite = FALSE, allow_null = TRUE)
140+
check_number_decimal(center, allow_infinite = FALSE, allow_null = TRUE)
141+
if (!is.null(boundary) && !is.null(center)) {
142+
cli::cli_abort("Only one of {.arg boundary} and {.arg center} may be specified.")
143+
}
144+
145+
if (!is.null(binwidth)) {
146+
binwidth <- allow_lambda(binwidth)
147+
if (is.function(binwidth)) {
148+
binwidth <- binwidth(x)
149+
}
150+
check_number_decimal(binwidth, min = 0, allow_infinite = FALSE)
151+
bins <- bin_breaks_width(
152+
range, binwidth,
153+
center = center, boundary = boundary, closed = closed
154+
)
155+
return(bins)
156+
}
157+
158+
bins <- allow_lambda(bins)
159+
if (is.function(bins)) {
160+
bins <- bins(x)
161+
}
162+
check_number_whole(bins, min = 1, allow_infinite = FALSE)
163+
bin_breaks_bins(
164+
range, bins,
165+
center = center, boundary = boundary, closed = closed
166+
)
167+
}
168+
131169
bin_vector <- function(x, bins, weight = NULL, pad = FALSE) {
132170
check_object(bins, is_bins, "a {.cls ggplot2_bins} object")
133171

@@ -141,8 +179,7 @@ bin_vector <- function(x, bins, weight = NULL, pad = FALSE) {
141179
weight[is.na(weight)] <- 0
142180
}
143181

144-
bin_idx <- cut(x, bins$fuzzy, right = bins$right_closed,
145-
include.lowest = TRUE)
182+
bin_idx <- bin_cut(x, bins)
146183
bin_count <- as.numeric(tapply(weight, bin_idx, sum, na.rm = TRUE))
147184
bin_count[is.na(bin_count)] <- 0
148185

@@ -170,6 +207,10 @@ bin_vector <- function(x, bins, weight = NULL, pad = FALSE) {
170207
bin_out(bin_count, bin_x, bin_widths)
171208
}
172209

210+
bin_cut <- function(x, bins) {
211+
cut(x, bins$fuzzy, right = bins$right_closed, include.lowest = TRUE)
212+
}
213+
173214
bin_out <- function(count = integer(0), x = numeric(0), width = numeric(0),
174215
xmin = x - width / 2, xmax = x + width / 2) {
175216
density <- count / width / sum(abs(count))
@@ -186,3 +227,41 @@ bin_out <- function(count = integer(0), x = numeric(0), width = numeric(0),
186227
.size = length(count)
187228
)
188229
}
230+
231+
bin_loc <- function(x, id) {
232+
left <- x[-length(x)]
233+
right <- x[-1]
234+
235+
list(
236+
left = left[id],
237+
right = right[id],
238+
mid = ((left + right) / 2)[id],
239+
length = diff(x)[id]
240+
)
241+
}
242+
243+
fix_bin_params = function(params, fun, version) {
244+
245+
if (!is.null(params$origin)) {
246+
args <- paste0(fun, c("(origin)", "(boundary)"))
247+
deprecate_warn0(version, args[1], args[2])
248+
params$boudnary <- params$origin
249+
params$origin <- NULL
250+
}
251+
252+
if (!is.null(params$right)) {
253+
args <- paste0(fun, c("(right)", "(closed)"))
254+
deprecate_warn0(version, args[1], args[2])
255+
params$closed <- if (isTRUE(params$right)) "right" else "left"
256+
params$right <- NULL
257+
}
258+
259+
if (is.null(params$breaks %||% params$binwidth %||% params$bins)) {
260+
cli::cli_inform(
261+
"{.fn {fun}} using {.code bins = 30}. Pick better value {.arg binwidth}."
262+
)
263+
params$bins <- 30
264+
}
265+
266+
params
267+
}

0 commit comments

Comments
 (0)