Search code examples
rggplot2plotly

Getting the name of the point while hovering it in R


Important note below

If you want to try it, here's the dataframe: google drive link to the csv file

I finished a simple clustering algorithm with Kmeans and I was ploting it like so:

library(factoextra) #for fviz_cluster()
library(plotly) #for ggplotly()
library(stats) #for kmeans()

k <- kmeans(df, centers = 4, nstart = 50)
p <- fviz_cluster(k, data=df, palette = "Set2", ggtheme = theme_minimal(), geom = "point")

Resulting on this plot:

enter image description here

I would like to be able to hover over the points for them to give me their name on the dataframe so I tried countless different ways to call this function (changing the parameters I mean):

ggplotly(p, tooltip = "name")

However, hovering the plot in this case only gives info about the cluster (1, 2, 3 or 4) and not the names of the points.

Additionally, I tried something that actually kinda works, but you'll see why not. If instead I did the original plot without specifying the geom = "point", so like this:

p <- fviz_cluster(k4, data=df_cluster,palette = "Set2", ggtheme = theme_minimal())
ggplotly(p, tooltip = "name")

Hovering actually works properly but the names of each point are also shown at all times resulting in something horrible:

enter image description here

Again, here, overing a specific point does actually show a pop-up with it's name but I would like that without having all the others constantly shown.

Any ideas? Thank you in advance!

Note:

There's this same question (answered) here: other question but in this case, instead of being for scatterplot, it's for a ploty tree. I tried adjusting that solution to my context but, even thought there was progress, I didn't manage to crack it.


Solution

  • There is surely a simpler way to do this, but here is an RShiny solution.

    First here is the ui.R section. In case you are unfamiliar with shiny you need to save this in a folder as ui.R.

    library(shiny)
    library(shinythemes)
    library(DT)
    library(factoextra) #for fviz_cluster()
    library(plotly) #for ggplotly()
    library(stats) #for kmeans()
    
    fluidPage(shinythemes::themeSelector(),
              
              sidebarLayout(
                sidebarPanel(
                  fileInput("files", "Choose File", multiple = FALSE, 
                            accept = c(".csv")
                  )),
                
                
                mainPanel(plotOutput("plot", click = "plot1_click", height = "600px"), 
                          verbatimTextOutput("click_info"), DTOutput("table")),
                
                
              )
              
    )
    
    

    Next, here is the server.R code. Save this in the same folder.

    library(shiny)
    library(shinythemes)
    library(DT)
    library(factoextra) #for fviz_cluster()
    library(plotly) #for ggplotly()
    library(stats) #for kmeans()
    
    
    function(input, output, session) {
      
      
      #Read in the data
      df <- reactive({
        
        req(input$files)
        
        data.frame(fread(input$files$datapath, 
              sep = ","))
      })
      
      df_1 <- reactive({
        
        samp <- df()
        samp2 <- samp[,-1]
        rownames(samp2) <- samp[,1]
        
        samp2
      })
      
    
      k <- reactive({
        kmeans(df_1(), centers = 4, nstart = 50)
      })
        
      p <- reactive({
        fviz_cluster(k(), data=df_1(), palette = "Set2", ggtheme = theme_minimal(), geom = "point")
        })
      
      
      output$table <- renderDT({
        req(input$files)
        
        p()[[1]]
      })
      
      
      output$plot <- renderPlot({
        p()
        
      })
      
      
      
      output$click_info <- renderPrint({
        
        Temp <- p()[[1]]
        
        names(Temp)[names(Temp) == "x"] <-"x"
        names(Temp)[names(Temp) == "y"] <-"y"
        
        Temp <- Temp[, c("x", "y")]
        
        
        nearPoints(Temp, input$plot1_click)
        
      })
      
      
    }
    

    Make sure you have all the packages listed installed. Next open both of these files in R Studio and press the Run App button on the top right. enter image description here

    This shiny app will open. There is a button for you to upload your data file. Pick your .csv file. The plot you show above should automatically appear. You can click on any of the points and the information for that point will be displayed in the box below.

    Shiny app