R: facet_wrap does not render correctly with ggplotly in Shiny app

江枫思渺然 提交于 2019-12-08 05:20:36

问题


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.


回答1:


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:

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"))


来源:https://stackoverflow.com/questions/46423671/r-facet-wrap-does-not-render-correctly-with-ggplotly-in-shiny-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!