ggplotly在散点图中闪亮的生产线

时间:2016-05-12 15:53:32

标签: r plot ggplot2 shiny plotly

在下面的代码中,情节的变化取决于"所有打字员"是否被选中。当它被选中时,应用程序看起来像这样,带有趋势线的散点图: enter image description here

但是,当取消选中该复选框时,图表看起来像这样,在点之间添加线条。应该注意,这是趋势线。当有更多的点时,它们之间有一条线: enter image description here

这是ggplotly中的错误吗?或者这是我的代码的问题?我在下面提供了一个最小的例子

library(tidyr)
library(dplyr)
library(reshape)
library(shiny)
library(plotly)
library(ggplot2)

df <- as.data.frame(list("UserID"=c(1,1,1,1,2,2,2,2), 
                          "QuestionID"=c(4,4,5,5,4,4,6,6),
                          "KeystrokeRate"=c(8,4,6,15,8,6,7,8),
                          "cumul.ans.keystroke"=c(3,7,4,5,11,14,3,9),
                          "Relative.Time.Progress"=c(0.1,1.0,0.4,1.0,0.8,1.0,0.8,1.0)
                    ))

trendLineOptions = c("All Selected User's Answers"="allThisUser", 
                     "All Typists"="allTypists"#, 
                    )

ui <- (fluidPage(
  sidebarLayout(
    sidebarPanel(
      selectInput("userInput","Select User", sort(unique(df$UserID)),
                  selected = sort(unique(df$UserID))[1]),
      uiOutput("answerOutput"),
      checkboxGroupInput("trendsInput", "Add Trend Lines",
                         choices=trendLineOptions,
                         selected="allTypists")#,
    ),

    mainPanel(
      plotlyOutput("mainPlot")#,
    )
  )
))

server <- function(input, output, session) {

  # filter only based on selected user
  filteredForUser <- reactive({
    try(
      df %>%
        filter(
          UserID == input$userInput
        ), silent=T)
  })

  # filter for both user and answer
  filteredFull <- reactive({
    try (
      df %>% 
        filter(
          UserID == input$userInput,
          QuestionID == input$answerInput
        ), silent=T)
  })

  # filter answer choices based on user
  output$answerOutput <- renderUI({
    df.u <- filteredForUser()
    if(!is.null(df)) {
      selectInput("answerInput", "Select A Typing Session",
                  sort(unique(df.u$QuestionID)))
    }
  })

  output$mainPlot <- renderPlotly({

    # add trend line based on this user's data
    addUserTrendLine <- reactive({
      if (class(filteredForUser()) == "try-error" ||
          class(filteredFull()) == "try-error") {
        return(geom_blank())
      }
      if ("allThisUser" %in% input$trendsInput) {
        g <- geom_smooth(data=filteredFull(), inherit.aes=F, 
                         aes(x=Relative.Time.Progress,y=cumul.ans.keystroke), 
                         method='lm')
      } else {
        g <- geom_blank()
      }
      return (g)
    })

    # add trend line based on all data
    addAllUsersTrendLine <- reactive({
      if (class(filteredForUser()) == "try-error" ||
          class(filteredFull()) == "try-error") {
        return(geom_blank())
      }
      if ("allTypists" %in% input$trendsInput) {
        g <- geom_smooth(data=df, inherit.aes=F, 
                         aes(x=Relative.Time.Progress,y=cumul.ans.keystroke), 
                         method='lm')
      } else {
        g <- geom_blank(inherit.aes=F)
      }
      return (g)
    })

    if (class(filteredForUser()) == "try-error" ||
        class(filteredFull()) == "try-error") {
      return(geom_blank())
    } else {
      # plot scatter points and add trend lines
      gplot <- ggplot(data=filteredFull(), 
                      aes(x=Relative.Time.Progress,y=cumul.ans.keystroke)) + 
        geom_point(aes(size=KeystrokeRate,colour=KeystrokeRate)) +
        addUserTrendLine() +
        addAllUsersTrendLine()
      g <- ggplotly(p=gplot, source="main")
    }
  })

}

shinyApp(ui, server)

1 个答案:

答案 0 :(得分:3)

毫无疑问,这是一个错误。这是一个最小的例子,它指出了潜在的问题:

gplot <- ggplot(data = data.frame(a = 1:2, b = 1:2), aes(x = a, y = b)) + geom_point()

ggplotly(p=gplot, source="main")
ggplotly(p=gplot + geom_blank(), source="main")
ggplotly(p=gplot + geom_blank() + geom_blank(), source="main")

如果您向阴谋项目提交错误报告,我认为这样会很好。

关于您的闪亮应用,我建议将addAllUsersTrendLineaddUserTrendLine合并为一个reactive或插入支票geom_blank