19

I want to highlight selected points and encountered some strange behaviour. First some dummy data:

a <- 1:50
b <- rnorm(50)
mydata <- data.frame(a=a,b=b)
ggplot(mydata,aes(x=a,y=b)) + geom_point()

This works correctly. Now,to highlight some points, I add another geom_point layer:

ggplot(mydata[20:40,],aes(x=a,y=b)) + 
    geom_point() + 
    geom_point(aes(x=a[c(10,12,13)],y=b[c(10,12,13)]),colour="red")

Note that I am displaying only a limited range of the data ([20:40]). Now comes the strange behavior:

ggplot(mydata[10:40,],aes(x=a,y=b)) + 
    geom_point() + 
    geom_point(aes(x=a[c(10,12,13)],y=b[c(10,12,13)]),colour="red")

Changing the size of the selected range, I get an error, roughly translated from German: Error...: Arguments implying different number of rows. Strangely, this varies with the selected range. [23:40] will work, [22:40] won't.


The error in English is:

Error in data.frame(x = c(19L, 21L, 22L), y = c(0.28198, -0.6215,  : 
  arguments imply differing number of rows: 3, 31
csgillespie
  • 59,189
  • 14
  • 150
  • 185
lambu0815
  • 311
  • 1
  • 2
  • 9

3 Answers3

43

If your data is different between different layers, then you need to specify the new data for each layer.

You do this with the data=... argument for each geom that needs different data:

set.seed(1)
mydata <- data.frame(a=1:50, b=rnorm(50))
ggplot(mydata,aes(x=a,y=b)) + 
  geom_point(colour="blue") +
  geom_point(data=mydata[10:13, ], aes(x=a, y=b), colour="red", size=5)

enter image description here

Andrie
  • 176,377
  • 47
  • 447
  • 496
  • 1
    Well, the data is not actually different, just a different subset. But this solution is at least stable. Works only with explicit naming (`data=...`). But no explanation for that strange error... – lambu0815 Jul 13 '12 at 12:52
  • 2
    @lambu0815 The fact that it's a different subset makes it different. You had that strange error because you tried to map a single aesthetic (x) to three different elements. Aesthetics must be mapped to column names. You also don't have to explicitly name the `data=...` argument, but then you need to have the arguments in the correct order, i.e. `geom_point(aes(...), data, ...)` – Andrie Jul 13 '12 at 14:24
8

Another option adding the conditions for both attributes, colour and size, inside geom_point. Then we control manually those using scale_colour_manual and scale_size_manual respectively.

set.seed(1)
mydata <- data.frame(a = 1:50, b = rnorm(50))
ggplot(mydata) + 
  geom_point(aes(x = a, y = b, colour = a > 9 & a < 14, size = a > 9 & a < 14)) + 
  scale_colour_manual(values = c("blue", "red")) + 
  scale_size_manual(values =c(1, 4))+
  theme(legend.position = "none")

enter image description here

mpalanco
  • 12,960
  • 2
  • 59
  • 67
5

Another solution with gghighlight:

a <- 1:50
b <- rnorm(50)
mydata <- data.frame(a=a,b=b, type = sample(letters, 50, replace = T))

library(gghighlight)
gghighlight_point(mydata, aes(x=a, y=b), label_key = type, 
                  a <= 14 & a >= 10 & b >= 0 , col="red")
Tung
  • 26,371
  • 7
  • 91
  • 115
maxatSOflow
  • 269
  • 3
  • 10