簡體   English   中英

在 Shiny 中將縮放添加到密度 Plot

[英]Adding Zoom to a Density Plot in Shiny

我希望能夠在 shiny 中以密度 plot 放大 vlines。 我將 iris 數據集用於可重現的目的。 vlines 標有行名稱。

在我的實際數據集中,我有許多彼此非常接近的 vline。 它們非常接近,以至於我經常無法區分行號標簽。 我想找到一種放大 vline 標簽的方法。 我曾嘗試使用刷子,但這不起作用。

library(tidyverse)
library(cluster)
library(shiny)

ui <- fluidPage({
  pageWithSidebar(
    headerPanel('Iris k-means clustering'),
    sidebarPanel(
      numericInput('clusters', 'Cluster count', 3, min = 1, max = 9)
    ),
    mainPanel(
      plotOutput('plot1', 
                 dblclick = 'plot1_dblclick',
                 brush = brushOpts(
                   id = 'plot1_brush',
                   resetOnNew = TRUE
                 ))
    )
  )
})


server <- function(input, output){
  
  ClusterData <- reactive({
    iris[,1:4]
  })
  
  # need to keep row numbers for outlier labels
  ClusterData2 <- reactive({
    ClusterData2 <- data.frame(ClusterData())
    
    row.names(ClusterData2) <- 1:nrow(ClusterData2)
    
    return(ClusterData2)
  })
  
  
  # scale the iris data
  ScaledData <- reactive({
    scale(ClusterData2())
  })
  
  # kmeans clustering
  final <- reactive({
    kmeans(ScaledData(), input$clusters, nstart = 25)
  })
  
  # find centers
  states.centers <- reactive({
    final()$centers[final()$cluster, ]
  })
  
  # find outliers
  distances <- reactive({
    sqrt(rowSums((ScaledData() - states.centers())^2))
  })
  
  # bind distances back to data
  outliers <- reactive({
    cbind(ClusterData(), Distance = distances())
  })
  
  # bind cluster number to data
  clusterMember <- reactive({
    cbind(outliers(), clusterNum = final()$cluster)
  })
  
  # turn into data frame
  clusterMember2 <- reactive({
    as.data.frame(clusterMember())
  })
  
  # find points that are their own cluster
  dist0 <- reactive({
    clusterMember() %>%
      filter(distances() == 0)
  })
  
  # arrange distances largest to smallest
  distArrange <- reactive({
    clusterMember() %>%
      arrange(desc(Distance))
  })
  
  # find top 5 outliers
  filtTop5 <- reactive({
    distArrange()[1:5,]
  })
  
  # bind outliers and single clusters together
  AllOutliers <- reactive({
    rbind(filtTop5(), dist0())
    
  })
  

  ########## output plot
  output$plot1 <- renderPlot({
    ClusterData() %>%
      ggplot(aes(x = Petal.Length)) +
      geom_density(fill = "blue", alpha = 0.4) +
      geom_vline(xintercept = AllOutliers()$Petal.Length) +  
      annotate("text", x = AllOutliers()$Petal.Length, 
               y = 0,
               label = rownames(AllOutliers()),
               hjust = 0.5,
               vjust = -1)
  
  })
  
  ######### zoom brush
  observeEvent(input$plot1_dblclick, {
    brush <- input$plot1_brush
    if (!is.null(brush)) {
      ranges$x <- c(brush$xmin, brush$xmax)
      ranges$y <- c(brush$ymin, brush$ymax)
    } else {
      ranges$x <- NULL
      ranges$y <- NULL
    }
  })
  
  
}

shinyApp(ui, server)

我沒有投資於上述方法。 歡迎大家提出意見。

謝謝你。

我建議您嘗試plotly package。

從您的問題修改代碼:

library(tidyverse)
library(cluster)
library(shiny)
library(plotly)

ui <- fluidPage({
    pageWithSidebar(
        headerPanel('Iris k-means clustering'),
        sidebarPanel(
            numericInput('clusters', 'Cluster count', 3, min = 1, max = 9)
        ),
        mainPanel(
            plotlyOutput('plot1')
        )
    )
})


server <- function(input, output){
    
    ClusterData <- reactive({
        iris[,1:4]
    })
    
    # need to keep row numbers for outlier labels
    ClusterData2 <- reactive({
        ClusterData2 <- data.frame(ClusterData())
        
        row.names(ClusterData2) <- 1:nrow(ClusterData2)
        
        return(ClusterData2)
    })
    
    
    # scale the iris data
    ScaledData <- reactive({
        scale(ClusterData2())
    })
    
    # kmeans clustering
    final <- reactive({
        kmeans(ScaledData(), input$clusters, nstart = 25)
    })
    
    # find centers
    states.centers <- reactive({
        final()$centers[final()$cluster, ]
    })
    
    # find outliers
    distances <- reactive({
        sqrt(rowSums((ScaledData() - states.centers())^2))
    })
    
    # bind distances back to data
    outliers <- reactive({
        cbind(ClusterData(), Distance = distances())
    })
    
    # bind cluster number to data
    clusterMember <- reactive({
        cbind(outliers(), clusterNum = final()$cluster)
    })
    
    # turn into data frame
    clusterMember2 <- reactive({
        as.data.frame(clusterMember())
    })
    
    # find points that are their own cluster
    dist0 <- reactive({
        clusterMember() %>%
            filter(distances() == 0)
    })
    
    # arrange distances largest to smallest
    distArrange <- reactive({
        clusterMember() %>%
            arrange(desc(Distance))
    })
    
    # find top 5 outliers
    filtTop5 <- reactive({
        distArrange()[1:5,]
    })
    
    # bind outliers and single clusters together
    AllOutliers <- reactive({
        rbind(filtTop5(), dist0())
        
    })
    
    
    ########## output plot
    output$plot1 <- renderPlotly({
        plot1 <- ClusterData() %>%
            ggplot(aes(x = Petal.Length)) +
            geom_density(fill = "#6495ed", alpha = 0.3) +
            geom_vline(xintercept = AllOutliers()$Petal.Length, size = 0.5, colour = "#013220") +  
            annotate("text", x = AllOutliers()$Petal.Length, 
                     y = 0,
                     label = rownames(AllOutliers()),
                     colour = "#d4240b", 
                     size = 4)
        
        ggplotly(plot1)
    })
    
}

shinyApp(ui, server)

Output(用簇數縮放 = 9):

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM