Search code examples
rbar-chartlinechartggvismultiple-axes

How to align a bar and a line chart in ggvis in a dual y-axes plot?


Using the following code:

library(ggvis)
library(dplyr)
mydf2 <- iris %>%
  group_by(Species) %>%
  summarize(Sepal.Length = mean(Sepal.Length),
            Sepal.Width = mean(Sepal.Width)) 

mydf2 %>% as.data.frame()  %>% 
  ggvis(x = ~ Species, y = ~ Sepal.Length ) %>%
  layer_bars(fillOpacity := 0.1 ) %>%
  add_axis("y", "ywidth", orient = "right", grid = FALSE) %>%
  layer_lines(prop("y", ~ Sepal.Width, scale = "ywidth")) %>%
  add_axis('x', title='the species', properties = axis_props(labels=list(fill='blank'))) %>%
  add_axis('x', 'myx2', orient='bottom', title='') %>%
  layer_lines(prop("x", ~ Species, scale = "myx2"), stroke := 'blank')

Output:

enter image description here

My issue is:

  • Does anyone know of a way to align the bar and line charts on this dual y-axes plot? I would like the tick marks to be aligned on the x-axis for both charts.

Edit

I decided to edit this question and provide a better example that shows better the problem.


Solution

  • After about 4 months and a bit of researching I found a way around this issue although it is kind of a hack:

    mydf2 %>% as.data.frame() %>% mutate(Species2= as.numeric(Species)) %>% 
      ggvis(x = ~ Species2, y = ~ Sepal.Length ) %>%
      layer_bars(fillOpacity := 0.1, width = 0.9 ) %>%
      add_axis("y", "ywidth", orient = "right", grid = FALSE) %>%
      layer_lines(prop("y", ~ Sepal.Width, scale = "ywidth")) %>%
      add_axis('x', title='the species', properties = axis_props(labels=list(fill='blank'))) %>%
      add_axis('x', 'myx2', orient='bottom', title='', grid=F) %>%
      layer_lines(prop("x", ~ Species, scale = "myx2"), stroke := 'blank') 
    

    Output

    enter image description here

    The rational behind the above answer is that in order for the line and the bar chart to be aligned the x-axis needs to be numeric. So, I made a new categorical x-axis which is used to plot an invisible line (check last two lines of code). The result is not optimal but it works.

    You could also check this answer too.

    P.S. The example code for the question comes from this post on github. The above has (luckily) been raised as an issue there. If it gets fixed (or there is a way to fix this) I will update the answer.