Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to turn off clipping only for certain geoms in ggplot2?

Tags:

r

ggplot2

I have this sample density curve data (found here):

library(tidyverse)
z <- rnorm(1000, mean = 0, sd = 1)
dens <- density(z)
data <- tibble(x = dens$x, y = dens$y) %>% 
  mutate(variable = case_when(
    (x >= -2 & x <= 0) ~ "On",
    (x >= 0.2 & x <= 1) ~ "Off",
    TRUE ~ NA_character_))

I plot this curve with ggplot2, along with highlighted regions using geom_area, along with some text created using geom_text outside the plot boundaries, requiring me to turn off clipping in coord_cartesian:

ggplot(data, aes(x, y)) + geom_line() +
  geom_area(data = filter(data, variable == 'On'), fill = 'grey') + 
  geom_area(data = filter(data, variable == 'Off'), fill = 'light blue') +
  geom_text(aes(x = 7, y = 0.15, label = "test")) +
  theme(plot.margin = unit(c(1,7,1,1), "lines")) +
  coord_cartesian(xlim = c(-5, 5),
                  # ylim = c(0.1, 0.2),
                  clip = "off")

enter image description here

What I would like to do now, is to zoom into y-axis between 0.1 and 0.2. I know that if I use the limits argument in scale_y_continuous, then this can sometimes remove data which is constraining the view, so I use the ylim argument inside coord_cartesian set as c(0.1, 0.2).

However, this causes the density area and curve to overlap the plot boundaries (as I've turned off clipping).

enter image description here

What I could do now, is to turn on clipping in coord_cartesian, however this would now remove the geom_text outside the plot boundaries which I need. Is there any way to reconcile my issue?

enter image description here

like image 472
Nautica Avatar asked Oct 29 '25 06:10

Nautica


1 Answers

This is a good use case to use the oob argument of the position scales in a non-standard way. The scales package has several out-of-bounds function that can serve you here, notably oob_squish(), which sets out-of-bounds to nearest limits, or oob_keep(), which keeps out-of-bounds data, similar to setting coordinate limits.

library(tidyverse)
#> Warning: package 'ggplot2' was built under R version 4.0.2
z <- rnorm(1000, mean = 0, sd = 1)
dens <- density(z)
data <- tibble(x = dens$x, y = dens$y) %>% 
  mutate(variable = case_when(
    (x >= -2 & x <= 0) ~ "On",
    (x >= 0.2 & x <= 1) ~ "Off",
    TRUE ~ NA_character_))

ggplot(data, aes(x, y)) + geom_line() +
  geom_area(data = filter(data, variable == 'On'), fill = 'grey') + 
  geom_area(data = filter(data, variable == 'Off'), fill = 'light blue') +
  geom_text(aes(x = 7, y = 0.15, label = "test")) +
  theme(plot.margin = unit(c(1,7,1,1), "lines")) +
  scale_y_continuous(limits = c(0.1, 0.2),
                     expand = c(0, 0),
                     oob = scales::oob_squish) +
  scale_x_continuous(limits = c(-5, 5), 
                     oob = scales::oob_keep) +
  coord_cartesian(clip = "off")

Created on 2020-12-25 by the reprex package (v0.3.0)

like image 119
teunbrand Avatar answered Oct 31 '25 20:10

teunbrand



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!