Reputation: 193
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:
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:
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.
Upvotes: 2
Views: 487
Reputation: 71
Here's a simple approach.
Set geom = NULL
in the fviz_cluster
command to make a plot with empty clusters. Convert it to a plotly object, but save it for further manipulation: fig <- ggplotly(p)
.
Then add a layer with markers and hover info. This snippet assumes your df has columns named X
, Y
, and name
.
fig <- add_markers(fig, type = "scatter", data = df, inherit = FALSE,
x = ~X, y = ~Y, mode = "markers", text = name,
hoverinfo = text)
If your scatter markers don't match the clusters, set fviz_cluster(..., stand = FALSE)
. fviz standardizes your data by default, (potentially?) changing the scale.
Upvotes: 0
Reputation: 413
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.
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.
Upvotes: 2