|
4 | 4 | #' @param end Position from 12 o'clock in radians where plot ends, to allow |
5 | 5 | #' for partial polar coordinates. The default, `NULL`, is set to |
6 | 6 | #' `start + 2 * pi`. |
| 7 | +#' @param thetalim,rlim Limits for the theta and r axes. |
7 | 8 | #' @param expand If `TRUE`, the default, adds a small expansion factor to |
8 | 9 | #' the limits to prevent overlap between data and axes. If `FALSE`, limits |
9 | 10 | #' are taken directly from the scale. |
|
40 | 41 | #' ggplot(mtcars, aes(disp, mpg)) + |
41 | 42 | #' geom_point() + |
42 | 43 | #' coord_radial(start = -0.4 * pi, end = 0.4 * pi, inner.radius = 0.3) |
| 44 | +#' |
| 45 | +#' # Similar with coord_cartesian(), you can set limits. |
| 46 | +#' ggplot(mtcars, aes(disp, mpg)) + |
| 47 | +#' geom_point() + |
| 48 | +#' coord_radial( |
| 49 | +#' start = -0.4 * pi, |
| 50 | +#' end = 0.4 * pi, inner.radius = 0.3, |
| 51 | +#' thetalim = c(200, 300), |
| 52 | +#' rlim = c(15, 30), |
| 53 | +#' ) |
43 | 54 | coord_radial <- function(theta = "x", |
44 | 55 | start = 0, end = NULL, |
45 | | - expand = TRUE, |
| 56 | + thetalim = NULL, rlim = NULL, expand = TRUE, |
46 | 57 | direction = deprecated(), |
47 | 58 | clip = "off", |
48 | 59 | r.axis.inside = NULL, |
@@ -91,11 +102,22 @@ coord_radial <- function(theta = "x", |
91 | 102 | arc <- switch(reverse, thetar = , theta = rev(arc), arc) |
92 | 103 |
|
93 | 104 | r.axis.inside <- r.axis.inside %||% !(abs(arc[2] - arc[1]) >= 1.999 * pi) |
| 105 | + if (isFALSE(r.axis.inside)) { |
| 106 | + place <- in_arc(c(0, 0.5, 1, 1.5) * pi, arc) |
| 107 | + if (!any(place)) { |
| 108 | + cli::cli_warn(c( |
| 109 | + "No appropriate placement found for outside {.field r.axis}.", |
| 110 | + i = "Will use {.code r.axis.inside = TRUE} instead" |
| 111 | + )) |
| 112 | + r.axis.inside <- TRUE |
| 113 | + } |
| 114 | + } |
94 | 115 |
|
95 | 116 | inner.radius <- c(inner.radius, 1) * 0.4 |
96 | 117 | inner.radius <- switch(reverse, thetar = , r = rev, identity)(inner.radius) |
97 | 118 |
|
98 | 119 | ggproto(NULL, CoordRadial, |
| 120 | + limits = list(theta = thetalim, r = rlim), |
99 | 121 | theta = theta, |
100 | 122 | r = r, |
101 | 123 | arc = arc, |
@@ -147,10 +169,20 @@ CoordRadial <- ggproto("CoordRadial", Coord, |
147 | 169 | }, |
148 | 170 |
|
149 | 171 | setup_panel_params = function(self, scale_x, scale_y, params = list()) { |
150 | | - |
| 172 | + if (self$theta == "x") { |
| 173 | + xlimits <- self$limits$theta |
| 174 | + ylimits <- self$limits$r |
| 175 | + } else { |
| 176 | + xlimits <- self$limits$r |
| 177 | + ylimits <- self$limits$theta |
| 178 | + } |
151 | 179 | params <- c( |
152 | | - view_scales_polar(scale_x, self$theta, expand = params$expand[c(4, 2)]), |
153 | | - view_scales_polar(scale_y, self$theta, expand = params$expand[c(3, 1)]), |
| 180 | + view_scales_polar(scale_x, self$theta, xlimits, |
| 181 | + expand = params$expand[c(4, 2)] |
| 182 | + ), |
| 183 | + view_scales_polar(scale_y, self$theta, ylimits, |
| 184 | + expand = params$expand[c(3, 1)] |
| 185 | + ), |
154 | 186 | list(bbox = polar_bbox(self$arc, inner_radius = self$inner_radius), |
155 | 187 | arc = self$arc, inner_radius = self$inner_radius) |
156 | 188 | ) |
@@ -431,38 +463,31 @@ CoordRadial <- ggproto("CoordRadial", Coord, |
431 | 463 |
|
432 | 464 | setup_params = function(self, data) { |
433 | 465 | params <- ggproto_parent(Coord, self)$setup_params(data) |
434 | | - if (!isFALSE(self$r_axis_inside)) { |
435 | | - return(params) |
436 | | - } |
437 | | - |
438 | | - place <- in_arc(c(0, 0.5, 1, 1.5) * pi, self$arc) |
439 | | - if (!any(place)) { |
440 | | - cli::cli_warn(c( |
441 | | - "No appropriate placement found for {.arg r_axis_inside}.", |
442 | | - i = "Axis will be placed at panel edge." |
443 | | - )) |
444 | | - params$r_axis_inside <- TRUE |
445 | | - return(params) |
| 466 | + if (isFALSE(self$r_axis_inside)) { |
| 467 | + place <- in_arc(c(0, 0.5, 1, 1.5) * pi, self$arc) |
| 468 | + params$r_axis <- if (any(place[c(1, 3)])) "left" else "bottom" |
| 469 | + params$fake_arc <- switch( |
| 470 | + which(place[c(1, 3, 2, 4)])[1], |
| 471 | + c(0, 2), c(1, 3), c(0.5, 2.5), c(1.5, 3.5) |
| 472 | + ) * pi |
446 | 473 | } |
447 | | - |
448 | | - params$r_axis <- if (any(place[c(1, 3)])) "left" else "bottom" |
449 | | - params$fake_arc <- switch( |
450 | | - which(place[c(1, 3, 2, 4)])[1], |
451 | | - c(0, 2), c(1, 3), c(0.5, 2.5), c(1.5, 3.5) |
452 | | - ) * pi |
453 | 474 | params |
454 | 475 | } |
455 | 476 | ) |
456 | 477 |
|
457 | | -view_scales_polar <- function(scale, theta = "x", expand = TRUE) { |
| 478 | +view_scales_polar <- function(scale, theta = "x", coord_limits = NULL, |
| 479 | + expand = TRUE) { |
458 | 480 |
|
459 | 481 | aesthetic <- scale$aesthetics[1] |
460 | 482 | is_theta <- theta == aesthetic |
461 | 483 | name <- if (is_theta) "theta" else "r" |
462 | 484 |
|
463 | 485 | expansion <- default_expansion(scale, expand = expand) |
464 | 486 | limits <- scale$get_limits() |
465 | | - continuous_range <- expand_limits_scale(scale, expansion, limits) |
| 487 | + continuous_range <- expand_limits_scale( |
| 488 | + scale, expansion, limits, |
| 489 | + coord_limits |
| 490 | + ) |
466 | 491 |
|
467 | 492 | primary <- view_scale_primary(scale, limits, continuous_range) |
468 | 493 | view_scales <- list( |
|
0 commit comments