Reputation: 3238
This question is a continuation of a previous question with the same data but with a slight tweak.
Same as before, this is the example I am looking to achieve, with the part I want now highlighted in green:
Instead of coloring a specific regression line, now I want to add a direct label to the plot window like above. I know that by faceting the data, we can achieve this with a legend, coloring the lines, etc. We can even manually add an annotation by selecting the x and y coordinates with annotate
or geom_text
.
But I want something that doesn't require a legend or manually figuring out where the exact geom coordinates are. Is there a way to simply add the label to a regression line within the plot window similar to other aes
functions? This is the base plot I have so far, with the label now removed and regression lines colored:
ggplot(slack.work,
aes(x=Coffee_Cups,
y=Mins_Work,
color=Month_Name))+
geom_point(alpha = .4)+
geom_smooth(method = "lm",
se = F)+
scale_colour_viridis_d()+
theme_bw()+
labs(title = "Coffee Cups x Minutes of Productivity",
subtitle = "Pearson r = .30, p < .001",
x="Cups of Coffee",
y="Minutes of Work",
color="Month")+
theme(plot.title = element_text(face = "bold",
size = 15,
family = "mono"),
plot.subtitle = element_text(face = "italic"),
legend.position = "none")
Currently, it looks like this:
But I would like for it to look something like this:
Upvotes: 0
Views: 578
Reputation: 125268
Adapting this answer to your case you could achieve your desired result by using stat="smooth"
via geom_text
or ggrepel::geom_text_repel
. The tricky part is to get only one label for which I use an ifelse
inside after_stat
:
library(ggplot2)
# Levels of Month_Name.
# Needed to get the month names.
# When using after_stat only get the level number via `group`
levels_month <- levels(factor(slack.work$Month_Name))
ggplot(
slack.work,
aes(
x = Coffee_Cups,
y = Mins_Work,
group = Month_Name,
color = Month_Name == "January"
)
) +
geom_point(alpha = .4) +
geom_smooth(
data = ~subset(.x, !Month_Name == "January"),
method = "lm",
se = F
) +
geom_smooth(
data = ~subset(.x, Month_Name == "January"),
method = "lm",
se = F
) +
ggrepel::geom_text_repel(aes(label = after_stat(ifelse(x %in% range(x)[1], levels_month[group], NA_character_))),
stat = "smooth", method = "lm",
nudge_x = -.5, direction = "y") +
scale_x_continuous(expand = expansion(add = c(.5, 0), mult =.05)) +
scale_colour_manual(values = c("TRUE" = "steelblue", "FALSE" = "grey65")) +
annotate("text",
x = 3,
y = 800,
label = "January had the strongest effect on productivity.",
size = 4,
color = "steelblue"
) +
theme_bw() +
labs(
title = "Coffee Cups x Minutes of Productivity",
subtitle = "Pearson r = .30, p < .001",
x = "Cups of Coffee",
y = "Minutes of Work",
color = "Month"
) +
theme(
plot.title = element_text(
face = "bold",
size = 15,
family = "mono"
),
plot.subtitle = element_text(face = "italic")
) +
guides(color = "none")
EDIT To get rid of the segments connecting the line and the label you could add min.segment.length = Inf
to geom_text_repel
:
... +
ggrepel::geom_text_repel(aes(label = after_stat(ifelse(x %in% range(x)[1], levels_month[group], NA_character_))),
stat = "smooth", method = "lm", min.segment.length = Inf,
nudge_x = -.5, direction = "y") +
...
Upvotes: 1