Skip to content

Commit 09776db

Browse files
authored
🐛 Deal with empty radial axes (#6272)
* Avoid assigning NULL to list, thereby deleting the element * protect theta guide better against empty keys * add test * add news bullet * Fix partial match * fix another partial match
1 parent 12d1c98 commit 09776db

File tree

5 files changed

+56
-30
lines changed

5 files changed

+56
-30
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# ggplot2 (development version)
22

3+
* `coord_radial()` now displays no axis instead of throwing an error when
4+
a scale has no breaks (@teunbrand, #6271).
35
* The `fatten` argument has been deprecated in `geom_boxplot()`,
46
`geom_crossbar()` and `geom_pointrange()` (@teunbrand, #4881).
57
* Axis labels are now preserved better when using `coord_sf(expand = TRUE)` and

R/coord-radial.R

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,18 @@ CoordRadial <- ggproto("CoordRadial", Coord,
250250
names(gdefs) <- aesthetics
251251

252252
# Train theta guide
253-
for (t in intersect(c("theta", "theta.sec"), aesthetics[!empty])) {
254-
gdefs[[t]] <- guides[[t]]$train(gdefs[[t]], panel_params[[t]])
255-
gdefs[[t]] <- guides[[t]]$transform(gdefs[[t]], self, panel_params)
256-
gdefs[[t]] <- guides[[t]]$get_layer_key(gdefs[[t]], layers)
257-
}
253+
t <- intersect(c("theta", "theta.sec"), aesthetics[!empty])
254+
gdefs[t] <- Map(
255+
function(guide, guide_param, scale) {
256+
guide_param$theme_suffix <- "theta"
257+
guide_param <- guide$train(guide_param, scale)
258+
guide_param <- guide$transform(guide_param, self, panel_params)
259+
guide_param <- guide$get_layer_key(guide_param, layers)
260+
},
261+
guide = guides[t],
262+
guide_param = gdefs[t],
263+
scale = panel_params[t]
264+
)
258265

259266
if (!isFALSE(self$r_axis_inside)) {
260267
# For radial axis, we need to pretend that rotation starts at 0 and
@@ -269,17 +276,18 @@ CoordRadial <- ggproto("CoordRadial", Coord,
269276
temp <- modify_list(panel_params, mod)
270277

271278
# Train radial guide
272-
for (r in intersect(c("r", "r.sec"), aesthetics[!empty])) {
273-
gdefs[[r]] <- guides[[r]]$train(gdefs[[r]], panel_params[[r]])
274-
gdefs[[r]] <- guides[[r]]$transform(gdefs[[r]], self, temp) # Use temp
275-
gdefs[[r]] <- guides[[r]]$get_layer_key(gdefs[[r]], layers)
276-
}
277-
278-
# Set theme suffixes
279-
gdefs$theta$theme_suffix <- "theta"
280-
gdefs$theta.sec$theme_suffix <- "theta"
281-
gdefs$r$theme_suffix <- "r"
282-
gdefs$r.sec$theme_suffix <- "r"
279+
r <- intersect(c("r", "r.sec"), aesthetics[!empty])
280+
gdefs[r] <- Map(
281+
function(guide, guide_param, scale) {
282+
guide_param$theme_suffix <- "r"
283+
guide_param <- guide$train(guide_param, scale)
284+
guide_param <- guide$transform(guide_param, self, temp)
285+
guide_param <- guide$get_layer_key(guide_param, layers)
286+
},
287+
guide = guides[r],
288+
guide_param = gdefs[r],
289+
scale = panel_params[r]
290+
)
283291

284292
panel_params$guides$update_params(gdefs)
285293
panel_params

R/guide-axis-theta.R

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,26 @@ GuideAxisTheta <- ggproto(
6363

6464
transform = function(params, coord, panel_params) {
6565

66-
opposite_var <- setdiff(c("x", "y"), params$aesthetic)
67-
opposite_value <- switch(params$position, top = , right = , theta.sec = -Inf, Inf)
68-
if (is.unsorted(panel_params$inner_radius %||% NA)) {
69-
opposite_value <- -opposite_value
70-
}
71-
if (nrow(params$key) > 0) {
72-
params$key[[opposite_var]] <- opposite_value
73-
}
74-
if (nrow(params$decor) > 0) {
75-
params$decor[[opposite_var]] <- opposite_value
66+
position <- params$position
67+
68+
if (!is.null(position)) {
69+
opposite_var <- setdiff(c("x", "y"), params$aesthetic)
70+
opposite_value <- switch(position, top = , right = , theta.sec = -Inf, Inf)
71+
if (is.unsorted(panel_params$inner_radius %||% NA)) {
72+
opposite_value <- -opposite_value
73+
}
74+
if (nrow(params$key) > 0) {
75+
params$key[[opposite_var]] <- opposite_value
76+
}
77+
if (nrow(params$decor) > 0) {
78+
params$decor[[opposite_var]] <- opposite_value
79+
}
7680
}
7781

7882
params <- GuideAxis$transform(params, coord, panel_params)
7983

8084
key <- params$key
81-
n <- nrow(key)
85+
n <- vec_size(key)
8286
if (n < 1) {
8387
return(params)
8488
}

R/guides-.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ Guides <- ggproto(
525525
coord <- coord %||% default_inside_position %||% just
526526

527527
groups$justs[[i]] <- just
528-
groups$coord[[i]] <- coord
528+
groups$coords[[i]] <- coord
529529
}
530530

531531
groups <- vec_group_loc(vec_slice(groups, keep))
@@ -540,10 +540,10 @@ Guides <- ggproto(
540540
# prepare output
541541
for (i in vec_seq_along(groups)) {
542542
adjust <- NULL
543-
position <- groups$key$position[i]
543+
position <- groups$key$positions[i]
544544
if (position == "inside") {
545545
adjust <- theme(
546-
legend.position.inside = groups$key$coord[[i]],
546+
legend.position.inside = groups$key$coords[[i]],
547547
legend.justification.inside = groups$key$justs[[i]]
548548
)
549549
}

tests/testthat/test-coord-polar.R

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,18 @@ test_that("radial coords can be reversed", {
197197
expect_equal(as.numeric(fwd$y), rev(as.numeric(rev$y)))
198198
})
199199

200+
test_that("coord_radial can deal with empty breaks (#6271)", {
201+
p <- ggplot_build(
202+
ggplot(mtcars, aes(mpg, disp)) +
203+
geom_point() +
204+
coord_radial() +
205+
scale_x_continuous(breaks = numeric()) +
206+
scale_y_continuous(breaks = numeric())
207+
)
208+
guides <- p$layout$panel_params[[1]]$guides$guides
209+
is_none <- vapply(guides, inherits, logical(1), what = "GuideNone")
210+
expect_true(all(is_none))
211+
})
200212

201213
# Visual tests ------------------------------------------------------------
202214

0 commit comments

Comments
 (0)