5

Sample data:

y1 = c(1,2,3,4)
y2 = c(6,5,4,3)
x  = c(1,2,3,4)
df = data.frame(x,y1,y2)

My Question:

I would like to combine the following two graphs into one, using ggvis:

df %>% ggvis(~x,~y1) %>% layer_paths()
df %>% ggvis(~x,~y2) %>% layer_paths()

However, the following does not work:

df %>% ggvis(~x,~y1) %>% layer_paths() %>% ggvis(~x,~y2) %>% layer_paths()
Alex
  • 15,186
  • 15
  • 73
  • 127

2 Answers2

7

You can refer to the original data and add a layer:

df %>% ggvis(~x,~y1) %>% layer_paths()%>%
  layer_paths(data = df, x = ~x, y = ~y2)

enter image description here

You can remove the reference to the data and it will be inferred:

df %>% ggvis(~x,~y1) %>% layer_paths()%>%
+     layer_paths(x = ~x, y = ~y2)
jdharrison
  • 30,085
  • 4
  • 77
  • 89
  • Thanks, this works, but it's rather unfortunate that you can't use the pipe language to do it. – Alex Jul 25 '14 at 02:39
  • E.g. I expect the following to work but it doesn't: `df %>% ggvis(~x,~y1) %>% layer_paths() %>% { df %>% ggvis(~x,~y2) %>% layer_paths() }` – Alex Jul 25 '14 at 02:42
  • You can remove the reference to the data and it will be inferred. I see nothing unfortunate what you have written is neither clear nor intuitive you are piping a list to a list and expecting? – jdharrison Jul 25 '14 at 05:20
  • ok, that's much better, thanks! :) As for "you are piping a list to a list and expecting", the way I understand the pipe is logical sequences of operators that occur one after another. The way I visualised my pipe operation was sensible from my perspective. – Alex Jul 25 '14 at 07:15
  • So one x,y pair goes in ggvis and another goes in layer_path(). This is a good example of a bad api design – MySchizoBuddy May 15 '15 at 14:49
2

It is possible to merge two ggvis by merging together each of their components:

p1 <- df %>% ggvis(~x,~y1) %>% layer_paths()
p2 <- df %>% ggvis(~x,~y2) %>% layer_paths()

pp <- Map(c, p1, p2) %>% set_attributes(attributes(p1))

I don't know if it works well in all situations, but it works at least for simple plots.

Here is a function that will do it for you:

merge_ggvis <- function(...) {
  vis_list <- list(...)
  out <- do.call(Map, c(list(`c`), vis_list))
  attributes(out) <- attributes(vis_list[[1]])
  out
}

You can use it with objects containing plots:

merge_ggvis(p1, p2)

or in a pipe:

df %>%
  ggvis(~x, ~y1) %>% layer_paths() %>%
  merge_ggvis(
    df %>% ggvis(~x, ~y2) %>% layer_paths()
  )
Lionel Henry
  • 6,652
  • 27
  • 33
  • Thanks for this. Is it possible to handle situation with different axes, So p1 is layer_points with y=y and axis orient = left; and p2 is layer_lines with y=log(y) and axis orient right. I may have to post separate question – pssguy Jun 01 '15 at 20:29