Reputation: 822
I am labeling a scatter plot with values. To make it readable, I want the text colour to be darker than the points (a green point would have a darker green label):
p1 <- ggplot(iris, aes(Sepal.Length, Sepal.Width, col = Species))+
geom_point()+
geom_text(aes(label = Sepal.Length), size = 2, position = position_dodge(width = 0.2))
I can use scale_colour_discrete to create the effect I want, but it applies to both points and text.
p1 + scale_colour_discrete(l = 50)
Can I apply it to the text only?
Upvotes: 4
Views: 1862
Reputation: 17668
You can try:
# specify your colour
COL <- c("red", "blue", "green")
p1 <- ggplot(iris, aes(Sepal.Length, Sepal.Width, col = Species))+
geom_point()
p1 <- p1 + scale_colour_manual(values = COL)
Now darken your colour using col2rgb
and rgb
(source) or another approach
COL2 <- col2rgb(COL)
COL2 <- COL2/2 # you can use of course other values than 2. Higher values the darker the output.
COL2 <- rgb(t(COL2), maxColorValue=255)
Plot the labels.
p1 + geom_text(aes(label = Sepal.Length), col=factor(iris$Species, labels=COL2), size = 2, position = position_dodge(width = 0.2))
For better overview I recommend to use geom_text_repel
. Of note, you have to use as.character
.
require(ggrepel)
p1 + geom_text_repel(aes(label = Sepal.Length), size = 2, col= as.character(factor(iris$Species, labels=COL2)))
If you don't want to specify a colour in the beginning you can also extract the original ggplot colors using:
g <- ggplot_build(p1)
COL <- unlist(unique(g$data[[1]]["colour"]))
Then you use the code above for the darker text colour or combine everything in a darker function:
p1 <- ggplot(iris, aes(Sepal.Length, Sepal.Width, col = Species))+
geom_point()
# function
darken <- function(Plot, factor=1.4){
g <- ggplot_build(Plot)
color <- unlist((g$data[[1]]["colour"]))
col <- col2rgb(color)
col <- col/factor
col <- rgb(t(col), maxColorValue=255)
col
}
# basic text
p1 + geom_text(aes(label = Sepal.Length), col=darken(p1, 2), size = 2, position = position_dodge(width = 0.2))
# repel text
p1 + geom_text_repel(aes(label = Sepal.Length), col= darken(p1, 2), size = 2)
Upvotes: 1
Reputation: 310
Define colors for points:
n <- length(levels(iris$Species))
cols_points <- hcl(h = seq(15, 375, length = n + 1), l = 65, c = 100)[1:n]
Plot points as you did initially but set colors manually:
p1 <- ggplot(iris, aes(Sepal.Length, Sepal.Width, colour = Species)) + geom_point() + scale_colour_manual(values = cols_points)
Define text colors by taking the same colors as you used for the plots but changing the hue (l, can be adjusted to how dark you want it):
cols_text <- hcl(h = seq(15, 375, length = n + 1), l = 30, c = 100)[1:n]
iris_cols <- ifelse(iris$Species == "setosa", cols_text[1],
ifelse(iris$Species == "versicolor", cols_text[2], cols_text[3]))
Plot with text annotation (I added a small y-offset, so that text and points don't overlap):
p1 + annotate("text", x = iris$Sepal.Length, y = iris$Sepal.Width + 0.05, label = iris$Sepal.Length, color = iris_cols, size = 2)
Upvotes: 1