This is a test version of Biostars. For the public version, visit https://www.biostars.org.
Question about making plot using ggplot2 and R

Hello everybody,

I got one question during making my plots using ggplot2.

siONE <- seqdata$ONE
siTWO <- seqdata$TWO
ggplot(data = seqdata, aes(x = siONE, y = siTWO, color = point, alpha = point, size = point)) + 
geom_point(position = "jitter") + 
lims(x = c(-1.5, 1.5), y = c(-1.5, 1.5)) + 
#scale_x_continuous(breaks = c(-3.0, -2.0, -1.0, 0, 1.0, 2.0, 3.0)) + 
scale_fill_gradient2(low =  "white", high = "red", mid = "blue", midpoint = 1.5) + 
annotate(geom = "segment", x = c(-Inf, 0), xend = c(Inf, 0), y = c(0, -Inf), yend = c(0, Inf), size = 0.6) +
coord_fixed(ratio = 1) +
theme(panel.background = element_rect(fill =  "#f5f5f5")) +
scale_color_manual(values=c("dark gray", "#e41a1c", "#377eb8", "#4daf4a", "#984ea3")) +
scale_alpha_manual(values = c(0.08, 5, 5, 5, 5)) +
scale_size_manual(values = c(0.7, 1, 2, 2, 2)) +
theme(panel.grid.major.x = element_blank(), 
      panel.grid.minor.x = element_blank(),
      panel.grid.major.y = element_blank(),
      panel.grid.minor.y = element_blank())

I used the script for this graph. enter image description here

In this graph, there are 387 missing values. But I want these 387 dots not to be omitted but to be placed on the rim of the graph like this one. (This is coming from Boehm et al. 2021 Nat Commun. There are dots placed in the upper limitation line instead omitted.) enter image description here

I hope I could find how I can make it. Thank you very much!

graph ggplot r

Add another column contains factors of the categories (NA, True and False), then add a group to ggplot.

1 answer

Here is some example code. The trick is to mutate the data, and if points are out of bounds based on the limits you define, then set them to exactly the limit so they're displayed at the edge of the plot.


library(tidyverse)

#/ dummy data:
set.seed(1)
dat <- data.frame(A=rnorm(30, 1, 1),
                  B=rnorm(30, 2, 2))

#/ set some limits to be applied to both axis:
uselims <- c(-0.5, 1)

#/ full plot:
full <- 
  dat %>%
    ggplot(aes(x=A, y=B)) +
    geom_point() + ggtitle("full")

#/ applying limits:
out_of_bounds <- 
  dat %>%
    ggplot(aes(x=A, y=B)) +
    geom_point() +
    lims(x=uselims, y=uselims) + ggtitle("missing values")

#/ trimming values to be at the edge of limits:
trimmed <- 
  dat %>%
    mutate(A=case_when(A < min(uselims) ~ min(uselims),
                       A > max(uselims) ~ max(uselims),
                       TRUE ~ A),
           B=case_when(B < min(uselims) ~ min(uselims),
                       B > max(uselims) ~ max(uselims),
                       TRUE ~ B)) %>%
    ggplot(aes(x=A, y=B)) +
    geom_point() +
    lims(x=uselims, y=uselims) +
    ggtitle("trimmed")

library(patchwork)
(full | out_of_bounds) / (trimmed | plot_spacer())

enter image description here

Thank you very much....! I fully understand.

May I ask you one more question?

I made up for my script like this

dat <- data.frame(siONE, siTWO, point)
dat %>% 

mutate(siONE = case_when(siONE < min(my_lim) ~ min(my_lim),
                        siONE > max(my_lim) ~ max(my_lim),
                        TRUE ~ siONE),
     siTWO = case_when(siTWO < min(my_lim) ~ min(my_lim),
                          siTWO > max(my_lim) ~ max(my_lim),
                          TRUE ~ siTWO)) %>% 

ggplot(aes(x=siONE, y=siTWO, color = point, alpha = point, size = point)) +
geom_point(position = "jitter") + 
lims(x = my_lim, y = my_lim) + 
scale_fill_gradient2(low =  "white", high = "red", mid = "blue", midpoint = 1.5) + 
annotate(geom = "segment", x = c(-Inf, 0), xend = c(Inf, 0), y = c(0, -Inf), yend = c(0, Inf), size = 0.6, lty = 2, alpha = 0.6) +
coord_fixed(ratio = 1) +
theme(panel.background = element_rect(fill =  "white")) +
scale_color_manual(values=c("black", "#e41a1c")) +
scale_alpha_manual(values = c(0.4, 0.8)) +
scale_size_manual(values = c(4, 5)) +
theme(panel.grid.major.x = element_blank(), 
    panel.grid.minor.x = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank())

When I ran this script, I got the graph exactly I wanted!

But there are still some missing values(about 20~30) and that number and representing points change whenever I run the script.

So can I get a little more advice? Thank you!

That is due to the jitter, why do you even jitter for a x/y plot?

Before trimming data, the points are indiscriminate because there are much more data in my graph. So I tried to use "jitter" and it remains.

I solve the problem after removing that. Thank you very much! Your advice is very helpful to me.

Log in to answer this question.