Manually colouring plots with `scale_fill_manual` in ggplot2 not working
Just in case you are not sure what @baptise means:
ggplot(ServicesProp, aes(x = Service, y = percent, fill = Service)) +
geom_bar(stat = "identity", position = "dodge") +
scale_fill_manual(values = c("red", "grey", "seagreen3"))
Scale_fill_manual not producing color fill specified by a condition
Try changing fill
by color
. Bars can be filled, whereas dots as those in jitter can be colored:
library(ggplot2)
#Data
fileUrl <- "https://raw.githubusercontent.com/MichaelSodeke/DataSets/main/tornado_dmg.csv"
df2 <- read.csv(fileUrl)
#Code
ggplot(df2, aes(x=bgn.date, y=path.area, color=(f == 5) ))+
geom_jitter(stat="identity", size=1)+
scale_color_manual(values=c("TRUE"="red", "FALSE"="grey80"))
Output:
How to use scale_fill_manual to manually define bar plot colors
I would create a dummy
variable in your input df2
for the ggplot
fill
aesthetic. Here, "-999" refers to "OJ" and will be coloured in black.
I've also updated your myPalette
to include black in it, and also setNames
to it so that only "-999" will have a corresponding "black" value.
library(tidyverse)
df2 <- data.frame(supp=rep(c("VC", "OJ"), each=3),
dose=rep(c("D0.5", "D1", "D2"),2),
len=c(6.8, 15, 33, 4.2, 10, 29.5))
myPalette <- c("#05eb92", "#119da4", "#ffc857")
myPalette_with_black <- setNames(c(myPalette, "black"),
c(as.character(seq_along(myPalette)), "-999"))
df2 <- df2 %>%
group_by(supp) %>%
mutate(dummy = ifelse(supp == "VC", as.character(row_number()), "-999"))
ggplot(data=df2, aes(x=dose, y=len, fill = dummy)) +
geom_bar(stat="identity", position=position_dodge()) +
scale_fill_manual(values = myPalette_with_black) +
theme(legend.position = "none")
Created on 2022-03-12 by the reprex package (v2.0.1)
scale_fill_manual is only applying to the legend and not bars
The issue is that your column p_value_dif
does not contain any values "Significant"
or "Insignificant"
. Only these values will be filled "black" or "orange". All other values will be filled with the default na.value
of the scale. Instead you could map your column p-value.category
on fill and set your fill colors and labels like so:
library(ggplot2)
ggplot(df, aes(x=gene,
y=p_value_dif ,
label=p_value_dif )) +
geom_bar(stat='identity',
aes(fill= `p-value.category`),
width=0.9) +
scale_fill_manual("legend",
values = c("sig" = "black", "non-sig" = "orange"),
labels = c("sig" = "Significant", "non-sig" = "Insignificant"))+
coord_flip()
DATA
df <- data.frame(
stringsAsFactors = FALSE,
check.names = FALSE,
gene = c("a", "c", "d", "e"),
p_value = c(0.06, 0.07, 0.008, 0.009),
p_value_dif = c("0.01", "0.02", "- 0.03", "- 0.04"),
`p-value.category` = c("non-sig", "non-sig", "sig", "sig")
)
ggplot2 displays wrong colors with manual scale
The reason you are getting different colours I think is because ggplot
isn't automatically making a connection between the colours you have supplied and the groups you have supplied. I'm not 100% sure why this is the case, but I can offer a solution.
You can create a new column in the data before you send it to ggplot
for plotting. We will call it colour_group
but you can call it anything. We populate this new column based on the values of avg
(I have made sample data as you haven't supplied all of yours). We use ifelse()
which tests a condition against the data, and returns a value based on if the test
is TRUE
or FALSE
.
In the below code, colour_group = ifelse(avg < -0.01, 'red', NA)
may be read aloud as: "If my value of avg is less than -0.01, make the value for the colour_group
column 'red', otherwise make it NA
". For subsequent lines, we want the FALSE
result to keep the results already in the colour_group
column - the ones made on the previous lines.
# make sample data
tibble(
chunk = 1:100,
avg = rnorm(100, 1, 1)
) %>%
{. ->> my_data}
# make the new 'colour_group' column
my_data %>%
mutate(
colour_group = ifelse(avg < -0.01, 'red', NA),
colour_group = ifelse(avg > 0.01, 'green', colour_group),
colour_group = ifelse(avg > -0.01 & avg < 0.01 , 'yellow', colour_group),
) %>%
{. ->> my_data_modified}
Now we can plot the data, and specify that we want to use the colour_group
column as the fill
aesthetic. When specifying scale_fill_manual
, we then tell ggplot
that if we have the value of green
in the colour_group
column, we want the bar to be a green colour, and so on for the other colours.
my_data_modified %>%
ggplot(aes(chunk, avg, fill = colour_group))+
geom_bar(stat = 'identity', show.legend = FALSE)+
scale_fill_manual(
values = c('green' = 'green', 'red' = 'red', 'yellow' = 'yellow')
)
It is slightly confusing, in a way having to specify the colour twice. However, we could specify the values of colour_group
as anything, such as 1, 2, 3 or low, med, high. In this instance, you would do the same code but modify the ifelse
statements, and change scale_fill_manual
to match these values. For example:
my_data %>%
mutate(
colour_group = ifelse(avg < -0.01, 'low', NA),
colour_group = ifelse(avg > 0.01, 'high', colour_group),
colour_group = ifelse(avg > -0.01 & avg < 0.01 , 'med', colour_group),
) %>%
{. ->> my_data_modified}
my_data_modified %>%
ggplot(aes(chunk, avg, fill = colour_group))+
geom_bar(stat = 'identity', show.legend = FALSE)+
scale_fill_manual(
values = c('high' = 'green', 'low' = 'red', 'med' = 'yellow')
)
R assigning colors manually in ggplot
You can pass a named vector to scale_fill_manual
:
library(ggplot2)
ggplot(test1, aes(y = rn, x = variable, fill = value)) +
geom_tile() +
theme(strip.background = element_blank(),
strip.text.x = element_blank(),
text = element_text(size=3)) +
geom_text(aes(label=value), size=3) +
labs(x="Seg", y= "Id ", fill = "Div",
title= "Myplot")+
scale_fill_manual(values=setNames(color, test1$value))
Related Topics
How to Download a Large Binary File with Rcurl *After* Server Authentication
How to Plot X-Axis Labels and Bars Between Tick Marks in Ggplot2 Bar Plot
Remove Zombie Processes Using Parallel Package
How to Calculate the Median on Grouped Dataset
R: Is There a Good Replacement for Plyr::Rbind.Fill in Dplyr
How to Control Label Color Depending on Fill Darkness of Bars
Cumulative Sum in a Window (Or Running Window Sum) Based on a Condition in R
Adding Annotation (Segment/Arrow) in Only Certain Facet Ggplot
Why Do Rapply and Lapply Handle Null Differently
Grouped Correlation with Dplyr (Works Only on Console)
Forest Plot with Table Ggplot Coding
Flatten Nested Lists in a List
Get Continent Name from Country Name in R
Nls Troubles: Missing Value or an Infinity Produced When Evaluating the Model
Caret: There Were Missing Values in Resampled Performance Measures
Fastest Way to Do This Double Summation