Skip to content

Radial inner radius #5679

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

Merged
merged 2 commits into from
Feb 12, 2024
Merged
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
44 changes: 22 additions & 22 deletions R/coord-radial.R
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,30 @@
#' in accordance with the computed `theta` position. If `FALSE` (default),
#' no such transformation is performed. Can be useful to rotate text geoms in
#' alignment with the coordinates.
#' @param donut A `numeric` between 0 and 1 setting the size of a donut hole.
#' @param inner.radius A `numeric` between 0 and 1 setting the size of a inner.radius hole.
#'
#' @note
#' In `coord_radial()`, position guides are can be defined by using
#' `guides(r = ..., theta = ..., r.sec = ..., theta.sec = ...)`. Note that
#' these guides require `r` and `theta` as available aesthetics. The classic
#' `guide_axis()` can be used for the `r` positions and `guide_axis_theta()` can
#' be used for the `theta` positions. Using the `theta.sec` position is only
#' sensible when `donut > 0`.
#' sensible when `inner.radius > 0`.
#'
#' @export
#' @examples
#' # A partial polar plot
#' ggplot(mtcars, aes(disp, mpg)) +
#' geom_point() +
#' coord_radial(start = -0.4 * pi, end = 0.4 * pi, donut = 0.3)
#' coord_radial(start = -0.4 * pi, end = 0.4 * pi, inner.radius = 0.3)
coord_radial <- function(theta = "x",
start = 0, end = NULL,
expand = TRUE,
direction = 1,
clip = "off",
r_axis_inside = NULL,
rotate_angle = FALSE,
donut = 0) {
inner.radius = 0) {

theta <- arg_match0(theta, c("x", "y"))
r <- if (theta == "x") "y" else "x"
Expand All @@ -47,7 +47,7 @@ coord_radial <- function(theta = "x",
check_bool(rotate_angle)
check_number_decimal(start, allow_infinite = FALSE)
check_number_decimal(end, allow_infinite = FALSE, allow_null = TRUE)
check_number_decimal(donut, min = 0, max = 1, allow_infinite = FALSE)
check_number_decimal(inner.radius, min = 0, max = 1, allow_infinite = FALSE)

end <- end %||% (start + 2 * pi)
if (start > end) {
Expand All @@ -64,7 +64,7 @@ coord_radial <- function(theta = "x",
direction = sign(direction),
r_axis_inside = r_axis_inside,
rotate_angle = rotate_angle,
donut = c(donut, 1) * 0.4,
inner_radius = c(inner.radius, 1) * 0.4,
clip = clip
)
}
Expand All @@ -84,13 +84,13 @@ CoordRadial <- ggproto("CoordRadial", Coord,
distance = function(self, x, y, details) {
arc <- details$arc %||% c(0, 2 * pi)
if (self$theta == "x") {
r <- rescale(y, from = details$r.range, to = self$donut / 0.4)
r <- rescale(y, from = details$r.range, to = self$inner_radius / 0.4)
theta <- theta_rescale_no_clip(
x, details$theta.range,
arc, self$direction
)
} else {
r <- rescale(x, from = details$r.range, to = self$donut / 0.4)
r <- rescale(x, from = details$r.range, to = self$inner_radius / 0.4)
theta <- theta_rescale_no_clip(
y, details$theta.range,
arc, self$direction
Expand All @@ -117,8 +117,8 @@ CoordRadial <- ggproto("CoordRadial", Coord,
c(
view_scales_polar(scale_x, self$theta, expand = self$expand),
view_scales_polar(scale_y, self$theta, expand = self$expand),
list(bbox = polar_bbox(self$arc, donut = self$donut),
arc = self$arc, donut = self$donut)
list(bbox = polar_bbox(self$arc, inner_radius = self$inner_radius),
arc = self$arc, inner_radius = self$inner_radius)
)
},

Expand Down Expand Up @@ -224,7 +224,7 @@ CoordRadial <- ggproto("CoordRadial", Coord,
bbox <- panel_params$bbox %||% list(x = c(0, 1), y = c(0, 1))
arc <- panel_params$arc %||% c(0, 2 * pi)

data$r <- r_rescale(data$r, panel_params$r.range, panel_params$donut)
data$r <- r_rescale(data$r, panel_params$r.range, panel_params$inner_radius)
data$theta <- theta_rescale(
data$theta, panel_params$theta.range,
arc, self$direction
Expand Down Expand Up @@ -258,7 +258,7 @@ CoordRadial <- ggproto("CoordRadial", Coord,
bbox <- panel_params$bbox %||% list(x = c(0, 1), y = c(0, 1))
arc <- panel_params$arc %||% c(0, 2 * pi)
dir <- self$direction
donut <- panel_params$donut
inner_radius <- panel_params$inner_radius

theta_lim <- panel_params$theta.range
theta_maj <- panel_params$theta.major
Expand All @@ -273,7 +273,7 @@ CoordRadial <- ggproto("CoordRadial", Coord,
theta_fine <- seq(self$arc[1], self$arc[2], length.out = 100)

r_fine <- r_rescale(panel_params$r.major, panel_params$r.range,
panel_params$donut)
panel_params$inner_radius)

# This gets the proper theme element for theta and r grid lines:
# panel.grid.major.x or .y
Expand Down Expand Up @@ -308,8 +308,8 @@ CoordRadial <- ggproto("CoordRadial", Coord,

ggname("grill", grobTree(
background,
theta_grid(theta_maj, grid_elems[[1]], donut, bbox),
theta_grid(theta_min, grid_elems[[2]], donut, bbox),
theta_grid(theta_maj, grid_elems[[1]], inner_radius, bbox),
theta_grid(theta_min, grid_elems[[2]], inner_radius, bbox),
element_render(
theme, majorr, name = "radius",
x = rescale(rep(r_fine, each = length(theta_fine)) *
Expand Down Expand Up @@ -453,7 +453,7 @@ view_scales_polar <- function(scale, theta = "x", expand = TRUE) {
#' @examples
#' polar_bbox(c(0, 1) * pi)
polar_bbox <- function(arc, margin = c(0.05, 0.05, 0.05, 0.05),
donut = c(0, 0.4)) {
inner_radius = c(0, 0.4)) {

# Early exit if we have full circle or more
if (abs(diff(arc)) >= 2 * pi) {
Expand All @@ -463,8 +463,8 @@ polar_bbox <- function(arc, margin = c(0.05, 0.05, 0.05, 0.05),
# X and Y position of the sector arc ends
xmax <- 0.5 * sin(arc) + 0.5
ymax <- 0.5 * cos(arc) + 0.5
xmin <- donut[1] * sin(arc) + 0.5
ymin <- donut[1] * cos(arc) + 0.5
xmin <- inner_radius[1] * sin(arc) + 0.5
ymin <- inner_radius[1] * cos(arc) + 0.5

margin <- c(
max(ymin) + margin[1],
Expand Down Expand Up @@ -546,16 +546,16 @@ flip_data_text_angle <- function(data) {
}


theta_grid <- function(theta, element, donut = c(0, 0.4),
theta_grid <- function(theta, element, inner_radius = c(0, 0.4),
bbox = list(x = c(0, 1), y = c(0, 1))) {
n <- length(theta)
if (n < 1) {
return(NULL)
}

donut <- rep(donut, n)
x <- rep(sin(theta), each = 2) * donut + 0.5
y <- rep(cos(theta), each = 2) * donut + 0.5
inner_radius <- rep(inner_radius, n)
x <- rep(sin(theta), each = 2) * inner_radius + 0.5
y <- rep(cos(theta), each = 2) * inner_radius + 0.5

element_grob(
element,
Expand Down
8 changes: 4 additions & 4 deletions man/coord_polar.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 5 additions & 5 deletions tests/testthat/test-coord-polar.R
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,9 @@ test_that("bounding box calculations are sensible", {
list(x = c(0.45, 1), y = c(0.146446609, 0.853553391))
)

# Top quarter of circle with donuthole
# Top quarter of circle with inner radius
expect_equal(
polar_bbox(arc = c(-0.25 * pi, 0.25 * pi), donut = c(0.2, 0.4)),
polar_bbox(arc = c(-0.25 * pi, 0.25 * pi), inner_radius = c(0.2, 0.4)),
list(x = c(0.146446609, 0.853553391), y = c(0.59142136, 1))
)
})
Expand Down Expand Up @@ -219,13 +219,13 @@ test_that("coord_radial() draws correctly", {
geom_point() +
theme

expect_doppelganger("donut with all axes", {
p + coord_radial(donut = 0.3, r_axis_inside = FALSE) +
expect_doppelganger("inner.radius with all axes", {
p + coord_radial(inner.radius = 0.3, r_axis_inside = FALSE) +
guides(r.sec = "axis", theta.sec = "axis_theta")
})

expect_doppelganger("partial with all axes", {
p + coord_radial(start = 0.25 * pi, end = 0.75 * pi, donut = 0.3,
p + coord_radial(start = 0.25 * pi, end = 0.75 * pi, inner.radius = 0.3,
r_axis_inside = TRUE, theta = "y") +
guides(r.sec = "axis", theta.sec = "axis_theta")
})
Expand Down
4 changes: 2 additions & 2 deletions tests/testthat/test-guides.R
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ test_that("guide_axis_stack stacks axes", {
p <- ggplot(mtcars, aes(hp, disp)) +
geom_point() +
theme(axis.line = element_line()) +
coord_radial(start = 0.25 * pi, end = 1.75 * pi, donut = 0.5) +
coord_radial(start = 0.25 * pi, end = 1.75 * pi, inner.radius = 0.5) +
guides(theta = top, theta.sec = bottom, r = left, r.sec = right)
expect_doppelganger("stacked radial axes", p)

Expand Down Expand Up @@ -1110,7 +1110,7 @@ test_that("guide_axis_theta sets relative angle", {
p <- ggplot(mtcars, aes(disp, mpg)) +
geom_point() +
scale_x_continuous(breaks = breaks_width(25)) +
coord_radial(donut = 0.5) +
coord_radial(inner.radius = 0.5) +
guides(
theta = guide_axis_theta(angle = 0, cap = "none"),
theta.sec = guide_axis_theta(angle = 90, cap = "both")
Expand Down