Ответ 1
Следующее должно делать то, что вам нужно. Обратите внимание, что он изменяет только цвета, которые сопоставляются с переменными. Цвет, передаваемый непосредственно на geom_*
, не будет затронут (пример ниже). Для подхода, который изменяет colour
или fill
(в зависимости от того, что отображается первым), см. Нижнюю половину этого сообщения.
change_colours <- function(p, palette) {
n <- nlevels(p$data[[deparse(p$mapping$group)]])
tryCatch(as.character(palette),
error=function(e) stop('palette should be a vector of colours', call.=FALSE))
if(n > length(palette)) stop('Not enough colours in palette.')
pal <- function(n) palette[seq_len(n)]
p + theme_light() + discrete_scale('colour', 'foo', pal)
}
# Here, df is from the OP post
p <- ggplot(df, aes(x=TS, y=price, group=stock))
Примеры:
# NB: custom_pal is defined in the OP post
change_colours(p + geom_line(aes(colour=stock)), custom_pal)
change_colours(p + geom_point(aes(colour=stock)), custom_pal)
И с другой палитрой:
change_colours(p + geom_smooth(aes(colour=stock)),
c('firebrick', 'midnightblue', 'violet', 'seagreen'))
Как упоминалось выше, это изменит только значения colour
и fill
, которые отображаются на переменные. Например, это не повлияет на следующие цвета:
change_colours(p + geom_point(colour=rep(c('tomato', 'hotpink', 'cadetblue'), each=300)),
custom_pal)
В ответ на OP comment вы можете легко определить, какие типы сопоставлений используются (например, alpha
, colour
, fill
). Просто взгляните на p$layers[[1]]$mapping
.
Если мы предположим, что первое отображение fill
или colour
первого слоя - это отображение, для которого вы хотите изменить цвета, вы можете сделать:
change_colours <- function(p, palette, type) {
n <- nlevels(p$data[[deparse(p$mapping$group)]])
tryCatch(as.character(palette),
error=function(e) stop('palette should be a vector of colours', call.=FALSE))
if(n > length(palette)) stop('Not enough colours in palette.')
if(missing(type))
type <- grep('colour|fill', names(p$layers[[1]]$mapping), value=TRUE)[1]
pal <- function(n) palette[seq_len(n)]
p + theme_light() + discrete_scale(type, 'foo', pal)
}
# Here, df is from the OP post
p <- ggplot(df, aes(x=TS, y=price, group=stock))
Примеры:
Изменение заливки вместо цвета:
change_colours(p + geom_point(aes(fill=stock), pch=21),
c('white', 'grey50', 'grey80'))
Отображение приоритета первого сопоставленного цвета/заливки:
change_colours(p + geom_point(aes(fill=stock, color=stock), pch=21) +
geom_smooth(aes(color=stock)),
c('black', 'grey50', 'grey80'))
change_colours(p + geom_point(aes(color=stock, fill=stock), pch=21) +
geom_smooth(aes(color=stock)),
c('black', 'grey50', 'grey80'))
Отмените приоритет первой сопоставленной эстетики с аргументом type
, например:
change_colours(p + geom_point(aes(color=stock, fill=stock), pch=21) +
geom_smooth(aes(color=stock)),
c('black', 'grey50', 'grey80'), type='fill')