Где хранятся цвета шкалы в объекте ggplot2?

Скажем, я создаю сюжет:

df <- data.frame(A = 1:100, B = jitter(1:100, 25), C = c('One', 'Two'))

p <- ggplot(df, aes(A, B, colour = C)) + 
  geom_point() + 
  scale_colour_manual(values = c('red', 'green'))

Где хранятся эти цвета (красный и зеленый) в p?


Здесь я вижу палитру функций, используемых в функции:

p$scales$scales[[1]]$palette

Содержимое этой функции:

function (n) 
{
  if (n > length(values)) {
    stop("Insufficient values in manual scale. ", n, " needed but only ", 
      length(values), " provided.", call. = FALSE)
  }
  values
}

Я думаю, что цвета должны храниться в values, но я понятия не имею, где они на самом деле находятся в p.


P.S. Я видел этот вопрос: Как извлечь заливку цвета из объекта ggplot?. Но для того, что я пытаюсь сделать, я не могу построить сюжет. Мне нужно получить цвета, прежде чем он будет построен.

Если бы был какой-то способ рекурсивного поиска p символов «красный» или «зеленый», это, вероятно, помогло бы найти эти значения.


РЕДАКТИРОВАТЬ: Что я в конечном итоге пытаюсь сделать.

Я пытаюсь редактировать графики до того, как они будут построены. Идея заключалась в том, что с заданным сюжетом p вы можете просто сделать что-то вроде этого:

apply_theme(p) 

...и цветовая схема применяется ко всему графику (включая масштабы, градиенты и т. д.). Это делается для того, чтобы не делать такие вещи, как:

p + some_theme + scales_colour_manual(values = plot_theme) 

Я пытаюсь уменьшить усилия пользователя, чтобы он мог просто применить тему ко всему сюжету и не беспокоиться о том, раскрашивают ли они градиент, дискретную шкалу или что-то еще.

Строительство участка является частичным решением. Но я хотел бы иметь возможность применить тему и по-прежнему иметь возможность редактировать сюжет позже.

Я смог отредактировать p так, чтобы любые цвета применялись к геометрии задним числом. Но я просто не могу найти, как это сделать с цветами шкалы. Я знаю, что цвета должны быть где-то там!


person Ciarán Tobin    schedule 08.01.2013    source источник
comment
Извините, я только что увидел, что вы не можете построить сюжет. Таким образом, я удалил свой ответ. Можете ли вы объяснить, почему строительство участка не вариант?   -  person Roland    schedule 08.01.2013
comment
@Roland добавил правку. Может быть, я иду об этом совершенно неправильно.   -  person Ciarán Tobin    schedule 08.01.2013


Ответы (1)


Прогресс невелик, но я исключил несколько мест, где он может скрываться.

Вы можете увидеть весь вектор символов, который p содержит с

Filter(is.character, unlist(p))
# $labels.x
# [1] "A"

# $labels.y
# [1] "B"

# $labels.colour
# [1] "C"

Таким образом, он не хранится напрямую.

Установив options(error = recover), а затем форсировав ошибку, предоставив только один цвет, мы можем проверить стек вызовов.

(p <- ggplot(df, aes(A, B, colour = C)) + 
  geom_point() + 
  scale_colour_manual(values = 'red')
)

 1: print(list(data = list(A = 1:100, B = c(4.32692646654323, 3.46481398493052, 0.4989527114667, 
...
13: scale$palette(n)

Войдя в кадр 13: scale$palette(n), мы видим, что переменная values действительно хранит информацию о цвете.

Browse[1]> values
[1] "red"

Мы можем просмотреть каждый кадр в стеке вызовов, но происходит что-то странное — похоже, его нигде нет.

Browse[1]> sapply(
  sys.frames(), 
  function(envir) 
  {
    exists("values", envir, inherits = FALSE)
  }
)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[16] FALSE FALSE

(Подробнее о стеке вызовов см. в разделе sys.status().)

Я подозреваю, что с эталонным классом Scales используется какой-то странный метод оценки.

person Richie Cotton    schedule 08.01.2013
comment
+1 спасибо за усилия. Часть трудностей возникает из-за количества вложений, происходящих в p. Например. Filter(is.character, unlist(p)) возвращает только три символа... но я точно знаю, что их больше (попробуйте: Filter(is.character, unlist(p$scales$scales)) просто в качестве примера). values может не существовать в p... цвета могут быть под каким-то другим названием. Мне, вероятно, нужен какой-то метод, чтобы полностью unlist() p. - person Ciarán Tobin; 08.01.2013