I have a stacked bar plot, labelled with geom_text
. To increase the visibility of the labels, I want to set the label color to either white or black depending of the 'darkness' of their background, i.e. the fill color of the bars. Thus, darker bars should have a white label, and lighter bars should have a black label.
I started with code from the question Showing data values on stacked bar chart in ggplot2, the answer to the question Is there a is light or is dark color function in R?. On top of that I'd like to show the label of the data value in 'white' or 'black' depending whether the stacked bar fill color is dark or not dark respectively.
I made two attempts. The first is using aes(colour=...)
of the geom_text
function but this one fails ... why?.
The second attempt is using the function scale_colour_manual
. But here the stacked bar lines are also "coloured" using the black or white toggling setting.
library(ggplot2)
library(RColorBrewer)
Year <- c(rep(c("2006-07", "2007-08", "2008-09", "2009-10"), each = 4))
Category <- c(rep(c("A", "B", "C", "D"), times = 4))
Frequency <- c(168, 259, 226, 340, 216, 431, 319, 368, 423, 645, 234, 685, 166, 467, 274, 251)
Data <- data.frame(Year, Category, Frequency)
isDark <- function(color) {
(sum(grDevices::col2rgb(color) *c(299, 587,114))/1000 < 123)
}
## control the color assignments
paletteName <- 'Set1' # 'Dark2'
colorsPerCat <- brewer.pal(name=paletteName,n=4)
names(colorsPerCat) <- c("A", "B", "C", "D")
## First attempt
Data$LabelColor <- as.character(as.vector(sapply(unlist(colorsPerCat)[Data$Category], function(color) { if (isDark(color)) 'white' else 'black' })))
Data
p <- ggplot(Data, aes(x = Year, y = Frequency, fill = Category, label = Frequency)) +
geom_bar(stat = "identity") +
geom_text(aes(colour=LabelColor), size = 3, position = position_stack(vjust = 0.5)) +
scale_fill_manual(values = colorsPerCat)
p
## Second attempt
labelColoursPerCat <- sapply(as.vector(colorsPerCat), function(color) { if (isDark(color)) 'white' else 'black' })
names(labelColoursPerCat) <- c("A", "B", "C", "D")
p <- ggplot(Data, aes(x = Year, y = Frequency, fill = Category, label = Frequency, colour = Category)) +
geom_bar(stat = "identity") +
geom_text(size = 3, position = position_stack(vjust = 0.5)) +
scale_fill_manual(values = colorsPerCat) +
scale_colour_manual(values = labelColoursPerCat)
p
Two ways to solve this issue by playing with geom_bar
color or size:
Data$LabelColor <- as.factor(Data$LabelColor)
p <- ggplot(Data, aes(x = Year, y = Frequency, fill = Category, label = Frequency, colour = LabelColor)) +
geom_bar(stat = "identity", color = "black") +
geom_text(size = 3, position = position_stack(vjust = 0.5)) +
scale_fill_manual(values = colorsPerCat) +
scale_colour_manual(values = levels(Data$LabelColor)) +
guides(colour = FALSE)
Data$LabelColor <- as.factor(Data$LabelColor)
p <- ggplot(Data, aes(x = Year, y = Frequency, fill = Category, label = Frequency, colour=LabelColor)) +
geom_bar(stat = "identity", size = 0) +
geom_text(size = 3, position = position_stack(vjust = 0.5)) +
scale_colour_manual(values = levels(Data$LabelColor)) +
scale_fill_manual(values = colorsPerCat) +
guides(colour = FALSE)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With