4

All, I'm not sure what's gone wrong with this example:

library(ggplot2)
par(ask = TRUE) 
alphaVals <- seq(0.1, 1, 0.1)
for(alpha in alphaVals) print(qplot(x = 1:100, y = 1:100) + geom_rect(xmin = 20, xmax = 70, ymin = -Inf, ymax = Inf, alpha = alpha, fill = 'grey50'))

You can see that from alpha equals 0 to around 0.2 I get some transparency, but after that it's just gone. I've never had problems setting the alpha scale of a ggplot2 layer before.

What am I doing wrong here?

M--
  • 25,431
  • 8
  • 61
  • 93
aaron
  • 6,339
  • 12
  • 54
  • 80

2 Answers2

3

The problem here is that ggplot2 is drawing the rectangle 100 times in the same location. Thus, 100 stacked transparent shapes appear as a single opaque shape. I discovered this by inspecting the pdf output with Adobe Illustrator. I have provided a possible solution below (re-written to use ggplot syntax instead of qplot). I certainly feel that this behavior is unexpected, but I'm not sure if it deserves to be called a bug.

My proposed solution involves (1) putting the rectangle data in its own data.frame, and (2) specifying the data separately in each layer (but not in the ggplot() call).

library(ggplot2)

dat  = data.frame(x=1:100, y=1:100)
rect_dat = data.frame(xmin=20, xmax=70, ymin=0, ymax=100)

# Work-around solution.
p = ggplot() + 
    geom_point(data=dat, aes(x=x, y=y)) + 
    geom_rect(data=rect_dat, 
              aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax),
              alpha = 0.3, fill = "black")

ggsave("test.png", plot=p, height=5, width=5, dpi=150)

enter image description here

# Original version with 100 overlapping rectangles.
p2 = ggplot(dat, aes(x=x, y=y)) + 
     geom_point() + 
     geom_rect(xmin=20, xmax=70, ymin=0, ymax=100, alpha=0.01, fill="black")

ggsave("test.pdf", height=7, width=7)
bdemarest
  • 14,397
  • 3
  • 53
  • 56
  • Yep, that seems to be the way forward. After looking through a couple other online examples I'm realizing that they all do the same thing, creating a separate df for the shaded rectangle object. thanks! – aaron Mar 19 '14 at 02:40
3

An alternative is using annotate instead of geom_rect:

ggplot(dat, aes(x = x, y = y)) +
  geom_point()+
    annotate("rect", xmin = 20, xmax = 70, ymin = 0, 
             ymax = 100, fill = "black", alpha = 0.3) 

Output:

enter image description here

Data:

dat <- structure(list(x = 1:100, y = 1:100),
                 class = "data.frame",
                 row.names = c(NA, -100L))
mpalanco
  • 12,960
  • 2
  • 59
  • 67