Reputation: 701
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))
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
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.
There is also a package, ggConvexHull ("cmartin/ggConvexHull") that works.
Upvotes: 0
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)
Upvotes: 4