R Shiny:当使用renderPlotly时,图例会分裂

huangapple go评论60阅读模式
英文:

R Shiny: the legend splits when renderPlotly is used

问题

我注意到一个奇怪的现象,renderPlotly可以将相同变量的图例分开。

例如,当使用renderPlot()时,生成的图表如下所示:R Shiny:当使用renderPlotly时,图例会分裂
然而,如果我尝试将其转换为Plotly对象,它会变成这样:
R Shiny:当使用renderPlotly时,图例会分裂

有人知道发生了什么,以及如何解决这个问题吗?谢谢!

英文:

I noticed a strange phenomenon that renderPlotly can split the legend of the same variable.

For example, when renderPlot() is used, the produced graph looks like this:R Shiny:当使用renderPlotly时,图例会分裂
However, if I tried to convert it into a plotly object, it changed into this:
R Shiny:当使用renderPlotly时,图例会分裂

Does anyone know what is going on and how to fix this problem? Thank you!
ggplot version:

library(shiny)
library(plotly)

ColorblindnessFriendlyValues <- c("Same" = "#648FFF", "Alt" = "#FFB000")

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      sliderInput("crossloadings", "Number Crossloadings",
                  min = 1, max = 10, value = 5),
      sliderInput("group1", "Group 1",
                  min = 0, max = 1, value = 0.5),
      sliderInput("group2", "Group 2",
                  min = 0, max = 1, value = 0.5)
    ),
    mainPanel(
      plotlyOutput("plot") # Changed here
    )
  )
)

server <- function(input, output) {
  output$plot <- renderPlotly({
    number_crossloadings <- seq(1, input$crossloadings)
    group1 <- runif(input$crossloadings, min = 0, max = input$group1)
    group2 <- runif(input$crossloadings, min = 0, max = input$group2)

    results <- data.frame(number_crossloadings, group1, group2)

    plot <- ggplot(data=results, aes(x=number_crossloadings))+
      geom_line(aes(y=group1,
                    color="Same"))+
      geom_line(aes(y=group2,color="Alt"))+
      suppressWarnings(geom_point(aes(y=group1,
                                      color="Same",
                                      shape = "Same",
                                      text = paste0("# of cross Loadings: ", number_crossloadings,
                                                    "<br>SRMR: ", sprintf('%.3f', group1)))))+
      suppressWarnings(geom_point(aes(y=group2,
                                      color="Alt",
                                      shape = "Alt",
                                      text = paste0("# of cross Loadings: ", number_crossloadings,
                                                    "<br>SRMR: ", sprintf('%.3f', group2)))))+
      scale_color_manual(values = ColorblindnessFriendlyValues, labels = c("Same", "Alt")) +
      scale_shape_manual(values = c("Same" = 16, "Alt" = 17), labels = c("Same", "Alt")) +
      geom_abline(color="grey",slope=0, intercept=0.08) +
          labs(color = "Legend", shape = "Legend")  +
      ylim(NA,1)

      ggplotly(plot,tooltip = c("text"))

    })
}

shinyApp(ui, server)

Plotly version:

library(shiny)
library(plotly)

ColorblindnessFriendlyValues <- c("Same" = "#648FFF", "Alt" = "#FFB000")

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      sliderInput("crossloadings", "Number Crossloadings",
                  min = 1, max = 10, value = 5),
      sliderInput("group1", "Group 1",
                  min = 0, max = 1, value = 0.5),
      sliderInput("group2", "Group 2",
                  min = 0, max = 1, value = 0.5)
    ),
    mainPanel(
      plotOutput("plot")
    )
  )
)

server <- function(input, output) {
  output$plot <- renderPlot({
    number_crossloadings <- seq(1, input$crossloadings)
    group1 <- runif(input$crossloadings, min = 0, max = input$group1)
    group2 <- runif(input$crossloadings, min = 0, max = input$group2)

    results <- data.frame(number_crossloadings, group1, group2)

    plot <- ggplot(data=results, aes(x=number_crossloadings))+
      geom_line(aes(y=group1, color="Same"))+
      geom_line(aes(y=group2,color="Alt"))+
      suppressWarnings(geom_point(aes(y=group1,
                                      color="Same",
                                      shape = "Same",
                                      text = paste0("# of cross Loadings: ", number_crossloadings,
                                                    "<br>SRMR: ", sprintf('%.3f', group1)))))+
      suppressWarnings(geom_point(aes(y=group2,
                                      color="Alt",
                                      shape = "Alt",
                                      text = paste0("# of cross Loadings: ", number_crossloadings,
                                                    "<br>SRMR: ", sprintf('%.3f', group2)))))+
      scale_color_manual(values = ColorblindnessFriendlyValues, labels = c("Same", "Alt")) +
      scale_shape_manual(values = c("Same" = 16, "Alt" = 17), labels = c("Same", "Alt")) +
      geom_abline(color="grey",slope=0, intercept=0.08) +
      labs(color = "Legend", shape = "Legend")  +
      ylim(NA,1)

    plot
  })
}

shinyApp(ui, server)

答案1

得分: 1

Whenever the translation ggplot <-> plotly does not yield the results I want, I use plot_ly directly as it allows for finer control.

Having said that, you can generate a similar plot with plot_ly like this (N.B. I changed your data structure a bit to avoid some duplication):

output$plot <- renderPlotly({
   number_crossloadings <- seq(1, input$crossloadings)
   group1 <- runif(input$crossloadings, min = 0, max = input$group1)
   group2 <- runif(input$crossloadings, min = 0, max = input$group2)
   results <- data.frame(x = rep(number_crossloadings, 2),
                         y = c(group1, group2),
                         g = rep(c("Same", "Alt"), each = input$crossloadings))
   plot_ly(results, 
           x = ~ x, 
           y = ~ y, 
           colors = ColorblindnessFriendlyValues, 
           symbols = c("triangle-up",  "circle"))  %>%
      add_trace(type = "scatter", 
                mode = "lines", 
                showlegend = FALSE, 
                hoverinfo = "none",
                color = I("gray"), 
                x = range(results$x) + c(-1, 1) * .2, 
                y = c(.08, .08)) %>%
      add_trace(type = "scatter", 
                mode = "markers+lines", 
                color = ~ g, 
                symbol = ~ g, 
                marker = list(size = 8),
                hoverinfo = "text",
                text = ~ paste0("# of cross Loadings: ", number_crossloadings,
                                "<br>SRMR: ", sprintf("%.3f", y))) %>%
      layout(legend = list(title = list(text = "Legend")),
             xaxis = list(title = list(text = "number_crossloadings")),
             yaxis = list(title = list(text = "y")))
})

R Shiny:当使用renderPlotly时,图例会分裂

Abline

I used a separate trace for the abline, another option would be to add a shape to layout like this:

layout(
   #...
   shapes = list(
      list(
         type = "rect",
         x0 = 0,
         x1 = 1,
         xref = "paper",
         y0 = 0.08,
         y1 = 0.08,
         yref = "y",
         line = list(dash = "solid",
                     color = "grey"),
         layer = "below"
      )
   )
)
英文:

Whenever the translation ggplot <-> plotly does not yield the results I want, I use plot_ly directly as it allows for finer control.

Having said that, you can generate a similar plot with plot_ly like this (N.B. I changed your data structure a bit to avoid some duplication):

output$plot &lt;- renderPlotly({
   number_crossloadings &lt;- seq(1, input$crossloadings)
   group1 &lt;- runif(input$crossloadings, min = 0, max = input$group1)
   group2 &lt;- runif(input$crossloadings, min = 0, max = input$group2)
   results &lt;- data.frame(x = rep(number_crossloadings, 2),
                         y = c(group1, group2),
                         g = rep(c(&quot;Same&quot;, &quot;Alt&quot;), each = input$crossloadings))
   plot_ly(results, 
           x = ~ x, 
           y = ~ y, 
           colors = ColorblindnessFriendlyValues, 
           symbols = c(&quot;triangle-up&quot;,  &quot;circle&quot;))  %&gt;% 
      add_trace(type = &quot;scatter&quot;, 
                mode = &quot;lines&quot;, 
                showlegend = FALSE, 
                hoverinfo = &quot;none&quot;,
                color = I(&quot;gray&quot;), 
                x = range(results$x) + c(-1, 1) * .2, 
                y = c(.08, .08)) %&gt;% 
      add_trace(type = &quot;scatter&quot;, 
                mode = &quot;markers+lines&quot;, 
                color = ~ g, 
                symbol = ~ g, 
                marker = list(size = 8),
                hoverinfo = &quot;text&quot;,
                text = ~ paste0(&quot;# of cross Loadings: &quot;, number_crossloadings,
                                &quot;&lt;br&gt;SRMR: &quot;, sprintf(&quot;%.3f&quot;, y))) %&gt;% 
      layout(legend = list(title = list(text = &quot;Legend&quot;)),
             xaxis = list(title = list(text = &quot;number_crossloadings&quot;)),
             yaxis = list(title = list(text = &quot;y&quot;))
})

R Shiny:当使用renderPlotly时,图例会分裂

Abline

I used a separate trace for the abline, another option would be to add a shape to layout like this:

layout(
   #...
   shapes = list(
      list(
         type = &quot;rect&quot;,
         x0 = 0,
         x1 = 1,
         xref = &quot;paper&quot;,
         y0 = 0.08,
         y1 = 0.08,
         yref = &quot;y&quot;,
         line = list(dash = &quot;solid&quot;,
                     color = &quot;grey&quot;),
         layer = &quot;below&quot;
      )
   )
)

huangapple
  • 本文由 发表于 2023年5月11日 08:44:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76223433.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定