I guess this is not so much a problem as something I don't understand. I initially assigned colors in scale_color_manual
:
values = c(
"300+ " = "#2B4871",
"150 - 300 " = "#05BADD",
"75 - 150 " = "#FFB404",
"0 - 75 " = "#FF8007"
)
...and set the geom_point aesthetic color value to one of the number ranges "300+ ", "150 - 300 ", "75 - 150 ", "0 - 75 ", and my colors on the table were coming out right, but the legend was printing out of order--- I think the colors were coming out in "alphabetical order" based on the number ranges ("0 - 75 " coming first, then "150 - 300 ", then "300+ ", then "75 - 150 ") I set them equal to. Anyway, I deleted the number ranges:
values = c(
"#2B4871",
"#05BADD",
"#FFB404",
"#FF8007"
)
...and I set the geom_point aesthetic color values to the hex color codes directly rather than referencing the number ranges. But when I did that, the colors came out wrong again, but on the plot instead!
It only righted itself once I switched the first two geom_point() code block hex codes and the last two geom_point code block hex codes:
# Create labels for week-year ----
labels_wy <- c(
"Week 15\n2016", "Week 16\n2016", "Week 17\n2016", "Week 18\n2016",
"Week 19\nMay-16"
)
# create df to use in next plot ----
weekly_moderate_75_150_300 <- as.data.frame(
weekly_data %>%
group_by(
weekly_moderate_m < 75,
(weekly_moderate_m >= 75 & weekly_moderate_m < 150),
(weekly_moderate_m >= 150 & weekly_moderate_m < 300),
weekly_moderate_m >= 300
) %>%
tally()
)
weekly_moderate_75_150_300_table <-
cbind(c("300+ ", "150 - 300 ", "75 - 150 ", "0 - 75 "), weekly_moderate_75_150_300[, 5])
# Create weekly_moderate_p ----
weekly_moderate_p <-
ggplot(weekly_data, aes(x = week_number, y = weekly_moderate_m))
# Add layers to weekly_moderate_p ----
weekly_moderate_p +
geom_point(
data = weekly_data[which(weekly_data$weekly_moderate_m >= 300), ],
aes(color = "#05BADD"),
size = 2,
position = position_jitter(width = .25, height = 0),
alpha = 0.5
) +
geom_point(
data = weekly_data[which(weekly_data$weekly_moderate_m >= 150 & weekly_data$weekly_moderate_m < 300), ],
aes(color = "#2B4871"), # This one is switched with #05BADD
size = 2,
position = position_jitter(width = .25, height = 0),
alpha = 0.5
) +
geom_point(
data = weekly_data[which(weekly_data$weekly_moderate_m >= 75 & weekly_data$weekly_moderate_m < 150), ],
aes(color = "#FF8007"),
size = 2,
position = position_jitter(width = .25, height = 0),
alpha = 0.5
) +
geom_point(
data = weekly_data[which(weekly_data$weekly_moderate_m < 75), ],
aes(color = "#FFB404"), # This one is switched with FF8007
size = 2,
position = position_jitter(width = .25, height = 0),
alpha = 0.5
) +
scale_x_discrete(name = NULL, labels = labels_wy) +
scale_y_continuous(
breaks = c(0, 75, 150, 300, 450, 600, 750, 900, 1050),
limits = c(0, 1060)) +
scale_color_manual(
name = "Minutes",
labels = c("300+ ", "150 - 300 ", "75 - 150 ", "0 - 75 "),
values = c(
"#2B4871",
"#05BADD",
"#FFB404",
"#FF8007"
)
) +
labs(
title = "Moderate activity",
subtitle = "(minutes per week)"
) +
geom_hline(yintercept = 75, linetype = "dashed", color = "black") +
geom_hline(yintercept = 150, linetype = "dashed", color = "black") +
geom_hline(yintercept = 300, linetype = "dashed", color = "black") +
ylab("Activity minutes") +
theme_minimal() +
theme(
plot.subtitle = element_text(
margin = margin(1, 5, 5, 0),
size = 10,
hjust = 1,
face = "italic"
),
axis.title.y = element_text(
margin = margin(0, 5, 0, 5),
size = 12
),
plot.title = element_text(
margin = margin(5, 5, 5, 0),
size = 14,
hjust = 1,
face = "bold"
),
legend.position = "bottom"
) +
guides(color = guide_legend(override.aes = list(size = 4))) +
# Add summary table to weekly_moderate_p ----
coord_cartesian(clip = "off") +
theme(
plot.margin = margin(1, 25, 1, 1)
) +
annotation_custom(
grob = tableGrob(weekly_moderate_75_150_300_table, theme = ttheme_minimal(
base_size = 9,
base_color = "black",
base_family = "",
parse = FALSE,
padding = unit(c(4, 4), "mm"),
core = list(
bg_params = list(fill = c("#2B4871", "#05BADD", "#FFB404", "#FF8007"),
alpha = .5,
col = NA),
fg_params = list(hjust = 0, x = 0.15, fontface = c(rep("plain", 3))),
colhead = list(fg_params = list(hjust = 0, x = 0.15))
),
vp = NULL
)),
xmin = 4.5, xmax = 6, ymin = 600, ymax = 1050
)
It ends up looking like , which is ideal, but I don't understand why. I would personally prefer the code to make sense to me and be matched up correctly, but if it works, it's not too much of a problem.
Here's a console output
structure(list(week_number = c("Week 15 of 2016", "Week 16 of 2016",
"Week 17 of 2016", "Week 18 of 2016", "Week 19 of 2016", "Week 15 of 2016",
"Week 16 of 2016", "Week 17 of 2016", "Week 18 of 2016", "Week 19 of 2016",
"Week 15 of 2016", "Week 16 of 2016", "Week 17 of 2016", "Week 18 of 2016",
"Week 19 of 2016", "Week 15 of 2016", "Week 16 of 2016", "Week 17 of 2016",
"Week 18 of 2016", "Week 19 of 2016"), weekly_moderate_m = c(87,
135, 127, 172, 73, 0, 29, 82, 69, 0, 171, 119, 166, 160, 25,
0, 33, 0, 7, 0)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-20L))
After a variety of attempts at making this make sense, I would like to just understand what is going on. Thanks!
Defining the colors in scale_color_manual()
with a named vector as you describe at the beginning of your question is a good way to do this. Your ggplot
code is more complicated than it should be and does not use the aesthetic logic that ggplot2 intends. Instead of defining several geom_point()
s and setting the color to hex color values you'd want to prepare a dataset that includes the bins/groups for the coloring and then use that variable for the color
aesthetic in one singular geom_point()
.
Below is an example that changes how the data is prepared. I reduced the ggplot
-code to the parts essential to your question.
library(tidyverse)
# Create labels for week-year ----
labels_wy <- c("Week 15\n2016",
"Week 16\n2016",
"Week 17\n2016",
"Week 18\n2016",
"Week 19\nMay-16")
# create df to use in next plot ----
weekly_data <-
weekly_data |>
mutate(
bins = case_when(
weekly_moderate_m < 75 ~ "0 - 75",
(weekly_moderate_m >= 75 &
weekly_moderate_m < 150) ~ "75 - 150",
(weekly_moderate_m >= 150 &
weekly_moderate_m < 300) ~ "150 - 300",
weekly_moderate_m >= 300 ~ "300+"
),
bins = factor(bins, levels = c("0 - 75", "75 - 150", "150 - 300", "300+"))
)
# plot ----
ggplot(weekly_data, aes(x = week_number, y = weekly_moderate_m)) +
geom_point(
aes(color = bins),
size = 2,
position = position_jitter(width = .25, height = 0),
alpha = 0.5
) +
scale_x_discrete(name = NULL, labels = labels_wy) +
scale_y_continuous(breaks = c(0, 75, 150, 300, 450, 600, 750, 900, 1050),
limits = c(0, 1060)) +
scale_color_manual(
name = "Minutes",
values = c(
"300+" = "#2B4871",
"150 - 300" = "#05BADD",
"75 - 150" = "#FFB404",
"0 - 75" = "#FF8007"
)
) +
theme_minimal()