How to adjust scale_alpha for geom_point()?

Viewed 258

I have produced this Volcano plot:

enter image description here

I would like the colored geom_point() to have an increasing alpha, e.g. values at -log(P-value) ~2.3 corresponding to alpha = 0.75 while the maximum values on the -log(P-value)-scale correspond to alpha = 1. This should make it a bit easier to read the text in condensed areas.

Expected output drawn manually with an example of two geom_point() illustrating the graphical output I am trying to accomplish.

enter image description here

Script

ggplot(BT_Ctrl, aes(x = diff, y = logp)) + 
  geom_point(data = filter(BT_Ctrl, 
                           (logp > 0 & logp < (-log(0.1))) | (logp > (-log(0.1)) & diff > (-1) & diff < 0) 
  ), aes(alpha = logp),
  size = 3, color = "grey50", fill = "grey60", shape=21, stroke = 1) +
  
  scale_alpha_continuous(range = c(0.05, .25)) + 

  
  geom_point(data = filter(BT_Ctrl,
                           (logp > (-log(0.1)) & diff < (-1)) | (logp > (-log(0.1)) & diff > 0)) %>%
               mutate(group = ifelse(diff > 0, "Tumor", "Ctrl")),
             aes(color = group, fill = group, size = logp, alpha = logp), alpha = .25, shape = 21, stroke = 1.5) +
  
  
  scale_size(range = c(3.5,8.5)) +
  
  scale_fill_manual(values = alpha(c("#D1B551", "#678F53"), 0.2),
                    name = "",
                    labels = c("Low abundant", 
                               "High abundant")) +
  scale_colour_manual(values = c("#D1B551", "#678F53"),
                      name = "",
                      labels = c("Low abundant", 
                                 "High abundant")) +
  
  scale_x_continuous(breaks = seq(-3, 4, 1),
                     name = "**Difference on log<sub>2</sub>-scale**") +
  scale_y_continuous(breaks = seq(0, 8, 1),
                     name = "**-log**(*P*-value)") +
  coord_cartesian(ylim = c(0, 8),
                  xlim = c(-3.5, 4)) +
  
  guides(colour = guide_legend(override.aes = list(size = 10)),
         size = "none",
         alpha = "none") +
  
  theme(axis.line = element_line(colour = "black", 
                                 size = .6),
        panel.grid.major = element_line(colour = "gray95"),
        panel.grid.minor = element_line(colour = "gray95"),
        panel.border = element_blank(),
        panel.background = element_blank(),
        axis.text.x = element_text(color = "grey20", size = 16), 
        axis.title.x = ggtext::element_markdown(color = "grey20", size = 22, 
                                                margin = ggplot2::margin(t = 10)),
        axis.text.y = element_text(color = "grey20", size = 16), 
        axis.title.y = ggtext::element_markdown(color = "grey20", size = 25, 
                                                margin = ggplot2::margin(r = 8)),
        legend.key = element_rect(fill = "white"),
        plot.title = ggtext::element_markdown(color = "grey20", 
                                              size = 20, hjust = 0),
        plot.subtitle = element_text(hjust = 0.5),
        legend.text = ggtext::element_markdown(size = 30), 
        legend.title = element_text(size = 20, hjust = 0.5),
        legend.position = "bottom")

Attempts

I tried adding to aes(alpha=logp), like:

  geom_point(data = filter(BT_Ctrl,
                           (logp > (-log(0.1)) & diff < (-1)) | (logp > (-log(0.1)) & diff > 0)) %>%
               mutate(group = ifelse(diff > 0, "Tumor", "Ctrl")),
             aes(color = group, fill = group, size = logp, alpha = logp), shape = 21, stroke = 1.5) +

Which sort of did it:

enter image description here

But, I cannot figure out to manually adjust/edit so that the high -log(P-values) become more visible/less transparent.

I tried different versions of scale_alpha_continuous(range = c(0.75, 1)) +, which messes up the fill.

enter image description here

Data

BT_Ctrl <- structure(list(diff = c(1.56649042, -1.87675892, -1.80424434, 
1.72693416, 1.5787399, -1.86329892, -1.6789665, -1.6568188, -1.86840369, 
1.39048414, 1.84550897, 1.38801267, -1.80942931, 1.78143388, 
1.69846066, 1.56978846, 1.77520343, -1.55898508, 1.79985492, 
2.17939968, -1.57936357, -1.89272256, 1.72693416, -1.98373825, 
2.01700136, 1.40530492, -1.84020557, -1.84425835, -2.60720077, 
-2.08867432, -1.84536301, 1.5702918, -1.77541872, -1.44684146, 
-2.06145142, -1.84536301, 1.67972282, -1.77577326, -1.63510231, 
1.34901378, 1.89824526, -2.02095109, 2.36706042, -1.73584855, 
1.36028805, 1.59969963, 1.75797169, 1.77520343, 2.45895289, -1.77541872, 
-1.62727675, 1.43298941, -1.55898508, 1.77236427, -1.58338037, 
-1.6589846, -1.64190355, -2.2859511, -2.2871833, -1.95949086, 
1.77520343, -2.27851687, 1.5787399, -1.62727675, 3.1597624, -1.59762678, 
1.93588366, -1.80424434, -2.2871833, 2.44329109, -2.60720077, 
-1.73584855, -1.77876207, 1.72096759, 1.96423548, 1.7674994, 
2.33708957, 1.84550897, -2.02085819, 1.67972282, 1.89824526, 
2.17943425, 1.96427512, 2.47608359, -2.08867432, 2.44329109, 
1.77520343, -2.2859511, -2.06145142, -1.55898508, -1.59762678, 
-1.8741578, 2.18772316, -1.69511194, 2.35213644, 1.59062826, 
-1.82735184, -1.59762678, -1.55143048, 1.78143388), logp = c(3.16307, 
2.183779, 2.481417, 2.213655, 2.225182, 2.175182, 2.33327, 2.076203, 
3.048191, 2.639413, 2.415948, 2.424919, 2.275779, 2.454661, 2.507648, 
2.716042, 2.628121, 2.056823, 2.690471, 3.260036, 2.911379, 2.155653, 
2.213655, 2.175591, 3.429587, 2.244559, 2.165071, 2.327765, 3.174527, 
2.48279, 2.461853, 2.366302, 2.20657, 2.231255, 3.239911, 2.461853, 
2.199472, 2.370887, 2.28479, 2.290686, 3.111832, 2.966969, 3.623449, 
2.325613, 2.1868, 2.049223, 2.065346, 2.628121, 3.364917, 2.20657, 
2.113838, 2.412649, 2.056823, 2.263531, 2.102176, 2.539142, 3.330895, 
3.094797, 3.31816, 2.776573, 2.628121, 3.002339, 2.225182, 2.113838, 
7.517751, 3.690766, 3.759602, 2.481417, 3.31816, 4.018759, 3.174527, 
2.325613, 2.245998, 2.477856, 2.353492, 3.37967, 3.957788, 2.415948, 
2.39418, 2.199472, 3.111832, 3.659539, 2.911672, 4.604996, 2.48279, 
4.018759, 2.628121, 3.094797, 3.239911, 2.056823, 3.690766, 2.369712, 
3.320643, 2.075087, 4.50423, 2.330635, 2.416558, 3.690766, 2.115206, 
2.454661)), row.names = c(NA, -100L), class = c("tbl_df", "tbl", 
"data.frame"))  
2 Answers

Building on the answer from @tjebo, does this give you what you're looking for?

I added a noramlized "intensity" variable to the data, and used that. Playing around with the rescale() values allows you to change the intensity of the alpha, and get the "~2.3 = 0.75 intensity" relationship.

library(tidyverse)

data_grey <- BT_Ctrl %>%
  filter(logp > 0 & logp < (-log(0.1)) | (logp > (-log(0.1)) & diff > (-1) & diff < 0)) %>% 
  mutate(intensity = 0.05)

data_color <-  BT_Ctrl %>%
  filter(logp > (-log(0.1)) & diff < (-1) | (logp > (-log(0.1)) & diff > 0)) %>%
  mutate(group = ifelse(diff > 0, "Tumor", "Ctrl")) %>% 
  mutate(intensity = scales::rescale(x = exp(logp), to = c(0.05, 30)))

ggplot(mapping = aes(x = diff, y = logp)) +
  geom_point(data = data_color, shape = 21, aes(fill = group, size = logp, alpha = intensity)) + 
  geom_point(data = data_grey, alpha = 0.1, shape = 21, fill = "grey50") +
  scale_alpha_identity(guide = "none") +
  scale_y_continuous(limits = c(0, 8))

enter image description here

Not sure if this is what you're actually after, but I think you just need ggnewscale.


edit

Sadly, ggnewscale::new_scale("alpha") does not seem to work in this case - setting new range/limits fails for a new alpha aesthetic. I think if the problem is "too dense" fill of the lower values, you can just change the scale of your logp values, e.g. with exp(logp). Bigger values will be further away from smaller, thus resulting in starker differences to lower alphas.

library(tidyverse)

data_grey <- # I prefer creating data frames outside of ggplot calls if more complex
  BT_Ctrl %>%
  filter(logp > 0 & logp < (-log(0.1)) | (logp > (-log(0.1)) & diff > (-1) & diff < 0))

data_color <-
  BT_Ctrl %>%
  filter(logp > (-log(0.1)) & diff < (-1) | (logp > (-log(0.1)) & diff > 0)) %>%
  mutate(group = ifelse(diff > 0, "Tumor", "Ctrl"))

ggplot(mapping = aes(x = diff, y = logp, alpha = exp(logp))) +
  geom_point(data = data_color, shape = 21, aes(fill = group, size = logp)) + 
  geom_point(data = data_grey, shape = 21, fill = "grey50") +
  scale_alpha(range = c(0.05, 1), guide = "none")  

# sadly does not work
# ggnewscale::new_scale("alpha") + scale_alpha(...)

Created on 2021-07-21 by the reprex package (v2.0.0)

Related