tidyverse / ggplot2

An implementation of the Grammar of Graphics in R
https://ggplot2.tidyverse.org
Other
6.39k stars 2k forks source link

Custom inside-axis position for `coord_radial()` #5908

Open teunbrand opened 1 month ago

teunbrand commented 1 month ago

This PR aims to fix #5805.

Briefly, you can now use numeric values for coord_radial(r.axis.inside) that will place the radius axis at some specified position of the theta axis.

I think it is probably best illustrated how it works. Let's make plot with clock-positions.

devtools::load_all("~/packages/ggplot2")
#> ℹ Loading ggplot2

set.seed(42)
df <- data.frame(x = runif(100, max = 12), y = rnorm(100))

p <- ggplot(df, aes(x, y)) +
  geom_point() +
  scale_x_continuous(limits = c(0, 12), breaks = 1:12, expand = c(0, 0)) +
  theme(axis.line = element_line())

This is how one would set the position:

p + coord_radial(r.axis.inside = 4.5)

If for some reason you have secondary axes, you can set a vector to control primary and secondary separately.

p + coord_radial(r.axis.inside = c(4.5, 7)) +
  guides(r.sec = "axis")

Out of bounds axes get squished to the nearest limit.

p + coord_radial(r.axis.inside = -10)

Created on 2024-05-24 with reprex v2.1.0

BenVolpe94 commented 1 week ago

This is really nice! Am I correct that the radius axis angle provided to r_axis_inside is not calculated relative to the start point? I created a polar plot with a 360 degree x-axis limit. I chose a different start point and wanted to have the radial axis at 45 degrees, but I had to input 135 degrees instead, which is maybe counter intuitive. Also, I need to input the start value in radials, but the r_axis_inside value in degrees. For some reason the axis labels are rotated in my plot as well.

See code below:

set.seed(42)
df <- data.frame(x = runif(100, max = 360), y = rnorm(100))

p <- ggplot(df, aes(x, y)) +
  geom_point() +
  scale_x_continuous(limits = c(0, 360), breaks = seq(0, 360, by = 90)) +
  theme(axis.line = element_line())

p + coord_radial(theta = "x",
                 direction = -1,
                 start = -90 * pi / 180, 
                 clip = "off",
                 r_axis_inside = 135,
                 inner.radius = 0.075,
                 expand = FALSE)

image

teunbrand commented 1 week ago

Thanks for raising these points!

Also, I need to input the start value in radials, but the r_axis_inside value in degrees

The r_axis_inside value is in scale-units. If your scale indicates degrees, then r_axis_inside indicates degrees. If your scale indicates kilograms, then r_axis_inside indicates kilograms. I get how this might be confusing, but it is similar to how xlim and ylim work.

For some reason the axis labels are rotated in my plot as well.

Yeah that shouldn't happen, I'll try to figure out what is going wrong here.

teunbrand commented 1 week ago

Now correctly places axis at 135 degrees:

set.seed(42)
devtools::load_all("~/packages/ggplot2")
#> ℹ Loading ggplot2

df <- data.frame(x = runif(100, max = 360), y = rnorm(100))

p <- ggplot(df, aes(x, y)) +
  geom_point() +
  scale_x_continuous(limits = c(0, 360), breaks = seq(0, 360, by = 90)) +
  theme(axis.line = element_line())

p + coord_radial(theta = "x",
                 direction = -1,
                 start = -90 * pi / 180, 
                 clip = "off",
                 r.axis.inside = 135,
                 inner.radius = 0.075,
                 expand = FALSE)

Created on 2024-06-27 with reprex v2.1.0