Reputation: 231
I want to create a general line of code I can apply to any ggplot
grouped barchart I make. I want it to make my graphs colour blind friendly. In the library ggthemes
, the scale_fill_colorblind
function does just the job. My problem is that black is often picked as one of the colours; I sometimes need to overlay confidence intervals and other stuff, so black is not really an option.
library(ggplot2)
library(ggthemes)
ggplot(diamonds, aes(clarity, fill=cut)) + geom_bar(position="dodge")+
scale_fill_colorblind()
Is there any way to to have within the scale_fill_colourblind
some code that tells it not to pick black? I don't want to list the colours manually because I want it to be compatible with lots of different data (some may have two "fills", some 10 etc...).
Any help would be greatly appreciated.
Upvotes: 2
Views: 4128
Reputation: 1091
This answer builds on the answer from Alec but creates a function that returns scale_fill_discrete
with a type argument equal to a vector of the last 7 colors used by scale_fill_colorblind
. You do not have to specify the number of groups in your data; if there are N groups, scale_fill_discrete
will use the first N colors in its type
argument. The function I wrote will also let you select which colors you want, so you can drop black or use the 2nd, 4th, and 5th colors.
library(ggplot2)
# Included because this is what I used to make the images:
theme_set(theme_minimal())
library(ggthemes)
# Fill
scale_fill_colorblind7 = function(.ColorList = 2L:8L, ...){
scale_fill_discrete(..., type = colorblind_pal()(8)[.ColorList])
}
# Color
scale_color_colorblind7 = function(.ColorList = 2L:8L, ...){
scale_color_discrete(..., type = colorblind_pal()(8)[.ColorList])
}
The default value of .ColorList
is 2:8
because there are 8 colors in the colorblind palette, and the first is black (the one we want to drop).
Use the functions like any other scale
function:
ggplot(diamonds, aes(clarity, fill = cut)) +
geom_bar(position = "dodge") +
scale_fill_colorblind7()
You can also specify breaks as part of the ...
argument.They get passed through to ...
in scale_fill_discrete
.
ggplot(diamonds, aes(clarity, fill = cut)) +
geom_bar(position = "dodge") +
scale_fill_colorblind7(breaks = diamonds$cut)
Don't like those colors? Tell the function which colors to use (their positions):
ggplot(diamonds, aes(clarity, fill = cut)) +
geom_bar(position = "dodge") +
scale_fill_colorblind7(.ColorList = c(3,4,7,6,1))
Upvotes: 4
Reputation: 75
Another option is use scale_fill_manual
with ggthemes::colorblind_pal
.
library(ggplot2)
library(ggthemes)
ggplot(diamonds, aes(clarity, fill = cut)) +
geom_bar(position = "dodge") +
scale_fill_colorblind()
n <- length(unique(diamonds$cut))
# or
n <- data.table::uniqueN(diamonds$cut)
# Manually fill the geom with breaks provided by the data
# and getting one extra color from ggthemes::colorblind_pal
# then dropping black (the first color)
ggplot(diamonds, aes(clarity, fill = cut)) +
geom_bar(position = "dodge") +
scale_fill_manual(breaks = diamonds$cut,
values = colorblind_pal()(n + 1)[-1])
Upvotes: 2
Reputation: 77116
at best a hack,
ggthemes_data$colorblind <- ggthemes_data$colorblind[-1]
assignInNamespace("ggthemes_data", ggthemes_data, ns="ggthemes")
last_plot() + scale_fill_colorblind()
Upvotes: 4