I have a barplot with labels in white. Sometimes the color of background is too light and the white label becomes illegible. I'm looking for a function that takes a color value and returns whether the color is dark or light. Then I can set the label color to white or black accordingly to obtain the best contrast against the background.
Asked
Active
Viewed 953 times
2
-
I'd prefer the black and white ... if I use grey then when the palette is gray the label will be again illegible. – SkyWalker Mar 22 '18 at 19:52
-
1Something like this maybe: https://stackoverflow.com/questions/47281365/ggplot2-text-color-based-on-background-contrast. When asking for help, you should include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Mar 22 '18 at 19:58
-
Also this function for calculating perceived brightness might help. https://trendct.org/2016/01/22/how-to-choose-a-label-color-to-contrast-with-background/. Don't know of any built-in implementation of it in R but it's clearly not too difficult to write into your own function. – MrFlick Mar 22 '18 at 20:03
-
@MrFlick thank you for the comments. The solution in your first comment is specific to that problem. I will then make a function based on your second comment. I just dont like reinventing the wheel if there exist such a thing already. – SkyWalker Mar 22 '18 at 20:06
1 Answers
10
Here's a strategy to implement picking a text color of black vs white based on the intensity scale in the (second) link provided by @MrFlick.
The blog cited a W3C publication: a standard formula for calculating the perceived brightness of a color that used an algorithm for RGB encoded colors:
((Red value X 299) + (Green value X 587) + (Blue value X 114)) / 1000
The col2rgb
function delivers a 3-row matrix which I multiply by the factors offered in that webpage. I used an example of "red" as a background color and the chosen text would then be "white"
c( "black", "white")[ 1+(sum( col2rgb("red") *c(299, 587,114))/1000 < 123) ]
[1] "white"
Implemented as a function:
isDark <- function(colr) { (sum( col2rgb(colr) * c(299, 587,114))/1000 < 123) }
isDark("red")
[1] TRUE

IRTFM
- 258,963
- 21
- 364
- 487
-
Just in case: in the function `col2rgb("red")` should be `col2rgb(colr)` – DJack Apr 08 '18 at 15:37
-