rggplot2plotlyggpubr

Display p-values and R in Shiny Plotly graph without overlapping the values


I tried to display R and p-values annotations together in a scatter plot where color is differentiated based on species using plotly.

But the text overlapped with each other when it runs in Shiny.

How to adjust the position of the values?

scatter plot shown in shiny: enter image description here

ui <- fluidPage(
  
  plotlyOutput("plot")
)

server <- function(input, output) {
  
  output$plot <- renderPlotly({
    p <- ggplot(iris, aes(Sepal.Length, Petal.Length)) + list(
      geom_point(aes(color = Species)),
      ggpubr::stat_cor(aes(color = Species), method = "pearson", output.type= "text")
    )
    ggplotly(p) 
  })
  
  
}
shinyApp(ui, server)

simply uses plotly (also is what i expected in shiny):

enter image description here


Solution

  • Unfortunately I don't see any easy or perfect fix except for extending the plotly package to account for the specifics of ggpubr::stat_cor or a a refactoring of ggpubr::stat_cor to account for how plotly works.

    In short, the issue is that ggpubr::stat_cor uses vjust (Brrr) to shift the labels for the different groups. However, it seems that vjust has no effect in plotly and hence all labels are placed at their same y position. The same is also true for the hjust parameter. But I can't tell whether this is a bug in the plotly package or simply a missing feature in plotly.js.

    A possible fix would be to shift or nudge the x and y positions in ggplot2 using stage and after_stat. But I'm afraid that this is not a real robust fix and requires some fiddling to set the right amount of nudging.

    library(plotly)
    library(shiny)
    
    ui <- fluidPage(
      plotlyOutput("plot")
    )
    
    server <- function(input, output) {
      output$plot <- renderPlotly({
        p <- ggplot(iris, aes(Sepal.Length, Petal.Length)) +
          list(
            geom_point(aes(color = Species)),
            ggpubr::stat_cor(
              aes(
                x = stage(Sepal.Length, after_stat = min(x) + .5),
                y = stage(Petal.Length, after_stat = y + .5 * seq_along(y)),
                color = Species
              ),
              vjust = .5,
              method = "pearson", output.type = "text"
            )
          )
        ggplotly(p)
      })
    }
    
    shinyApp(ui, server)
    #> 
    #> Listening on http://127.0.0.1:5201