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

Jim*_*Jim 5 r shiny facet-grid ggplotly

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") 
Run Code Online (Sandbox Code Playgroud)


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)
Run Code Online (Sandbox Code Playgroud)

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

Eum*_*ies 2

首先要注意的是,问题与您的使用无关Shiny,而与您的使用有关ggplotly。这个问题可以通过以下方式复制:

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)
Run Code Online (Sandbox Code Playgroud)

尽管您需要一些东西来查看输出,这很可能是shiny.

在回答你的问题时,问题似乎是你不能有超过 25 个方面。如果您从中删除任何单个组,rdmGroupplotly输出可以正常工作,例如

diamonds <- subset(diamonds, rdmGroup != "Q")
Run Code Online (Sandbox Code Playgroud)

要更新你的闪亮示例:

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)
Run Code Online (Sandbox Code Playgroud)

提供以下输出: 输出

一种解决方法是简单地使用多个图,将数据集分成 25 个组。

编辑:我做了一些更多的研究,当面板边距太大而无法显示所有图时,图将按预期停止显示。您可以通过减少来显示所有 26 行,panel.spacing.y但这只能到此为止,具体取决于您需要的行数:

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"))
Run Code Online (Sandbox Code Playgroud)