Reputation: 6755
I have this heatmap with value labels added to each tile
require(ggplot2)
require(RColorBrewer)
require(dplyr)
jBuPuFun <- colorRampPalette(brewer.pal(n = 9, "BuPu"))
paletteSize <- 256
jBuPuPalette <- jBuPuFun(paletteSize)
nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")
nba$Name <- with(nba, reorder(Name, PTS))
nba.m <- melt(nba)
nba.m <- ddply(nba.m, .(variable), transform,
rescale = rescale(value))
ggplot(nba.m, aes(variable, Name)) +
geom_tile(aes(fill = rescale), colour = "white") +
scale_fill_gradient2(low = jBuPuPalette[1],
mid = jBuPuPalette[paletteSize/2],
high = jBuPuPalette[paletteSize],
midpoint = 0.5) +
geom_text(aes(fill = rescale, label = round(rescale, 1)), colour = "white")
Nevertheless labels maintain a uniform colour (white) which make them difficult to read when the background is also light.
Is there any elegant way to dynamically define the color of each geom_text
based on the filling value?
Upvotes: 2
Views: 1327
Reputation: 32426
If you color the text in the reverse of the fill, you can get decent results. I changed the midpoint of the reverse coloring to "steelblue" because the colors will be hard to differentiate at the midpoint if you don't tweak it there.
p <- ggplot(nba.m, aes(variable, Name)) +
geom_tile(aes(fill = rescale), color="white") +
scale_fill_gradient2(low = jBuPuPalette[1],
mid = jBuPuPalette[paletteSize/2],
high = jBuPuPalette[paletteSize],
midpoint = 0.5) +
scale_color_gradient2(low = jBuPuPalette[paletteSize],
mid = "steelblue",
high = jBuPuPalette[1],
midpoint = 0.5) +
geom_text(aes(fill = rescale, color=rescale, label = round(rescale, 1)))
Upvotes: 1