Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Colour changing between plots originating from the same hclust object, needs to be uniform for user experience

Tags:

r

ggplot2

I'm trying to create a clusting evaluation tool. via 3 plot. but the colors are not consistaint. so one cluster might be blue in one plot but yelow in the otherone. not user friendly.

The function bellow can be provided any Hclust object and it will generate 3 plots. a dendrogram, cluster plot and a silhouette plot. The colours are consistent with the last two but the dendrogram colours the differently. I think this is do the hieratical nature of this plot. And so the fist to split of gains the first colour. But I’m not sure. Because the all have the same object with the same cluster labels (1, 2 etc). this miscolouring is really bugging me and I what to fix it. If you know why this happens or have a solution I’m all ears. The library used is factoextra

Also this is my first post. So if anything is unclear or whatever pleas also tell me.

library(factoextra)

# clustermodel = hclust object
# tot_clusters = the number of clusters (same as used as argument in hclust function)
# plots is an temp env to save the plots (function only returns one item so this is a work around) 
# the plots wil later be plotted by calling { plot(plots$dend) }  *example*
Cluster_visualisation <-  function(cluster_model, tot_clusters, plots) {

plots$dend <- fviz_dend(cluster_model, ggtheme = theme_minimal(),
          show_labels = FALSE, main = paste("Dendrogram", tot_clusters, "clusters" ))

plots$sil <- fviz_silhouette(cluster_model, print.summary = F, main= paste("silhouette plot of", tot_clusters, "clusters"), ggtheme = theme_minimal())

plots$clust <-fviz_cluster(cluster_model, ellipse.type = "convex", ggtheme = theme_minimal(),
             labelsize = 0, main= paste("Cluster plot of", tot_clusters ,"clusters"))
like image 502
Ketosaurus Avatar asked Dec 14 '25 05:12

Ketosaurus


1 Answers

Here is a solution to match the branch colours of the dendrogram created by fviz_dend. Essentially, you need to extract the dendrogram-order from the ggplot object, and then use it to determine the levels for fviz_silhouette, fviz_clust or any other plot you may want to do.

library(factoextra)
library(RColorBrewer)
library(cluster)
library(cowplot)

## generate data
iris <- datasets::iris

## perform hierarchical clustering 
d_iris <- dist(iris)
hc_iris <- hclust(d_iris, method = "complete")

## cut tree to three clusters
k = 3
clust_iris <- cutree(hc_iris,k=k)

## pick colour
cols = brewer.pal(n=k, "Set2")

## plot dendrogram
plot_dend =
fviz_dend(hc_iris, k_colors = cols, k=k) + theme_cowplot()

## create silhouette data
sil_data = as.numeric(clust_iris)
names(sil_data) = rownames(iris)
sil_iris = silhouette(sil_data, d_iris)

## extract dendrogram from ggplot object and create named colour vector
dend = attributes(plot_dend)$dendrogram
tree_order <- order.dendrogram(dend)
clust_iris = factor(clust_iris, levels = unique(clust_iris[tree_order]))
names(cols) = unique(clust_iris[tree_order])

## plot silhouettes
plot_silhouette =
fviz_silhouette(sil_iris, print.summary = F) + 
  scale_colour_manual(values = cols) +
  scale_fill_manual(values = cols) + 
  theme_cowplot()

## plot clusters 
plot_cluster =
fviz_cluster(list(data = d_iris, cluster = clust_iris)) + 
  scale_colour_manual(values = cols) +
  scale_fill_manual(values = cols) + 
  theme_cowplot()

## show as grid
plot_grid(plot_dend, plot_silhouette, plot_cluster, ncol=3)

enter image description here

like image 114
mluerig Avatar answered Dec 16 '25 22:12

mluerig



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!