library(terra)
library(ggplot2)
library(sf)
library(leaflet)
library(RColorBrewer)
library(googledrive)
library(dplyr)
Phenology of Mangroves
Fall 2024 GEO 511 Final Project
Contents
Introduction
Mangrove forests are salt-tolerant trees and shrubs that thrive in intertidal zones of tropical and subtropical regions (Vaiphasa et al. 2005). These ecosystems are highly valued as blue carbon reservoirs and natural coastal protection systems (Macreadie et al. 2021). Within mangrove ecosystems, different species display significant diversity in tree structures, growth strategies, and environmental adaptations. While mangroves are evergreen, remote sensing observations reveal that distinct species exhibit varying temporal patterns in the onset, persistence, and greenness of their growth stages.
This study aims to characterize the phenological patterns of three mangrove species: red mangrove (Rhizophora mangle), white mangrove (Avicennia germinans), and black mangrove (Laguncularia racemosa) in Everglades National Park, Florida. To be more specific, high-temporal-resolution remote sensing data from the Harmonized Landsat and Sentinel (HLS) dataset for 2023 will be used to extract Normalized Difference Vegetation Index (NDVI) values, enabling a detailed analysis of the phenological differences among these dominant species.
Materials and methods
To extract phenological information of three mangrove species from remote sensing-based observation, we need:
Materials
Harmonized Landsat and Sentinel (HLS) dataset
The HLS product integrates data from the Landsat 8 (or Landsat 9) and Sentinel-2A (or Sentinel-2B) satellites, producing a harmonized surface reflectance dataset with a 30-meter spatial resolution. Moreover, HLS includes a Quality Assurance (QA) band, which provides data quality filters and masks for clouds, cloud shadows, and water bodies. To generate time series NDVI from HLS dataset, red and near inf-red bands are collected.
Geographical location of mangrove samples
The geographical information of three mangrove species are collected from Project: The Vegetation of Everglades National Park: Final Report (Spatial Data) (Ruiz and Others 2021). 10 samples of each three mangrove species (red mangrove, white mangrove, and black mangrove) are extracted from this final report.
Normalized Difference Vegetation Index
NDVI is widely used to monitor vegetation health and phenological changes over time. The formula is:\[ \text{NDVI} = \frac{(NIR - RED)}{(NIR + RED)} \]
Harmonic Regression
Harmonic regression is a statistical technique that fits sine and cosine functions to data and is adept at identifying and modeling the cyclical variations inherent in time series with periodic patterns.\[ y_t = \beta_0 + \sum_{k=1}^{K} \left( \beta_{k} \cos\left(\frac{2\pi k t}{T}\right) + \gamma_{k} \sin\left(\frac{2\pi k t}{T}\right) \right) + \epsilon_t \]
Where:
- \(y_t\): The observed value at time \(t\).
- \(\beta_0\): The intercept or constant term in the model.
- \(\beta_k\): The coefficient for the cosine term corresponding to the \(k\)-th harmonic.
- \(\gamma_k\): The coefficient for the sine term corresponding to the \(k\)-th harmonic.
- \(T\): The period of the data (e.g., the number of days in a year if the data is annual).
- \(t\): The time point or index (often representing the day of the year, etc.).
- \(K\): The total number of harmonics (sinusoidal terms) included in the model, usually based on the periodicity of the data.
- \(\epsilon_t\): The error term at time \(t\), capturing the residual variability in the data that is not explained by the harmonic components.
Methods
Install and load necessary packages
This study needs packages related to image processing, such as: terra
, sf
, and googledrive
; moreover, packages related to result presentation are required, including ggplot2
, leaflet
, dplyr
, and RColorBrewer
.
Prepare three mangrove species samples
The distribution of three mangrove species samples in our study area is as shown in the following:
The downloaded HLS images are uploaded to Google Drive, we can access this data folder through ID. Then, we will collect band 4 and band5 from the dataset. Partial code is presented as following:
# drive_auth() for first time to link Google Drive from R, we should do this authentication
<- "MYGOOGLEFOLDERIDHERE"
HLSImages_Folder_ID <- drive_ls(as_id(HLSImages_Folder_ID))
HLS_Everglades <- HLS_Everglades %>% filter(grepl("_B04_", name))
HLS_band4 <- HLS_Everglades %>% filter(grepl("_B05_", name))
HLS_band5
# extract DOY from HLS_band4$name
<- function(names_column) {
extract_doy <- gsub(".*_doy(\\d{7}).*", "\\1", names_column)
doy_values return(as.numeric(doy_values)) # convert it to numeric
}
# Add it to DOY column in HLS_band4 and HLS_band5
$DOY <- extract_doy(HLS_band4$name)
HLS_band4$DOY <- extract_doy(HLS_band5$name)
HLS_band5
# Initial the results file (extracted band 4 and band 5 values) as a list
$download_link <- sapply(HLS_band4$drive_resource, function(x) x$webContentLink)
HLS_band4$download_link <- sapply(HLS_band5$drive_resource, function(x) x$webContentLink)
HLS_band5
<- lapply(HLS_band4$download_link, function(link) rast(link))
band4_rasters <- lapply(HLS_band5$download_link, function(link) rast(link)) band5_rasters
Extract phenology from time-series HLS
- NDVI values were retrieved for mangrove species sampling points. The extracted data were organized into a tabular format, with rows representing dates and columns representing NDVI values for each sample point.
Code
# Function to compute NDVI from Band 4 and Band 5 datasets
<- function(band4_file, band5_file, output_file) {
compute_ndvi # Read Band 4 and Band 5 CSV files
cat("Reading Band 4 data from:", band4_file, "\n")
<- read.csv(band4_file)
band4_data cat("Reading Band 5 data from:", band5_file, "\n")
<- read.csv(band5_file)
band5_data
# Preprocess DOY columns
cat("Preprocessing DOY columns...\n")
$DOY <- as.numeric(trimws(band4_data$DOY))
band4_data$DOY <- as.numeric(trimws(band5_data$DOY))
band5_data
# Remove duplicates if present
if (any(duplicated(band4_data$DOY))) {
cat("Removing duplicate DOY values in Band 4...\n")
<- band4_data[!duplicated(band4_data$DOY), ]
band4_data
}if (any(duplicated(band5_data$DOY))) {
cat("Removing duplicate DOY values in Band 5...\n")
<- band5_data[!duplicated(band5_data$DOY), ]
band5_data
}
# Identify common DOY
cat("Identifying common DOY values...\n")
<- intersect(band4_data$DOY, band5_data$DOY)
common_doy if (length(common_doy) == 0) {
stop("No matching DOY values found between Band 4 and Band 5 datasets.")
}cat("Number of matching DOY values:", length(common_doy), "\n")
# Filter data to retain only matching DOY
<- band4_data[band4_data$DOY %in% common_doy, ]
band4_data <- band5_data[band5_data$DOY %in% common_doy, ]
band5_data
# Sort datasets by DOY
<- band4_data[order(band4_data$DOY), ]
band4_data <- band5_data[order(band5_data$DOY), ]
band5_data
# Check alignment of DOY columns
cat("Checking DOY alignment...\n")
if (!all(band4_data$DOY == band5_data$DOY)) {
<- which(band4_data$DOY != band5_data$DOY)
mismatches cat("Mismatched DOY rows detected:\n")
print(band4_data$DOY[mismatches])
print(band5_data$DOY[mismatches])
stop("DOY columns still not aligned after sorting.")
}cat("DOY columns are aligned.\n")
# Initialize NDVI results
cat("Initializing NDVI results...\n")
<- data.frame(DOY = band4_data$DOY)
ndvi_results
# Compute NDVI for each sample point
cat("Computing NDVI for sample points...\n")
for (col in 2:ncol(band4_data)) { # Skip the DOY column
<- band4_data[, col]
band4_col <- band5_data[, col]
band5_col
# Calculate NDVI
<- (band5_col - band4_col) / (band5_col + band4_col)
ndvi_results[, col]
}
# Add column names to NDVI results
colnames(ndvi_results) <- colnames(band4_data)
# Save NDVI results to CSV
cat("Saving NDVI results to:", output_file, "\n")
write.csv(ndvi_results, output_file, row.names = FALSE)
cat("NDVI computation completed successfully.\n")
}
compute_ndvi("data/extracted_band4_BM.csv", "data/extracted_band5_BM.csv", "data/ndvi_BM.csv")
compute_ndvi("data/extracted_band4_RM.csv", "data/extracted_band5_RM.csv", "data/ndvi_RM.csv")
compute_ndvi("data/extracted_band4_WM.csv", "data/extracted_band5_WM.csv", "data/ndvi_WM.csv")
- Harmonic regression was employed to model the seasonal patterns in NDVI data. The fitted harmonic regression curves were plotted alongside the observed NDVI data points to visualize seasonal trends.
Code
# Function to preprocess DOY to extract the day of year
<- function(doy_column) {
preprocess_doy as.numeric(substr(doy_column, 5, 7)) # Extract last three digits
}
# Function to remove outliers based on 3x standard deviation
<- function(data) {
remove_outliers <- mean(data$Average_NDVI, na.rm = TRUE)
mean_ndvi <- sd(data$Average_NDVI, na.rm = TRUE)
std_ndvi <- mean_ndvi - 3 * std_ndvi
threshold_low <- mean_ndvi + 3 * std_ndvi
threshold_high %>%
data filter(Average_NDVI >= threshold_low & Average_NDVI <= threshold_high)
}
# Function to fit harmonic regression and predict NDVI
<- function(data, species_name) {
fit_harmonic_regression # Preprocess DOY and remove outliers
<- data %>%
data mutate(DOY = preprocess_doy(DOY)) %>% # Preprocess DOY to extract day of year
filter(Average_NDVI > 0 & Average_NDVI < 1) %>% # Filter valid NDVI values
remove_outliers() # Remove outliers based on 3x std
# Fit harmonic regression
<- lm(Average_NDVI ~ cos(2 * pi * DOY / 365) + sin(2 * pi * DOY / 365), data = data)
model
# Generate DOY sequence for predictions
<- seq(1, 365, by = 1)
doy_seq <- predict(model, newdata = data.frame(
predictions DOY = doy_seq
))
# Return observed data, fitted model, and predictions
list(
data = data,
model = model,
predictions = data.frame(DOY = doy_seq, Fitted_NDVI = predictions),
species = species_name
) }
Results
Average NDVI
The NDVI value ranges are shown in the following graph.Among three mangrove species, red mangrove present the lowest average NDVI through the year 2023 (0.61), while white mangrove presents the highest average NDVI (0.65).Moreover, black mangrove presents highest peak NDVI through the year compared to other two mangrove species.
Pheonogy demostration based on harmonic regression
We used harmonic regression to generate descriptive phenological curves as following. We observed that many points fall outside the normal range of mangrove NDVI values. These outliers may be caused by cloud cover or water inundation.By observing the current results, the onset time of Red Mangrove appears to be earlier compared to the other two mangrove species.
Conclusion
This study utilized time-series HLS data on 2023 to analyze the phenology of three mangrove species in Everglades, Florida. To be more specific, I applied harmonic regression to generate phenology based on time-series NDVI. From the resluts, we can see that different mangrove species present different average greenness (average NDVI) and pheonogy through the year. Moreover, to refine this study, we can filter the image pixels influenced by clouds and tides. In conclusion, this study help in understanding the dynamics within one mangrove ecosystem, aiding conservation efforts and the management of coastal ecosystems in the face of climate change.