'ggplot2 with colour blind ggthemes except black

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.



Solution 1:[1]

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])

Solution 2:[2]

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.

Load packages

library(ggplot2)
# Included because this is what I used to make the images:
theme_set(theme_minimal()) 
library(ggthemes)

Define color/fill functions

# 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).

Usage

Use the functions like any other scale function:

ggplot(diamonds, aes(clarity, fill = cut)) + 
  geom_bar(position = "dodge") +
  scale_fill_colorblind7()

Histogram of diamond clarity by cut

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)

Histogram of diamond clarity by 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))

Histogram of diamond clarity by cut

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alec
Solution 2 randy