3

I want to add a background fill to a plot created with grouped data (factor x axis) and a log-scale y axis. When the log-scale is added, the background fill is removed.

Is this a bug, or am I doing something wrong?

Reproducible Example data: I'll use the mtcars data, but with the cyl variable as a factor. This is the simplest dataset that mimics my data.

library(dplyr)
library(ggplot2)
mtcars_f <- mtcars %>% 
  mutate(cyl.f = factor(cyl)) 

This works fine with a normal y-axis scale.

mtcars_f %>% 
  ggplot(aes(cyl.f, mpg)) +
  geom_rect(xmin=-Inf, ymin=17.5, xmax=Inf, ymax=22.5) +
  geom_point() 

enter image description here

The Problem: However, the background rectangle fill is removed when the y-axis is transformed:

mtcars_f %>% 
  ggplot(aes(cyl.f, mpg)) +
  geom_rect(xmin=-Inf, ymin=17.5, xmax=Inf, ymax=22.5) +
  geom_point() +
  scale_y_log10()

enter image description here

note: this is a different issue than this similarly titled question

EDIT with answer: The answer by @Tung works! This can also be worked around by passing the data to geom_rect as an aesthetic, and you specify the x-axis as "discrete"

rect_df <- 
  data_frame(xmin=-Inf, ymin=17.5, xmax=Inf, ymax=22.5)
mtcars_f %>% 
  ggplot(aes(cyl.f, mpg)) +
  geom_rect(data = rect_df, aes(xmin=xmin, ymin=ymin, xmax=xmax, ymax=ymax), inherit.aes = F) +
  geom_point() +
  scale_y_log10() +
  scale_x_discrete()
Matt L.
  • 2,753
  • 13
  • 22
  • 2
    I've figured out the rectangle is still there, it's just outside the plot limits. When data is passed to `geom_rect` outside of a dataframe and the proper mapping with `aes()` the numbers are altered when the scale is changed. It can be seen after adding to the scale command: `scale_y_log10(limits = c(0.05, 1e+25))` – Matt L. Aug 24 '18 at 16:29
  • To work around this, pass the data like I've edited in my answer or the answer by @Tung below. – Matt L. Aug 24 '18 at 16:30

1 Answers1

2

This is a workaround using annotate until you find out what went wrong for geom_rect

library(dplyr)
library(ggplot2)

mtcars_f <- mtcars %>% 
  mutate(cyl.f = factor(cyl)) 

mtcars_f %>% 
  ggplot(aes(cyl.f, mpg)) +
  scale_y_log10() +
  scale_x_discrete() +
  annotate(geom = "rect", 
           xmin = -Inf, ymin = 17.5, xmax = Inf, ymax = 22.5,
           fill = "light blue", alpha = 0.8) +
  geom_point() +
  theme_classic(base_size = 12)

Created on 2018-08-24 by the reprex package (v0.2.0.9000).

Tung
  • 26,371
  • 7
  • 91
  • 115
  • 1
    Thanks! this indeed looks like the preferred way to do it. – Matt L. Aug 24 '18 at 15:40
  • 2
    Alternatively, I get the same result when using similar notation and passing the data in a dataframe to an aes. The issue is that data passed to `geom_rect` outside of `aes()` are not transformed. I found that comment by Hadley in a ggplot issue- that is actually the preferred behavior and won't be changed. – Matt L. Aug 24 '18 at 15:44