Lucca Ramalho
Lucca Ramalho

Reputation: 593

How to switch between geom_line and geom_bar visualization in ggplot2 in Shiny - R

I want the user to choose whether they want to see a geom_line or a geom_bar on the graph.

What should be the best way to do it, using a checkboxGroupInput?

Let's say I have this plot with geom_line:

ggplot(regiao, aes(x=Ano,fill=Regiao, color=Regiao))+
    geom_line(stat='count')

and this one with geom_bar:

ggplot(regiao, aes(x=Ano,fill=Regiao, color=Regiao))+
    geom_bar()+
    stat_count()

I'd like to know how to set reactively the arguments for the ggplot.

I've searched everywhere but could only find reactive functions for values, not arguments, like this: ggplot2 with reactive Geom lines

I guess it should look like this:

ggplot(regiao, aes(x=Ano,fill=Regiao,color=Regiao))+
if (input$checkbox == "bars") {
 + geom_bar()+
stat_count()
}
if (input$checkbox=="lines") {
+geom_line(stat='count')
}

Upvotes: 2

Views: 601

Answers (2)

camille
camille

Reputation: 16862

You can save ggplot objects to a variable and build onto it however you need. Outside of a Shiny context, you could do this by referring to a variable, or encapsulating the task of adding onto a ggplot in a function. Inside a Shiny context, you can decide what to add to the object based on a user input.

For example, in a plain R context:

library(ggplot2)

set.seed(123)
df <- data.frame(
  month = 1:10,
  value = runif(10)
)

Create the base ggplot object. As an example, I also specified a y scale, because the ggplot elements like geoms and scales don't have to be added in any kind of order. You might have some specification like a scale that holds regardless of the geom type.

plot_base <- ggplot(df, aes(x = month, y = value)) +
  scale_y_continuous(labels = scales::percent)

Then add a geom based on what type of plot. In a Shiny app, this would instead be input$plot_type, and take the value of a pair of radio buttons or some other input. That decision-making would go inside your render function, such as renderPlot.

plot_type <- "Line"

if(plot_type == "Line") {
  p <- plot_base +
    geom_line()
} else {
  p <- plot_base +
    geom_col()
}
p

Same logic applies with a bar/column. You just wouldn't have to run through the if/else again—it would rerun reactively when the user changes the input.

plot_type <- "Bar"

if(plot_type == "Line") {
  p <- plot_base +
    geom_line()
} else {
  p <- plot_base +
    geom_col()
}
p

Created on 2018-10-17 by the reprex package (v0.2.1)

Upvotes: 2

Jordo82
Jordo82

Reputation: 816

Could you make both plots and then use the checkbox as a condition to determine what gets output?

output$myPlot <- renderPlot(ifelse(input$checkbox == "bars", myBarPlot, myLinePlot))

Upvotes: 0

Related Questions