akh22
akh22

Reputation: 701

ggplot2: the issue with overlay convex clusters by geom_polygon

I'd like to crate a plot overlaid with convex clusters and group (V1) color based on this data;

 str(stackoverflow)
 Classes ‘data.table’ and 'data.frame': 174 obs. of  4 variables:
 $ ID   : Factor w/ 277 levels "1001","1021",..: 1 2 4 5 6 7 8 9 10 11 ...
 $ UMAP1: num  -1.1313 -0.8176 0.1355 -0.0957 0.0724 ...
 $ UMAP2: num  0.219 0.48 -1.378 -0.95 -1.229 ...
 $ V1   : Factor w/ 3 levels "0","1","2": 3 1 1 1 1 1 1 1 1 1 ...

I computed a K-means cluster as follows;

km<-eclust(lipid.b.kmeans[,2:3],"kmeans", k=5, nboot = 2)

and a resulting km is ;

    km
K-means clustering with 5 clusters of sizes 38, 15, 18, 42, 61

Cluster means:
       UMAP1     UMAP2
1 -5.3988979 -1.585529
2 -0.4963504  0.470514
3  4.9895693  3.208727
4  1.6177653  1.461844
5  0.8990981 -1.081347

Clustering vector:
  [1] 2 2 5 5 5 5 5 5 5 5 1 1 1 1 1 5 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 3 1 1 1 4 1 4 1 1 4 1 1 1 1 4 3 4 4 4 4 4 4 4 4 3 4 4 3 4 4 4
 [72] 4 3 4 4 4 4 4 3 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 3 3 4 3 3 4 3 3 3 3 5 3 2 4 3 3 2 2 2 4 2 5 5 5 2 5 5 5 2 5 5 5 2 5 5 5 5 5 5 5 5 5 2 5 5 5
[143] 5 5 5 5 5 5 5 5 5 5 5 5 5 2 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 2 5

Within cluster sum of squares by cluster:
[1] 13.897357  2.224761  2.208410 16.884947 59.421921
 (between_SS / total_SS =  95.8 %)

Then I generated a convex date;

k<-fviz_cluster(km, data = stackoverflow[, 2:3], repel = T, ellipse.type = "convex") 
d<-k$data    
convex.data<-d %>% group_by(cluster) %>% slice(chull(x,y))

which is ;

str(convex.data)
Classes ‘grouped_df’, ‘tbl_df’, ‘tbl’ and 'data.frame': 46 obs. of  4 variables:
 $ name   : Factor w/ 174 levels "1","10","100",..: 46 118 101 116 108 119 123 30 1 99 ...
 $ x      : num  -1.54 -1.87 -1.89 -1.7 -1.67 ...
 $ y      : num  -1.36 -1.362 -1.089 -0.592 -0.56 ...
 $ cluster: Factor w/ 5 levels "1","2","3","4",..: 1 1 1 1 1 1 1 2 2 2 ...
 - attr(*, "groups")=Classes ‘tbl_df’, ‘tbl’ and 'data.frame':  5 obs. of  2 variables:
  ..$ cluster: Factor w/ 5 levels "1","2","3","4",..: 1 2 3 4 5
  ..$ .rows  :List of 5
  .. ..$ : int  1 2 3 4 5 6 7
  .. ..$ : int  8 9 10 11 12 13 14
  .. ..$ : int  15 16 17 18 19 20 21
  .. ..$ : int  22 23 24 25 26 27 28 29 30 31
  .. ..$ : int  32 33 34 35 36 37 38 39 40 41 ...
  ..- attr(*, ".drop")= logi TRUE

when I plot these by using ggplot2 by using;

ggplot(convex.data, aes(x,y))+geom_point(data=stackoverflow, aes(x=UMAP1, y=UMAP2, color= V1))+geom_polygon(data=convex.data, alpha=0.5, aes(fill=cluster,linetype=cluster))

I get this graph enter image description here

X and y scales of the polygon convex cluster image is smaller than image by geom_point. I used expand_limits to correct scale differences but did not work at all. At this point, I would really appreciate any suggestions or pointers to fix this issue.

Upvotes: 1

Views: 582

Answers (2)

akh22
akh22

Reputation: 701

I sort of figured this out by using stat_chull from ggscatter (ggpubr) as follows;

ggscatter(na.omit(stackoverflow), "UMAP1", "UMAP2", color = "V1")+stat_chull(aes(color=cluster, fill=cluster), alpha=0.1, geom = "polygon", na.rm = T)

This gave me a following plot that I wanted.

enter image description here

There is also a package, ggConvexHull ("cmartin/ggConvexHull") that works.

Upvotes: 0

s__
s__

Reputation: 9495

Maybe you can decide to use ggalt::geom_encircle() to simplify your work, here an example with the iris dataset:

set.seed(1234)
# using only two variables
model <- kmeans(iris[,1:2],3)
# new dataset with clusters as factors
iris1 <- data.frame(iris[,1:2], clust = as.factor(model$cluster))

library(ggplot2)
library(ggalt)
ggplot(iris1, aes(x =Sepal.Length, y =Sepal.Width, color = clust)) + geom_point() +
  geom_encircle(aes(fill = clust), s_shape = 1, expand = 0,
                alpha = 0.2, color = "black", show.legend = FALSE)

enter image description here

Upvotes: 4

Related Questions