#r #ggplot2
#r #ggplot2
Вопрос:
У меня есть пакет R в качестве серверного движка для графического интерфейса пользователя (JASP). Я хочу, чтобы люди могли конвертировать свои изображения в оттенки серого (для печати публикации). Для большинства графиков я могу использовать scale_colour_grey()
, но это не работает, когда цвета указаны в stats_summary. Например:
# simulate data
set.seed(1212)
y = rnorm(100)
g = sample(c("a", "b"), 100, T)
d = data.frame(y=y, g=g)
### create ggplot
plot = ggplot(data=d, aes(x=g, y=y))
geom_jitter()
stat_summary(fun="mean", geom="point", size=3, color="red")
stat_summary(geom="errorbar", size=3, color="red")
theme_bw()
### converting to greyscale doesn't work
plot scale_colour_grey()
После некоторого исследования я узнал, что вы можете проанализировать объект ggplot, а затем перестроить его:
### can rebuilt ggplot object, but not ideal
q <- ggplot_build(plot)
q$data[[2]]$colour <- "black"
q$data[[3]]$colour <- "black"
q <- ggplot_gtable(q)
plot = ggplotify::as.ggplot(q)
plot
Это работает нормально, но я стараюсь включать как можно меньше зависимостей в свои R-пакеты. Действительно ли мне нужно прибегать к другому пакету (ggplotify), чтобы изменить цвет, поступающий из stat_summary?
Несколько замечаний: я не хочу изменять исходную инструкцию stat_summary. Давайте просто представим, что это нельзя изменить. Кроме того, давайте предположим, что я не могу добавить другой пакет (кроме ggplot2, который уже загружен). Помните, я «гость» во фреймворке JASP, и я не хочу добавлять другой пакет в список пакетов, которые они должны хранить.
Комментарии:
1. Просто удалите
color = "red"
изstat_summary
и поместите его в начальный вызовggplot(data=d, aes(x=g, y=y, color="red"))
. Таким образом, другие слои (geom_*
илиscale_*
) унаследуют его.2. Спасибо за комментарий, но это не вариант. Опять же, я не могу изменить существующий график. (И это все равно не сработало бы в моем случае… Я не хочу изменять цвет точек, только цвет из stat_summary).
Ответ №1:
На самом деле вы можете получить доступ к объекту ggplot до его построения, перейти к слою с цветным объектом и изменить его. Вот полное повторение:
library(ggplot2)
# simulate data
set.seed(1212)
y = rnorm(100)
g = sample(c("a", "b"), 100, T)
d = data.frame(y=y, g=g)
### create ggplot
p <- ggplot(data=d, aes(x=g, y=y))
geom_jitter()
stat_summary(fun="mean", geom="point", size=3, color="red")
stat_summary(geom="errorbar", size=3, color="red")
theme_bw()
p
p$layers[[3]]$aes_params$colour <- "gray50"
p
Если вам нужен более общий подход к изменению цвета конкретной геометрии, вы могли бы выполнить что-то вроде этой функции:
recolour_geom <- function(gg_plot, geom, colour = "gray50")
{
ss <- which(sapply(p$layers, function(l) {
paste(gsub("GEOM|GG|PROTO", "", toupper(class(l$geom))),
collapse = "")}) %in% toupper(geom))
if (length(ss) > 0)
{
for (i in ss)
{
p$layers[[i]]$aes_params$colour <- colour
}
}
p
}
Что позволяет вам делать, например
recolour_geom(p, "errorbar", "blue")
recolour_geom(p, "point", "green")
Однако имейте в виду, что это изменяет ggplot по ссылке, поэтому p
изменяется как побочный эффект функции.
Создано 2020-08-14 пакетом reprex (версия 0.3.0)