Howard, Tim G (DEC)
2023-Oct-31 12:35 UTC
[R] Missing shapes in legend with scale_shape_manual
I believe the missing shapes are because you had set alpha=0 for the last geom point. I expect there are better ways, but one way to handle it would be to avoid the filtering, adding columns with med and exercise status, like the following: # setup with data provided Date <- c('2023-10-17', '2023-10-16', '2023-10-15', '2023-10-14', '2023-10-13', '2023-10-12', '2023-10-11') Time <- c('08:50', '06:58', '09:17', '09:04', '08:44', '08:55', '07:55') bg <- c(128, 144, 137, 115, 136, 122, 150) missed_meds <- c(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE) no_exercise <- c(FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE) b2 <- data.frame(Date, Time, bg, missed_meds, no_exercise) b2$Date <- as.Date(b2$Date) # add "status" columns, could also be defined as factor. b2$medStat <- c("missed_meds",NA, NA, NA, NA, NA, "missed_meds") b2$exercise <- c(NA, NA, "missed_exercise",NA,"missed_exercise", "missed_exercise", "missed_exercise") Then your ggplot call would be like this: ggplot(data = b2, aes(x = Date, y = bg)) + geom_line() + geom_point(aes(shape = medStat), size = 3)+ geom_point(aes(shape = exercise),size = 3)+ scale_y_continuous(name = "Blood glucose (mg/dL)", breaks = seq(100, 230, by = 20) ) + geom_hline(yintercept = 130) + scale_shape_manual(name = "Conditions", labels = c("Missed meds", "Missed exercise"), values = c(20, 4) ) Note that this method then gets very close without the scale_shape_manual, too. Hope that helps. Tim> Date: Mon, 30 Oct 2023 20:55:17 +0000 > From: Kevin Zembower <kevin at zembower.org> > To: r-help at r-project.org <r-help at r-project.org> > Subject: [R] Missing shapes in legend with scale_shape_manual > Message-ID: > <0100018b825e8f7f-646d2539-f8b5-4e1a-afc3-5d29f961967f- > 000000 at email.amazonses.com> > > Content-Type: text/plain; charset="utf-8" > > Hello, > > I'm trying to plot a graph of blood glucose versus date. I also record > conditions, such as missing the previous night's medications, and missing > exercise on the previous day. My data looks like: > > > b2[68:74,] > # A tibble: 7 ? 5 > Date Time bg missed_meds no_exercise > <date> <time> <dbl> <lgl> <lgl> > 1 2023-10-17 08:50 128 TRUE FALSE > 2 2023-10-16 06:58 144 FALSE FALSE > 3 2023-10-15 09:17 137 FALSE TRUE > 4 2023-10-14 09:04 115 FALSE FALSE > 5 2023-10-13 08:44 136 FALSE TRUE > 6 2023-10-12 08:55 122 FALSE TRUE > 7 2023-10-11 07:55 150 TRUE TRUE > > > > This gets me most of the way to what I want: > > ggplot(data = b2, aes(x = Date, y = bg)) + > geom_line() + > geom_point(data = filter(b2, missed_meds), > shape = 20, > size = 3) + > geom_point(data = filter(b2, no_exercise), > shape = 4, > size = 3) + > geom_point(aes(x = Date, y = bg, shape = missed_meds), > alpha = 0) + #Invisible point layer for shape mapping > scale_y_continuous(name = "Blood glucose (mg/dL)", > breaks = seq(100, 230, by = 20) > ) + > geom_hline(yintercept = 130) + > scale_shape_manual(name = "Conditions", > labels = c("Missed meds", > "Missed exercise"), > values = c(20, 4), > ## size = 3 > ) > > However, the legend just prints an empty square in front of the labels. > What I want is a filled circle (shape 20) in front of "Missed meds" and a filled > circle (shape 4) in front of "Missed exercise." > > My questions are: > 1. How can I fix my plot to show the shapes in the legend? > 2. Can my overall plotting method be improved? Would you do it this way? > > Thanks so much for your advice and guidance. > > -Kevin > > > >