2

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"))  
cmirian
  • 2,572
  • 3
  • 19
  • 59

2 Answers2

3

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

tjebo
  • 21,977
  • 7
  • 58
  • 94
Tech Commodities
  • 1,884
  • 6
  • 13
2

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)

tjebo
  • 21,977
  • 7
  • 58
  • 94
  • @cmirian I've also decided to completely strip down your code to the essential, so the look will not be what you want as a final result - this is more about the principle. Please also take this as an improvement suggestion for future questions - it's much easier to understand questions when the problem is reduced to its core... – tjebo Jul 21 '21 at 10:35
  • Hi @tjebo, thank you for your inputs. I will definitely work on improving my questions, I can see your improvement. Regarding the question, it does not seem that adding `ggnewscale::new_scale("alpha") + scale_alpha_continuous(range = c(0.75, 1)) +` after `geom_point(data = data_color)` did anything. The plot is the same regardless of these two lines of code. Both in your example and when trying the code on my data, the "top" `geom_point()` still appear transparrent to some degree (as seen on the plot you uploaded) – cmirian Jul 21 '21 at 10:52
  • @cmirian sadly, you seem right and ggnewscale does not seem to take new ranges/limits. Edited my answer for a different suggestion. – tjebo Jul 21 '21 at 11:39