Afiq Johari
Afiq Johari

Reputation: 1462

ggplot layering multiple geom_points on top of each other with specific order

ID <- rep(c('A','B'),each = 10)
x <- rep(1,10)
y <- 1:10
have <- tibble(x, y)
have <- cbind(ID,rbind(have,have))

have %>%
  ggplot(aes(x, y, color = ID)) + 
  geom_point() + theme_bw()

enter image description here

Notice that just because ID B came later based on the dataframe ordering, it will be plotted on top of ID A.

To confirm this behavior, I just need to switch the ordering


ID <- rep(c('B','A'),each = 10)
x <- rep(1,10)
y <- 1:10
have <- tibble(x, y)
have <- cbind(ID,rbind(have,have))

have %>%
  ggplot(aes(x, y, color = ID)) + 
  geom_point() + theme_bw()

enter image description here

In some contexts, the solution can be jittering the points, but what I really want is to enforce orders on these points.

For example, if I decide B is more important than A, therefore in all cases if any of these points were to overlap against each other, B will always be on top of A.

Is there a way to enforce this rule? I was thinking of layering the geom_points one by one. For example, if I want B to be on top of A, I will have to create a ggplot geom_point with only point A first, and the layer another geom_point with B.

But this proves to be not efficient should have say 10 different ID. Is there a better way?

# layer A first then B
Apoint %>%
  ggplot(aes(x, y, color = ID)) + 
  geom_point() + theme_bw() + 
  geom_point(data = Bpoint)

# layer B first then A
Bpoint %>%
  ggplot(aes(x, y, color = ID)) + 
  geom_point() + theme_bw() + 
  geom_point(data = Apoint)

In the below chart, I the orange dots are overwhelming the red dots when they overlap. I want to make sure that when they overlap, some colors (which is based on factor level) should take priority over others.

enter image description here

Upvotes: 2

Views: 1373

Answers (1)

Jon Spring
Jon Spring

Reputation: 66415

Here's one approach, to encode the importance as a variable, sort by that, then plot:

library(tidyverse)

ID <- rep(c('A','B'),each = 10)
x <- rep(1,10)
y <- 1:10
have <- tibble(ID, 
               x = rep(x, 2), 
               y = rep(y, 2),
               importance = c(1:10, 10:1))

have %>%
  arrange(importance) %>%
  ggplot(aes(x, y, color = ID)) + 
  geom_point() + theme_bw()

enter image description here

Upvotes: 2

Related Questions