I have the following plot:
df1 <- data.frame(col1 = rep(LETTERS[1:3], each = 4), col2 = rnorm(12), col3 = runif(12), col4 = rep(c("Fred", "Bob"), each = 6))
df1_list <- split(df1, df1$col1)
gridExtra::grid.arrange(grobs = mapply(function (x, y) {
ggplot2::ggplot(x, ggplot2::aes(x = col2, y = col3, col = col4))
ggplot2::geom_point()
ggplot2::ggtitle(y)
ggplot2::scale_color_manual('Person', values = c('Fred' = 'red', 'Bob' = 'blue'))
}, x = df1_list, y = names(df1_list), SIMPLIFY = F))
On the first graph in this figure, all the points represent Fred
, but in the legend, Bob
still appears. Is it possible to include only the people who appear in each graph in the legend?
I want to make sure 'Fred'
is always 'red'
and 'Bob'
is always 'blue'
, so using the scale_discrete_manual
function's drop = T
argument won't work.
Thanks!
CodePudding user response:
Here is a possible solution where the values
parameter in scale_color_manual
is dynamically created.
set.seed(1234)
df1 <- data.frame(col1 = rep(LETTERS[1:3], each = 4), col2 = rnorm(12),
col3 = runif(12), col4 = rep(c("Fred", "Bob"), each = 6))
df1$col4 <- factor(df1$col4)
df1_list <- split(df1, df1$col1)
cols <- setNames(c('red', 'blue'), c('Fred','Bob'))
gridExtra::grid.arrange(grobs = mapply(function (x, y) {
x$col4 <- droplevels(x$col4)
idx <- match(levels(x$col4), names(cols))
ggplot2::ggplot(x, ggplot2::aes(x = col2, y = col3, col = col4))
ggplot2::geom_point()
ggplot2::ggtitle(y)
ggplot2::scale_color_manual('Person', values = cols[idx])
}, x = df1_list, y = names(df1_list), SIMPLIFY = F))
CodePudding user response:
Can you share your sessionInfo()
so we can see the package versions you run? I run your code and this is what I get.