ggplot2: факторы восстановления для последовательно добавленных слоев - PullRequest
0 голосов
/ 24 июня 2019

Я пишу метод построения для класса "foo". Мне бы хотелось, чтобы эта функция построения графика принимала несколько foo объектов и отображала их на одном графике.

Код

#parabola function
parabolas <- function(x, parm) {
  y <- parm[1]*(x^2)+parm[2]*x+parm[3]
  return(y)
}
#make foo object
make_foo <- function(a, b, c) {
   x <- runif(100, 0 , 20)
   y <- parabolas(x = x, parm = c(a,b,c)) + rnorm(100, mean = 100 ,sd = 100)
   foo <- list(data = data.frame(x = x, y = y), parameters = c(a,b,c))
   class(foo) <- "foo"
   return(foo)
}


#plot function
plot.foo <- function(x, 
                 ...,
                 labels) {

 a <- ggplot(NULL, aes(x = x, y = y))

 foo.list <- list(x, ...)
 #browser()
 #build plot
 for(i in 1:length(foo.list)){
   foo.obj <- foo.list[[i]]
   foo.obj$data$lab <- factor(rep(labels[i], nrow(foo.obj$data)), levels = labels)
a <- a + geom_point(data = foo.obj$data, size = 5, alpha = .7, aes(color = lab))
a <- a + stat_function(data = foo.obj$data,
                       fun = parabolas, 
                       args = list(parm = foo.obj$parameters), size = 1.2)
 }
 return(a)
}

Проблема

ggplot получит уровни фактора lab в соответствии с алфавитным порядком меток факторов. Я не знаю, как выбрать порядок уровней факторов для lab при последовательном добавлении этих слоев. Я хотел бы, чтобы первый элемент labels соответствовал первому изображенному объекту foo, а второй элемент соответствовал второму объекту foo и т. Д. И т. Д.

foo1 <- make_foo(2, 10, 3)
foo2 <- make_foo(-6, -3, 2000)
plot(foo1, foo2, labels = c("obj1","obj2"))
#label for foo1 is "obj1" and label for foo2 is "obj2"
plot(foo1, foo2, labels = c("obj3","obj2"))
#label for foo1 should be "obj3" and label for foo2 should be "obj2"

Мотивация

Причина, по которой я структурирую функцию графика таким образом, а не связываю вместе кадры данных и присваиваю правильные уровни факторов для lab, заключается в том, что в этом конкретном случае facet_wrap и stat_function не работают хорошо вместе. После применения нескольких stat_function и одновременного использования facet_wrap все кривые появятся на каждой панели. Эта тема иллюстрирует похожую проблему . Поскольку эти разные слои ограничены разными наборами данных, facet_wrap будет корректно огранять каждый график stat_function в соответствии с данными / параметрами, использованными для его построения.

plot(foo1, foo2, labels = c("z","a")) + facet_wrap(~lab, scales = "free")
#Shows facet_wrap works as intended but the labels for foo1 and foo2 are
#still not in the intended order

1 Ответ

0 голосов
/ 24 июня 2019

Вы можете вручную изменить порядок цветовой шкалы, установив limits. Вот как:

plot.foo <- function(x, 
                     ...,
                     labels) {

  a <- ggplot(NULL, aes(x = x, y = y))

  foo.list <- list(x, ...)
  #browser()
  #build plot
  for(i in 1:length(foo.list)){
    foo.obj <- foo.list[[i]]
    foo.obj$data$lab <- factor(rep(labels[i], nrow(foo.obj$data)), levels = labels)
    a <- a + geom_point(data = foo.obj$data, size = 5, alpha = .7, aes(color = lab))
    a <- a + stat_function(data = foo.obj$data,
                           fun = parabolas, 
                           args = list(parm = foo.obj$parameters), size = 1.2)
  }

  ### added line:
  a <- a + scale_color_discrete(limits = labels)
  ###

  return(a)
}

enter image description here

enter image description here

...