kneijenhuijs
kneijenhuijs

Reputation: 1209

Flexible repeating of fill palette

I wish to create a frequency graph with a fill based on the levels of a variable. This variable has more levels than there are colours in the fill palette I wish to use: scale_fill_economist(). The fill is mostly used for ease of interpreting, so not all level colours need to be unique. As such, I wish to cycle through 3 colours.

I run into two problems: 1) My plot includes a level with NAs that I am unable to get coloured through the method I figured out (which I'm including below). 2) While the current data set I am using represents 19 levels (including the NA level), I wish to recreate the plot on a regular basis where more levels will be added. As such, I want the code to be flexible. My current code is hard-coded.

Reproducible example of what I managed to accomplish:

library(ggplot2)
library(ggthemes)
Tempfreq <- structure(list(Var1 = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 
                              8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, NA), .Label = c("A", 
                                                                                                   "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", 
                                                                                                   "O", "P", "Q", "R"), class = "factor"), Freq = c(4L, 1L, 3L, 
                                                                                                                                                    1L, 1L, 1L, 3L, 1L, 1L, 1L, 1L, 1L, 7L, 3L, 4L, 1L, 4L, 2L, 27L
                                                                                                   )), .Names = c("Var1", "Freq"), row.names = c(NA, -19L), class = "data.frame")
ggplot(data=Tempfreq, aes(x=Var1, y=Freq, fill=Var1)) + 
geom_bar(stat='identity') + guides(fill=FALSE) + xlab("Level") + ylab("Frequency") + ggtitle("Title") +
geom_text(aes(label=Freq), vjust = 0.5, hjust= -1, size=4, family="ITC Officina Sans") +
coord_flip() + theme_economist() + 
scale_fill_manual(values=c(rep(economist_pal(fill=TRUE)(3), times=length(Tempfreq$Var1)/3), economist_pal(fill=TRUE)(1)))

The main line of importance is the last, including the scale_fill_manual command. This command calls 3 values of the economist_pal() palette, and repeats this for the length of Var1 divided by three. As 19 / 3 = 6.33, and this is rounded down, this only fills 18 levels. That is why I am adding one more value of the palette. However, as the image shows, this does not fill the NA level:

I'm hoping someone can help me out with filling the NA data, as well as making this code flexible.

Upvotes: 2

Views: 457

Answers (1)

Heroka
Heroka

Reputation: 13149

Does this work for you?

First, we change the levels of the factor Var1 to include "Missing" and make 'NA', "Missing":

levels(Tempfreq$Var1) <- c(levels(Tempfreq$Var1),"Missing")
Tempfreq$Var1[is.na(Tempfreq$Var1)] <- "Missing" 

Then we use the 'length.out' argument in 'rep' to create our colors:

mycols <- rep(economist_pal(fill=TRUE)(3),length.out=nrow(Tempfreq))

And use these colors as argument in scale_fill_manual. (Can be done without assigning of course, but I thought this was more readable).

ggplot(data=Tempfreq, aes(x=Var1, y=Freq, fill=Var1)) + 
  geom_bar(stat='identity') + guides(fill=FALSE) + xlab("Level") + ylab("Frequency") + ggtitle("Title") +
  geom_text(aes(label=Freq), vjust = 0.5, hjust= -1, size=4, family="ITC Officina Sans") +
  coord_flip() + theme_economist() + 
  scale_fill_manual(values=mycols)

enter image description here

Upvotes: 5

Related Questions