Преобразовать ggplot в оттенки серого с помощью stat_summary

#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)