Skip to content
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

Custom inside-axis position for coord_radial() #5908

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# ggplot2 (development version)

* `coord_radial(r.axis.inside)` can now take a numeric value to control
placement of internally placed radius axes (@teunbrand, #5805).
* The `arrow.fill` parameter is now applied to more line-based functions:
`geom_path()`, `geom_line()`, `geom_step()` `geom_function()`, line
geometries in `geom_sf()` and `element_line()`.
Expand Down
59 changes: 42 additions & 17 deletions R/coord-radial.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
#' @param expand If `TRUE`, the default, adds a small expansion factor the
#' the limits to prevent overlap between data and axes. If `FALSE`, limits
#' are taken directly from the scale.
#' @param r.axis.inside If `TRUE`, places the radius axis inside the
#' panel. If `FALSE`, places the radius axis next to the panel. The default,
#' `NULL`, places the radius axis outside if the `start` and `end` arguments
#' form a full circle.
#' @param r.axis.inside One of the following:
#' * `NULL` (default) places the axis next to the panel if `start` and
#' `end` arguments form a full circle and inside the panel otherwise.
#' * `TRUE` to place the radius axis inside the panel.
#' * `FALSE` to place the radius axis next to the panel.
#' * A numeric value, setting a theta axis value at which
#' the axis should be placed inside the panel. Can be given as a length 2
#' vector to control primary and secondary axis placement separately.
#' @param rotate.angle If `TRUE`, transforms the `angle` aesthetic in data
#' in accordance with the computed `theta` position. If `FALSE` (default),
#' no such transformation is performed. Can be useful to rotate text geoms in
Expand Down Expand Up @@ -58,7 +62,10 @@ coord_radial <- function(theta = "x",

theta <- arg_match0(theta, c("x", "y"))
r <- if (theta == "x") "y" else "x"
check_bool(r.axis.inside, allow_null = TRUE)
if (!is.numeric(r.axis.inside)) {
check_bool(r.axis.inside, allow_null = TRUE)
}

check_bool(expand)
check_bool(rotate.angle)
check_number_decimal(start, allow_infinite = FALSE)
Expand Down Expand Up @@ -130,12 +137,29 @@ CoordRadial <- ggproto("CoordRadial", Coord,
},

setup_panel_params = function(self, scale_x, scale_y, params = list()) {
c(

params <- 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, inner_radius = self$inner_radius),
arc = self$arc, inner_radius = self$inner_radius)
)

axis_rotation <- self$r_axis_inside
if (is.numeric(axis_rotation)) {
theta_scale <- switch(self$theta, x = scale_x, y = scale_y)
axis_rotation <- theta_scale$transform(axis_rotation)
axis_rotation <- oob_squish(axis_rotation, params$theta.range)
axis_rotation <- theta_rescale(
axis_rotation, params$theta.range,
params$arc, self$direction
)
params$axis_rotation <- rep_len(axis_rotation, length.out = 2)
} else {
params$axis_rotation <- params$arc
}

params
},

setup_panel_guides = function(self, panel_params, guides, params = list()) {
Expand Down Expand Up @@ -173,9 +197,9 @@ CoordRadial <- ggproto("CoordRadial", Coord,
opposite_r <- isTRUE(scales$r$position %in% c("bottom", "left"))
}

if (self$r_axis_inside) {
if (!isFALSE(self$r_axis_inside)) {

arc <- rad2deg(self$arc)
arc <- rad2deg(panel_params$axis_rotation)
r_position <- c("left", "right")
# If both opposite direction and opposite position, don't flip
if (xor(self$direction == -1, opposite_r)) {
Expand Down Expand Up @@ -223,7 +247,7 @@ CoordRadial <- ggproto("CoordRadial", Coord,
gdefs[[t]] <- guides[[t]]$get_layer_key(gdefs[[t]], layers)
}

if (self$r_axis_inside) {
if (!isFALSE(self$r_axis_inside)) {
# For radial axis, we need to pretend that rotation starts at 0 and
# the bounding box is for circles, otherwise tick positions will be
# spaced too closely.
Expand Down Expand Up @@ -273,14 +297,14 @@ CoordRadial <- ggproto("CoordRadial", Coord,
},

render_axis_v = function(self, panel_params, theme) {
if (self$r_axis_inside) {
if (!isFALSE(self$r_axis_inside)) {
return(list(left = zeroGrob(), right = zeroGrob()))
}
CoordCartesian$render_axis_v(panel_params, theme)
},

render_axis_h = function(self, panel_params, theme) {
if (self$r_axis_inside) {
if (!isFALSE(self$r_axis_inside)) {
return(list(top = zeroGrob(), bottom = zeroGrob()))
}
CoordCartesian$render_axis_h(panel_params, theme)
Expand Down Expand Up @@ -359,7 +383,7 @@ CoordRadial <- ggproto("CoordRadial", Coord,

border <- element_render(theme, "panel.border", fill = NA)

if (!self$r_axis_inside) {
if (isFALSE(self$r_axis_inside)) {
out <- grobTree(
panel_guides_grob(panel_params$guides, "theta", theme),
panel_guides_grob(panel_params$guides, "theta.sec", theme),
Expand All @@ -370,14 +394,15 @@ CoordRadial <- ggproto("CoordRadial", Coord,

bbox <- panel_params$bbox
dir <- self$direction
arc <- if (dir == 1) self$arc else rev(self$arc)
arc <- dir * rad2deg(-arc)
rot <- panel_params$axis_rotation
rot <- if (dir == 1) rot else rev(rot)
rot <- dir * rad2deg(-rot)

left <- panel_guides_grob(panel_params$guides, position = "left", theme)
left <- rotate_r_axis(left, arc[1], bbox, "left")
left <- rotate_r_axis(left, rot[1], bbox, "left")

right <- panel_guides_grob(panel_params$guides, position = "right", theme)
right <- rotate_r_axis(right, arc[2], bbox, "right")
right <- rotate_r_axis(right, rot[2], bbox, "right")

grobTree(
panel_guides_grob(panel_params$guides, "theta", theme),
Expand Down Expand Up @@ -426,7 +451,7 @@ CoordRadial <- ggproto("CoordRadial", Coord,
},

setup_params = function(self, data) {
if (!self$r_axis_inside) {
if (isFALSE(self$r_axis_inside)) {
place <- in_arc(c(0, 0.5, 1, 1.5) * pi, self$arc)
if (place[1]) {
return(list(r_axis = "left", fake_arc = c(0, 2) * pi))
Expand Down
14 changes: 10 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
Loading