Home > Back-end >  ggbiplot(): How to change the colour of the arrows and text using a function for a PCA biplot
ggbiplot(): How to change the colour of the arrows and text using a function for a PCA biplot

Time:09-21

Issue

I have used the function ggbiplot() to produce a PCA biplot for multivariate data (see diagram 1 - below)

I found this enter image description here

Diagram 2 enter image description here

CodePudding user response:

Unfortunately, despite the effort you put in to creating a dummy data set, the code you made to reproduce it contains errors. However, this seems a bit tangential to what you are asking here, which is to change the colors and weights of segments and text in the image produced by ggbiplot. To do this, we can simply use the example that comes with the package:

library(ggbiplot)

data(wine)
wine.pca <- prcomp(wine, scale. = TRUE)

p <- ggbiplot(wine.pca, obs.scale = 1, var.scale = 1, 
         groups = wine.class, ellipse = TRUE, circle = TRUE)

p

enter image description here

The options for styling the plot within the function itself are somewhat limited, but since it produces a ggplot object, we can re-specify the necessary layers. The following code should work on any object output from ggbiplot. First we find the geom segment and geom text layers:

seg <- which(sapply(p$layers, function(x) class(x$geom)[1] == 'GeomSegment'))
txt <- which(sapply(p$layers, function(x) class(x$geom)[1] == 'GeomText'))

We can change the colour and width of the segments by doing

p$layers[[seg]]$aes_params$colour <- 'black'
p$layers[[seg]]$aes_params$size <- 1

To change the labels to have a gray background, we need to overwrite the geom_text layer with a geom_label layer:

p$layers[[txt]] <- geom_label(aes(x = xvar, y = yvar, label = varname,
                                  angle = angle, hjust = hjust), 
                              label.size = NA,
                              data = p$layers[[txt]]$data, 
                              fill = '#dddddd80')

Now we can draw the plot with a clean modern theme:

p   theme_minimal()

enter image description here

CodePudding user response:

Thank you Allan Cameron for providing this helpful answer

PCA_plot<-ggbiplot(PCA, ellipse=TRUE, circle=TRUE, varname.adjust = 2.5, groups=Box_Cox_Stan_Dataframe$Country, var.scale = 1)  
                  ggtitle("PCA of Acoustic Parameters")  
                  theme(plot.title = element_text(hjust = 0.5))  
                  theme_minimal()  
                  theme(panel.background = element_blank(), 
                  panel.grid.major = element_blank(), 
                  panel.grid.minor = element_blank(),
                  panel.border = element_blank())   
                  theme(axis.line.x = element_line(color="black", size = 0.8),
                  axis.line.y = element_line(color="black", size = 0.8))

#Place the arrows in the forefront of the points
PCA_plot$layers <- c(PCA_plot$layers, PCA_plot$layers[[2]])

#The options for styling the plot within the function itself are somewhat limited, but since it produces a 
#ggplot object, we can re-specify the necessary layers. The following code should work on any object 
#output from ggbiplot. First we find the geom segment and geom text layers:

seg <- which(sapply(PCA_plot$layers, function(x) class(x$geom)[1] == 'GeomSegment'))
txt <- which(sapply(PCA_plot$layers, function(x) class(x$geom)[1] == 'GeomText'))

#We can change the colour and width of the segments by doing
PCA_plot$layers[[seg[1]]]$aes_params$colour <- 'black' 
PCA_plot$layers[[seg[2]]]$aes_params$colour <- 'black'

#Labels
# Extract loadings of the variables
PCAloadings <- data.frame(Variables = rownames(PCA$rotation), PCA$rotation)

#To change the labels to have a gray background, we need to overwrite the geom_text layer with a geom_label layer:
  PCA_plot$layers[[txt]] <- geom_label(aes(x = xvar, y = yvar, label = PCAloadings$Variables,
                                       angle = 0.45, hjust = 0.5, fontface = "bold"), 
                                       label.size = NA,
                                       data = PCA_plot$layers[[txt]]$data, 
                                       fill = '#dddddd80')
  
  PCA_plot

Output Figure

enter image description here

  • Related