overlaying points in specific manner in ggplot scatter plots

Viewed 80

The colors are added to the ggplot scatter plot based on interaction of two variables : choice and flag (each has two values, therefore, total four combinations). I used faceting based on z value.

library(tidyverse)

x <- runif(10000)
y <- runif(10000)
z <- c(rep(0, 5000), rep(1, 5000))
flag <- c(rep(0, 500), rep(1, 4500), rep(0, 4500), rep(1, 500))
choice <- rep(c(0, 1), 5000)

tbl <- tibble(x, y, z, flag, choice)

scatterplot <- ggplot(tbl,
                      aes(x = x,
                          y = y,
                          color = factor(interaction(choice, flag)))
                      ) + 
  geom_point(alpha = 0.7,
             size = 2) +
  scale_color_manual(values = c("blue3", "cyan1", "red3", "orange")) +
  facet_grid(z ~ .) + 
  theme_bw() + 
  theme(legend.position = "right") + 
  theme(aspect.ratio = 1) +
  ggtitle("Scatter plot")

scatterplot

But I have the following requirement -

  1. z is used for facetting. For z = i, I want points with flag = i to be above, i.e. in the figure below,

for z = 0, blue points (flag = 0) should be over red/orange points.

for z = 1, red/orange points (flag = 1) should be over blue points (as shown)

enter image description here

2 Answers

If I understand you correctly, you are happy with the lower panel, but you need the blue dots in the top panel to be overlaid on the orange dots (at the moment the orange dots are overlaid on the blue dots in both panels).

If this is the case, then calling geom_point a second time with a subsetted data frame where z == 0 & flag == 0 will overlay the appropriate blue points on the top panel without affecting the lower panel.

tbl <- tbl %>% 
  mutate(col = interaction(choice, flag))

ggplot(tbl, aes(x, y, color = col)) + 
  geom_point(alpha = 0.7, size = 2) +
  geom_point(data = subset(tbl, z == 0 & flag == 0), 
             alpha = 0.7, size = 2) +
  scale_color_manual(values = c("blue3", "cyan1", "red3", "orange")) +
  facet_grid(z ~ .) + 
  theme_bw() + 
  theme(legend.position = "right") + 
  theme(aspect.ratio = 1) +
  ggtitle("Scatter plot")

enter image description here

Consider this as an option for you. With facets it was complex to set specific order but you can do the same plot using patchwork:

library(tidyverse)
library(patchwork)
#Data
x <- runif(10000)
y <- runif(10000)
z <- c(rep(0, 5000), rep(1, 5000))
flag <- c(rep(0, 500), rep(1, 4500), rep(0, 4500), rep(1, 500))
choice <- rep(c(0, 1), 5000)

tbl <- tibble(x, y, z, flag, choice)

Plots:

#Plot
G1 <- ggplot(subset(tbl,z==0),aes(x = x,y = y,
               color = factor(interaction(choice, flag),
                              levels = rev(unique(interaction(choice, flag))),
                              ordered = T))) + 
  geom_point(alpha = 0.7,
             size = 2) +
  scale_color_manual(values = c("blue3", "cyan1", "red3", "orange")) +
  facet_grid(z ~ .) + 
  theme_bw() + 
  theme(legend.position = "right") + 
  theme(aspect.ratio = 1) +
  ggtitle("Scatter plot")+
  labs(color='Color',x='')+theme(legend.position = 'none')
#Plot 2
G2 <- ggplot(subset(tbl,z==1),aes(x = x,y = y,
                            color = factor(interaction(choice, flag)))) + 
  geom_point(alpha = 0.7,
             size = 2) +
  scale_color_manual(values = c("blue3", "cyan1", "red3", "orange")) +
  facet_grid(z ~ .) + 
  theme_bw() + 
  theme(legend.position = "right") + 
  theme(aspect.ratio = 1) +
  labs(color='Color')

Final arrange:

#Final plot
G <- G1/G2
G <- G+plot_layout(guides = 'collect')

Output:

enter image description here

Related