PCA of Triadica sebifera leaf contours

The goals of this notebook are:
1. To perform PCA using the coefficients obtained by conventional normalization, oriented true EFD normalization and normalized EFD.
2. To compare PCA results across these three methods.

Setup & preprocessing


Attaching package: 'Momocs'
The following object is masked from 'package:stats':

    filter
source("R/geometry.R")
source("R/normalization.R")
source("R/pca_plot.R")
# color palette for colorblind-friendly visualization
palette("Okabe-Ito")
# set the data directory from environment variable (.Renviron)
data_dir <- Sys.getenv("PROJECT_DATA_DIR")

Load contours from the CSV files in the data/contour_triadica_sebifera/ directory.

file_paths_xy <- list.files(
  file.path(data_dir, "data/contour_triadica_sebifera/"),
  full.names = TRUE,
  pattern = "\\.csv$"
)
xy_list <- lapply(file_paths_xy, function(fp) {
  #cat("File:", fp, "\n")
  df <- read.csv(fp)
  df <- df[, c("x", "y")]
  df <- as.matrix(df)
  storage.mode(df) <- "double"
  # Ensure the contour is closed by checking if the first and last points are the same. If not, append the first point to the end of the matrix.
  if (!all(df[1, ] == df[nrow(df), ])) {
    df <- rbind(df, df[1, ])
  }
  return(df)
})

PCA using conventional normalization

PCA using normalized EFD coefficients (conventional method (Kuhl and Giardina 1982)).
Normalization is performed using Momocs (Bonhomme et al. 2014).

nb_h <- 5 # Number of harmonics
out <- Out(xy_list) # convert to Momocs Out object
ef_norm <- efourier(out, nb.h = nb_h, norm = TRUE, start = FALSE) # EFD with normalization
pca_norm <- PCA(ef_norm, center = TRUE, scale. = FALSE) # PCA with Momocs
pca_plot(pca_norm)

Save the plot as SVG file
save_dir <- "results"
dir.create(save_dir, showWarnings = FALSE, recursive = TRUE)
save_file_name <- "fig4d_pca_efd_normalized.svg"
save_file_path <- file.path(save_dir, save_file_name)
svg(
  save_file_path,
  bg = "transparent"
)
pca_plot(pca_norm)
dev.off()

True EFD normalization

PCA using coefficients obtained by true EFD normalization.
Normalization is performed using the efourier_true_norm() function implemented in this project (see R/normalization.R for details).

nb_h <- 5 # Number of harmonics
out <- Out(xy_list) # convert to Momocs Out object
# oriented true EFD normalization
ef_true_norm <- efourier_true_norm(
  out,
  nb_h = nb_h,
  x_sy = TRUE,
  y_sy = TRUE,
  skip_rotation = FALSE
)
pca_true_norm <- PCA(ef_true_norm, center = TRUE, scale. = FALSE) # PCA with Momocs
pca_plot(pca_true_norm)

Save the plot as SVG file
save_dir <- "results"
dir.create(save_dir, showWarnings = FALSE, recursive = TRUE)
save_file_name <- "fig4e_pca_true_efd_normalized.svg"
save_file_path <- file.path(save_dir, save_file_name)
svg(
  save_file_path,
  bg = "transparent"
)
pca_plot(pca_true_norm)
dev.off()

PCA using oriented true EFD normalization

Contours obtained from LeafContourEFD already have standardized starting points and rotation. Therefore, we apply only the x-axis symmetry correction step from true EFD normalization to implement oriented true EFD normalization.

Although the same results can be obtained from the Fourier coefficients exported by LeafContourEFD, we use Momocs here so we can easily visualize reconstructed contour changes associated with principal component score shifts.

In a future update, we plan to provide a workflow that does not depend on Momocs.

nb_h <- 5 # Number of harmonics
out <- Out(xy_list) # convert to Momocs Out object
# oriented true EFD normalization
ef_true_norm <- efourier_true_norm(
  out,
  nb_h = nb_h,
  x_sy = TRUE,
  y_sy = FALSE,
  skip_rotation = TRUE
)
pca_true_norm <- PCA(ef_true_norm, center = TRUE, scale. = FALSE) # PCA with Momocs
pca_plot(pca_true_norm)

Save the plot as SVG file
save_dir <- "results"
dir.create(save_dir, showWarnings = FALSE, recursive = TRUE)
save_file_name <- "fig4f_pca_oriented_true_efd_normalized.svg"
save_file_path <- file.path(save_dir, save_file_name)
svg(
  save_file_path,
  bg = "transparent"
)
pca_plot(pca_true_norm)
dev.off()

References