Search code examples
rggvis

ggvis - add_legend with multiple data and position legend inside graph


I'm trying to add legends with arbitrary text in a ggvis plot using data from different dataframes. I have tried using add_legend() but I have not idea about what parameters to use. Using plot() is very simple using the legend() function but it has been very hard to find a way to do it using ggvis()

Here is a simple example of what I have using plot():

df1 = data.frame(x = sample(1:10), y = sample(1:10))
df2 = data.frame(x = 1:10, y = 1:10)
df3 = data.frame(x = 1:10, y = sqrt(1:10))

plot(df1)
lines(df2$x, df2$y, col = "red")
lines(df3$x, df3$y, col = "green")
legend("topleft", c("Data 2","Data 3"), lty = 1, col = c("red","green"))

Now, using ggvis() I can plot the points and the lines from different datasets but I can not find a way to put the legends using add_legend(), Here is the code using ggvis():

df1 %>% ggvis(x=~x,y=~y) %>% layer_points() %>% 
layer_paths(x=~x,y=~y,data = df2, stroke := "red") %>% 
layer_paths(x=~x,y=~y,data = df3, stroke := "green") 

I will really appreciate any help.

Thank you.

Edited:

This a sample code using only one data frame and plot()

df = data.frame(x = sample(1:10), y = sample(1:10), x2 = 1:10, y2 = 1:10, y3 = sqrt(1:10) )
plot(df[,c("x","y")])
lines(df$x2, df$y2, col = "red")
lines(df$x2, df$y3, col = "green")
legend("topleft", c("Data 2","Data 3"), lty = 1, col = c("red","green"))

Solution

  • So, what I came up with, is the following, which works:

    #add an id column for df2 and df3 and then rbind
    df2$id <- 1
    df3$id <- 2
    df4 <- rbind(df2,df3)
    #turn id into a factor
    df4$id <- factor(df4$id)
    
    #then plot df4 using the stroke=~id argument
    #then plot the legend
    #and finally add df1 with a separate data
    df4 %>% ggvis(x=~x,y=~y,stroke=~id) %>% layer_lines() %>%
            add_legend('stroke', orient="left") %>%
            layer_points(x=~x,y=~y,data = df1,stroke:='black') 
    

    And it works:

    enter image description here

    If you would like to move the legend to a position inside the plot then you need to try this:

    df4 %>% ggvis(x=~x,y=~y,stroke=~id) %>% layer_lines() %>%
      #make sure you use add relative scales
      add_relative_scales() %>%
      #values for x and y need to be between 0 and 1
      #e.g for the x-axis 0 is the at far-most left point and 1 at the far-right 
      add_legend("stroke", title = "Cylinders",
                 properties = legend_props(
                   legend = list(
                     x = scaled_value("x_rel", 0.1),
                     y = scaled_value("y_rel", 1)
                   ))) %>%
      layer_points(x=~x,y=~y,data = df1,stroke:='black') 
    

    And the output:

    enter image description here