I would like to create a barplot with ggplot2 puttingg a scale fill gradient where I can set the values of min, mid and max (in my case it would be: min = 0, mid = 50, max = 100). For each of these values I'd like to associate a scale gradient where 0 correspond to blue, mid to yellow (or white) and 100 to red.
I found nothing here, could you help me please?
Thank you in advance.
Here there is the code I tried to use but didn't work (the barplot I obtain has has gray bars).
TPH <- ggplot(ser, aes(x= Stages, y= TPH))+
geom_bar(stat = "identity")+
scale_fill_gradient(low='blue', high='red')+
labs(y= expression("Counts per million (CPM)"), x = "Hours post fertilization (hpf)")+
ggtitle("Tryptophan Hydroxylase", subtitle = "TPH")+
theme(plot.title=element_text(hjust=0.5),
plot.subtitle=element_text(hjust=0.5))+
scale_y_continuous(limits=c(0, 100))+
scale_x_discrete(labels=c("hpf00" = "0", "hpf04" = "4", "hpf08" ="8", "hpf12"="12", "hpf16"="16", "hpf20"="20","hpf24"="24", "hpf28"="28", "hpf32"="32", "hpf36"="36","hpf40"="40", "hpf44"="44", "hpf48"="48", "hpf52"="52", "hpf72"="72"))
TPH
Assuming that your data looks like this (please include some example data in your next questions)
# libraries
library(tidyr)
library(dplyr)
library(ggplot2)
# set seed for reproducibility
set.seed(123)
# get example data
ser <- data.frame(Stages = c("hpf00", "hpf04", "hpf08", "hpf12", "hpf16",
"hpf20", "hpf24", "hpf28", "hpf32", "hpf36",
"hpf40", "hpf44", "hpf48", "hpf52", "hpf72")) %>%
mutate(TPH = sample(1:100, length(Stages)))
you can generate a vector from 0 to your observation per level of Stages
(following the answer provided here https://stackoverflow.com/a/71043558/15024678). You then unnest these vectors:
ser_mod <- ser %>%
mutate(TPH = purrr::map(TPH, ~0:.x)) %>%
unnest_longer(TPH)
This can be plotted using geom_tile()
resulting in a bar chart that fits your description.
ggplot(ser_mod, aes(x = Stages, y = TPH)) +
geom_tile(aes(fill = TPH, width = .9)) +
scale_fill_distiller(palette = "RdYlBu") +
theme(legend.position = "none")
Get modified example data so that TPH = 100 for hpf12:
# set seed for reproducibility
set.seed(123)
# get example data
ser <- data.frame(Stages = c("hpf00", "hpf04", "hpf08", "hpf12", "hpf16",
"hpf20", "hpf24", "hpf28", "hpf32", "hpf36",
"hpf40", "hpf44", "hpf48", "hpf52", "hpf72")) %>%
mutate(TPH = sample(1:100, length(Stages))) %>%
mutate(TPH = ifelse(Stages == "hpf12", 100, TPH))
After generating the column containing values from 0 to the value of your observation per level of TPH
you can generate a new column (TPH_fill
) you use for coloring. This column can then be modified so that it only contains 100 (resulting in red color) if the maximum value of TPH
is 100:
ser_mod <- ser %>%
mutate(TPH = purrr::map(TPH, ~0:.x)) %>%
unnest_longer(TPH) %>%
group_by(Stages) %>%
mutate(TPH_fill = ifelse(max(TPH) == 100, 100, TPH)) %>%
mutate(TPH_fill = ifelse(TPH_fill != 100, TPH, TPH_fill))
Plot using TPH_fill
as argument for fill
:
ggplot(ser_mod, aes(x = Stages, y = TPH)) +
geom_tile(aes(fill = TPH_fill, width = .9)) +
scale_fill_distiller(palette = "RdYlBu") +
theme(legend.position = "none")
You can plot a geom_col()
based on the unmodified data and set fill
by the value of TPH
:
ggplot(ser, aes(x = Stages, y = TPH)) +
geom_col(aes(fill = TPH)) +
scale_fill_distiller(palette = "RdYlBu") +
theme(legend.position = "none")