Reputation: 113
I am developing a shiny application which aims at comparing plots on the same graph and I want to use ggplot to be able to zoom in my graph.
The problem is the number of plots, which depends on the user selection. I want to plot the graphs with lines, here is what I have (working example) :
ui.R
shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
fluidRow(
#checkboxGroupInput
column((5),
checkboxGroupInput("model",
label = h3("Choix du modele"),
choices = c("1","2","3"),
selected = 8)
)
)
),
mainPanel
(
fluidRow(
column(width = 12, class = "well",
h4("Brush and double-click to zoom"),
plotOutput("plot1", height = 300,
dblclick = "plot1_dblclick",
brush = brushOpts(
id = "plot1_brush",
resetOnNew = TRUE
)
)
)
)
)
)
)
)
server.R
# Here is the server part of Shiny
library('shiny')
library(ggplot2)
library(reshape)
library(Cairo)
function(input, output) {
ranges <- reactiveValues(x = NULL, y = NULL)
output$plot1 <- renderPlot({
tsPlot <- seq(from = ISOdate(2012,01,01,0,0,0), to = ISOdate(2012,01,01,23,45,0), by =60*15)
measures <- runif(96)
dataPlot <- data.frame(tsPlot,measures)
list_models <- c("1","2","3")
if(length(input$model) > 0)
{
nb = 0
for(i in 1:length(list_models))
{
values <- runif(96)
dataPlot<- cbind(dataPlot,values)
}
}
dataPlot_melted <- melt(dataPlot,id="tsPlot")
ggplot() +
geom_line(data=dataPlot_melted,aes(tsPlot,value)) +
coord_cartesian(xlim = ranges$x, ylim = ranges$y)
})
# When a double-click happens, check if there's a brush on the plot.
# If so, zoom to the brush bounds; if not, reset the zoom.
observeEvent(input$plot1_dblclick, {
brush <- input$plot1_brush
if (!is.null(brush)) {
ranges$x <- c(brush$xmin, brush$xmax)
ranges$y <- c(brush$ymin, brush$ymax)
} else {
ranges$x <- NULL
ranges$y <- NULL
}
})
}
The problem is solved if I want to plot points. I just have to use geom_point. But if I want to point lines, all the values are put in the same plot.
Does anyone know the trick to get out of this situation ?
Thanks in advance :)
Upvotes: 1
Views: 1299
Reputation: 113
I found a solution. It's not really beautiful, but it works :
dataPlot <- data.frame(tsPlot,measures,rep("Measures",length(tsPlot)))
names(dataPlot) <- c("ts","value","name")
list_models <- c("1","2","3")
if(length(input$model) > 0)
{
nb = 0
for(i in 1:length(list_models))
{
values <- runif(96)
dataPlot2<- data.frame(dataPlot,values,rep(list_models[i],length(values)))
names(dataPlot2) <- c("ts","value","name")
dataPlot <- rbind(dataPlot,dataPlot2)
}
}
x <- ggplot(data=dataPlot, aes(x=time, y=value, group=name, colour=factor(name)))+
geom_line(size=.25)
The trick relies on "group=name" in ggplot. We have only one column of values, but we also have a column of labels (name), which splits up correctly the data.
Upvotes: 2