4

In basic R you can add layers to the existing plot without creating a new one.

df <- data.frame(x = 1:10, y = runif(10))
plot(df, type = "l")
points(df, add = T)

The second line creates a plot and the third line adds points to the existing plot. In ggplot2:

my_plot <- ggplot(df, aes(x, y)) + geom_path()
my_plot
my_plot + geom_point()

The second line creates a plot and the third one creates another plot. Can I somehow add the points to the existing plot created by the second line? Is there something like add=TRUE in ggplot?

The reason I want this behaviour is that using ggplot2 in shiny causes blinks in its animations.

Rorschach
  • 31,301
  • 5
  • 78
  • 129
Mostafa Rezaei
  • 599
  • 5
  • 9
  • @nongkrong I want to plot the curve first, then have points added to it without creating a new plot. your answer is not a solution to my problem. – Mostafa Rezaei Aug 30 '15 at 22:39
  • 2
    not really, because ggplot2 does a lot of intermediate processing between the high-level layer command and the final plot output (re-computing scales, etc.) – baptiste Aug 30 '15 at 22:45

2 Answers2

3

Here is an idea. Keep the plot as a reactiveValue and have an observer to update the plot with user inputs. Then, have another observer to watch the plot data that will render the plot when the plot data changes. This way the long calculations happen before the plot data is changed, so the rendering of the plot should happen so quickly that there should be very little visible interrupt. Here is an example using the diamond dataset from ggplot2 which is large enough to be obviously slow when rendering paths.

shinyApp(
    shinyUI(
        fluidPage(
            sidebarLayout(
                sidebarPanel(
                    selectInput("x", "X", choices=names(diamonds)),
                    selectInput("y", "Y", choices=names(diamonds)),
                    checkboxInput("line", "Add line")
                ),
                mainPanel(
                    plotOutput("plot")
                )
            )
        )
    ),
    shinyServer(function(input, output, session) {
        data(diamonds)
        vals <- reactiveValues(pdata=ggplot())

        observe({
            input$x; input$y; input$line
            p <- ggplot(diamonds, aes_string(input$x, input$y)) + geom_point()
            if (input$line)
                p <- p + geom_line(aes(group=cut))
            vals$pdata <- p
        })

        observeEvent(vals$pdata,{ 
            output$plot <- renderPlot({
                isolate(vals$pdata)
            })
        })
        ## Compare to this version
        ## output$plot <- renderPlot({
        ##     vals$pdata
        ## })
    })
)
Rorschach
  • 31,301
  • 5
  • 78
  • 129
  • This is a bummer. Have the same problem. I want to create lots of lines in a loop and add each when created to the main existing plot. So, my only options seem to be to either stick with ‘plot’ (which works) or save all of the data for all of these lines and do the plot at the very end. Bummer. – Ernie Apr 10 '16 at 16:28
0

I have exactly the same problem, and I saw here using special css tag, it solved the problem, but actually it id not solve it for me. It might help you though!

I have just found out, however, that all what you need to do is to add this link of code in the ui chunck of code: tags$style(type="text/css", ".recalculating {opacity: 1.0;}")

Community
  • 1
  • 1
owise
  • 1,055
  • 16
  • 28