Reputation: 1141
I've got a grouped plot in which I've already labelled the peak with it's x-axis value. However, I'd like another label in the top right of the plot with another measure, but I can't get it to work. Here's an example.
d <- data.frame(USArrests)
nrow(d)
d$predictor <- factor(c(rep(c(1, 2), times = 25)))
label <- d %>%
group_by(predictor) %>%
filter(Assault == max(Assault))
label$measure1 <- c(1.45, 5.67)
label$measure2 <- c(4.55, 6.11)
library(ggplot2)
ggplot(d, aes(x=UrbanPop, y=Assault, fill=predictor)) +
geom_col(position=position_dodge(width = 0, preserve = "single"), width = 5) +
geom_text(data = label, aes(label = UrbanPop)) +
geom_text(data = label, aes(label = measure), hjust="right", vjust="top")
I want the second label in the top right to say in red "measure1 = 1.45" then on a new line "measure2 = 4.55", then below it in green "measure1 = 5.67" and on a new line "measure2=6.11". Obviously "measures" are dynamic objects, so I don't just want to insert a static caption. Any help much appreciated!
Upvotes: 1
Views: 1879
Reputation: 4243
It's a bit clunky, but you could create the full labels in a data.frame and force them to be on different lines with \n
.
d <- data.frame(USArrests)
d$predictor <- factor(c(rep(c(1, 2), times = 25)))
label <- d %>%
group_by(predictor) %>%
filter(Assault == max(Assault))
label$measure1 <- c(1.45, 5.67)
label$measure2 <- c(4.55, 6.11)
label2 <- label %>%
pivot_longer(measure1:measure2, 'measure', 'value') %>%
mutate(label = case_when(
predictor == 1 & measure == 'measure1' ~ paste0(measure, ' = ', value),
predictor == 1 & measure == 'measure2' ~ paste0('\n', measure, ' = ', value),
predictor == 2 & measure == 'measure1' ~ paste0('\n\n', measure, ' = ', value),
predictor == 2 & measure == 'measure2' ~ paste0('\n\n\n', measure, ' = ', value)
))
ggplot(d, aes(x=UrbanPop, y=Assault, fill=predictor)) +
geom_col(position=position_dodge(width = 0, preserve = "single"), width = 5) +
geom_text(data = label, aes(label = UrbanPop)) +
geom_text(data = label2,
aes(x = Inf, y = Inf, label = label, color = predictor),
hjust="right", vjust="top")
Upvotes: 1
Reputation: 23737
E.g., use x and y = Inf. In your example, faceting makes sense, because you pass the label to different data-sets.
library(tidyverse)
d <- data.frame(USArrests)
d$predictor <- factor(c(rep(c(1, 2), times = 25)))
label <- d %>%
group_by(predictor) %>%
filter(Assault == max(Assault))
label$measure1 <- c(1.45, 5.67)
label$measure2 <- c(4.55, 6.11)
ggplot(d, aes(x=UrbanPop, y=Assault, fill=predictor)) +
geom_col(position=position_dodge(width = 0, preserve = "single"), width = 5) +
geom_text(data = label, aes(label = UrbanPop)) +
geom_text(data = label, aes(x = Inf, y = Inf, label = measure2), hjust="right", vjust="top")+
facet_grid(~predictor)
#> Warning: position_dodge requires non-overlapping x intervals
#> Warning: position_dodge requires non-overlapping x intervals
Created on 2020-04-17 by the reprex package (v0.3.0)
Upvotes: 0