1

I'm trying to draw a barplot using ggvis, for some data where for each variable I have both a negative and a positive value. It would be similar to this example from ggplot2.

However, when I try something similar in ggvis, I end up with basically no plot at all, just some weird lines.

Example data:

df <- data.frame(
direction=rep(c("up", "down"), each=3),
value=c(1:3, -c(1:3)),
x=rep(c("A", "B", "C"), 2))

This works, for all positive values:

df %>%
mutate(value.pos=abs(value)) %>%
ggvis(x=~x, y=~value.pos) %>%
group_by(direction) %>%
layer_bars(stack=TRUE)

This gives me nothing:

df %>%
ggvis(x=~x, y=~value) %>%
group_by(direction) %>%
layer_bars(stack=TRUE)

I've also tried various combinations of plotting them one by one, e.g.:

df %>%
spread(key=direction, value=value) %>%
ggvis(x=~x, y=~up) %>%
layer_bars() %>%
layer_bars(x=~x, y=~down)

So far, no luck. I suspect I'm missing some simple solution...

Zhou H
  • 11
  • 1

2 Answers2

0

I don't ggvis lets you produce stacked bar plots with negative values within the same groups as positive data.

This is because if an x value appear more than once in the data, then ggvis will sum up the y values at each x. I had thought that since you plotted the vector 1:3, they canceled out, but that's not the case.

As of now, I do not believe that dodged bar plots exist for this. It also messes with the labels.

You can produce the plot non-stacked, while filling in the position.

df %>%
  group_by(direction) %>%
  ggvis(x=~x, y=~value, fill = ~direction) %>%
  layer_bars(stack = FALSE)

Anyways, you might consider avoiding ggvis for any production work since it is under development, and hasn't been updated in a couple of months.

shayaa
  • 2,787
  • 13
  • 19
0

@shayaa Thanks, this does seem to be working, although it will probably require some tweaking, and may not look as nicely as if I was using ggplot2. Actually, the reason I am using ggvis, is because I would like to combine it with shiny, to make a small interactive web version. For example:

df <- data.frame(
    direction=rep(c("up", "down"), each=3),
    value=c(1:3, -c(1:3)),
    x=rep(c("A", "B", "C"), 2))

plot_fct <- function(letter) {
    df %>%
        filter(x==letter) %>%
        ggvis(x=~x, y=~value, fill = ~direction) %>%
        layer_bars(stack = FALSE) %>%
        scale_numeric("y", domain=c(NA,NA))
}

ui <- fluidPage(
    sidebarPanel(
        selectInput("letter", "Choose letter", c("A", "B", "C"), selected="A")
    ),
    mainPanel(
        ggvisOutput("letter_barplot")
    )
)

server <- function(input, output) {
    plot_fct(letter=reactive(input$letter)) %>% bind_shiny("letter_barplot")
}   
runApp(shinyApp(ui, server))

However, it does not seem to work for me anyway, since there is some issue with the reactive being of class character. I keep getting the error:

Error in eval(substitute(expr), envir, enclos) : comparison (1) is possible only for atomic and list types

Guess I'll have to keep trying.

Zhou H
  • 11
  • 1
  • Absolutely. And hopefully the package gets some updates soon. In the meantime, you can click the checkmark next to my answer to indicate that this question is resolved. – shayaa Aug 06 '16 at 07:18