5

When I do a facet_grid in ggplotly() for a Shiny App, with a large number of faceting groups, the plot is messed up. However it works correctly outside Shiny.

How can I fix this?
I suspect it is linked to the Y scale but I couldn't find the solution.


Here's a reproducible example based on diamonds example from plotly.

Comparison of Shiny vs non Shiny outputs : Comparison of facet_grid outside and within Shiny

Code

Outside Shiny:

library(ggplot2)

data(diamonds, package = "ggplot2")

# new faceting group
  diamonds$rdmGroup <- as.factor(sample(LETTERS, dim(diamonds)[1], replace=TRUE))

# subset of diamonds   
  diamonds <- diamonds[sample(nrow(diamonds), 1000),]

ggplot(diamonds , aes_string(x = diamonds$x, y = diamonds$y, color = diamonds$x)) + 
      geom_point() + facet_grid(rdmGroup~.) +
      guides(color=FALSE) +
      labs(x = "X", y="Y") 


The same code in a Shiny App:

library(shiny)
library(plotly)
library(ggplot2)

data(diamonds, package = "ggplot2")

# new faceting group
  diamonds$rdmGroup <- as.factor(sample(LETTERS, dim(diamonds)[1], replace=TRUE))

# subset of diamonds   
  diamonds <- diamonds[sample(nrow(diamonds), 1000),]

ui <- fluidPage(
  headerPanel("Diamonds Explorer"),
  sidebarPanel(
    sliderInput('plotHeight', 'Height of plot (in pixels)', 
                min = 100, max = 2000, value = 1000) 
  ),
  mainPanel(
    plotlyOutput('trendPlot')
  )
)


server <- function(input, output) {

  output$trendPlot <- renderPlotly({ 
      p <- ggplot(diamonds, aes_string(x = diamonds$x, y =diamonds$y, color = diamonds$x)) + 
            geom_point()+ facet_grid(rdmGroup~., scales = "free_y") +
            labs(x = "X", y="Y")

      ggplotly(p) %>% 
            layout(height = input$plotHeight, autosize=TRUE)
  })
}
shinyApp(ui, server)

PS: I used aes_string() instead of aes() intentionally as I need it in my real app.

Jim
  • 65
  • 1
  • 5
  • I get lots of warnings when running your example. Have you tried installing the latest github release of ggplot2? "We recommend that you use the dev version of ggplot2 with `ggplotly()` Install it with: `devtools::install_github('hadley/ggplot2')`" – DataJack Sep 26 '17 at 10:48
  • I updated ggplot2 and warnings are gone. Thanks for the advice. It does not solve the pb though. – Jim Sep 26 '17 at 11:10

1 Answers1

2

The first thing to note is that the problem has nothing to do with Shiny but rather your use of ggplotly. The problem can be replicated with just:

library(ggplot2)
library(plotly)

data(diamonds, package = "ggplot2")

# new faceting group
  diamonds$rdmGroup <- as.factor(sample(LETTERS, dim(diamonds)[1], replace=TRUE))

# subset of diamonds   
  diamonds <- diamonds[sample(nrow(diamonds), 1000),]

p <- ggplot(diamonds , aes_string(x = diamonds$x, y = diamonds$y, color = diamonds$x)) + 
      geom_point() + facet_grid(rdmGroup~.)

ggplotly(p)

though you will need something to view the output in, which may well be shiny.

In answer to your question, the problem seems to be that you cannot have more than 25 facets. If you remove any single group from rdmGroup then the plotly output works fine e.g.

diamonds <- subset(diamonds, rdmGroup != "Q")

To update your shiny example:

library(shiny)
library(plotly)
library(ggplot2)

data(diamonds, package = "ggplot2")

# new faceting group
diamonds$rdmGroup <- as.factor(sample(LETTERS, dim(diamonds)[1], replace=TRUE))

# subset of diamonds   
diamonds <- diamonds[sample(nrow(diamonds), 1000),]
diamonds <- subset(diamonds, rdmGroup != "Q")

ui <- fluidPage(
  headerPanel("Diamonds Explorer"),
  sidebarPanel(
    sliderInput('plotHeight', 'Height of plot (in pixels)', 
                min = 100, max = 2000, value = 1000) 
  ),
  mainPanel(
    plotlyOutput('trendPlot')
  )
)


server <- function(input, output) {

  output$trendPlot <- renderPlotly({ 
    p <- ggplot(diamonds, aes_string(x = diamonds$x, y =diamonds$y, color = diamonds$x)) + 
      geom_point()+ facet_grid(rdmGroup~., scales = "free_y") +
      labs(x = "X", y="Y")

    ggplotly(p) %>% 
      layout(height = input$plotHeight, autosize=TRUE)
  })
}
shinyApp(ui, server)

provides the following output: output

A workaround could be to simply have more than one plot, splitting the dataset into groups of 25.

EDIT: I did some more research and the plot stops displaying as expected when the panel margins are too large to allow all of the plots to display. You can display all 26 by reducing the panel.spacing.y but this will only go so far depending on how many rows you need:

p <- ggplot(diamonds, aes_string(x = diamonds$x, y =diamonds$y, color = diamonds$x)) + 
  geom_point()+ facet_grid(rdmGroup~., scales = "free_y") +
  labs(x = "X", y="Y") + theme(panel.spacing.y = unit(0.2, "lines"))
Eumenedies
  • 1,618
  • 9
  • 13
  • Ok thanks. I was not aware of the limitation in the number of facets. I splitted the dataset by levels of groups and produced in a loop as many plots as the number of groups. – Jim Sep 26 '17 at 14:09