spectrakit Package – Part 1: Plotting Spectra in R with plotSpectra()
This is part 1 of a series on the spectrakit R package. Start
here for an introduction.
Overview
TheplotSpectra() function from the spectrakit R package
reads spectral data from multiple files in a folder, applies optional
normalization, and produces publication-ready plots with extensive
customization options. It supports multiple plotting modes, color palettes,
axis formatting, annotations and automatic export of figures. This function is
especially useful when working with batches of raw spectra files that require
consistent and reproducible visualization. Typical use cases include
exploratory comparison of spectra and generating standardized figures for
reports, presentations or scientific publications.Syntax
plotSpectra(
folder = ".",
file_type = "csv",
sep = ",",
header = TRUE,
normalization = c("none", "simple", "min-max", "z-score", "area", "vector"),
norm_scope = c("global", "range"),
x_config = NULL,
x_reverse = FALSE,
y_trans = c("linear", "log10", "sqrt"),
x_label = NULL,
y_label = NULL,
line_size = 0.5,
palette = "black",
plot_mode = c("individual", "overlapped", "stacked"),
display_names = FALSE,
vertical_lines = NULL,
shaded_ROIs = NULL,
annotations = NULL,
output_format = "tiff",
output_folder = NULL
)
Arguments
| Argument name | Type | Description | Default value (if provided, argument is optional) |
|---|---|---|---|
| folder | Character | Path to the folder containing spectra files | "." (working directory) |
| file_type | Character | File extension (without dot) to search for | "csv" |
| sep | Character | Delimiter for file columns. Use "\t" for tab-delimited files | "," (comma-separated) |
| header | Logical | Whether the files contain a header row | TRUE |
| normalization | Character |
Normalization method to apply to y-axis data. One of:
|
"none" |
| norm_scope | Character |
Determines whether normalization is applied to the full spectrum or
only to a specified range. One of:
|
"global" |
| x_config | Numeric vector of length 3 | Specifies x-axis range and breaks: c(min, max, step) | NULL (the full data range is used and axis breaks are set every 100 units) |
| x_reverse | Logical | If TRUE, reverses the x-axis | FALSE |
| y_trans | Character |
Transformation for the y-axis. One of:
|
"linear" |
| x_label | Character or expression | Label for the x-axis. Supports mathematical notation via expression(), e.g., expression(Wavenumber~(cm^{-1})) | NULL (no axis label) |
| y_label | Character or expression | Label for the y-axis. Supports mathematical notation via expression(), e.g., expression(Delta*E["00"]^{"*"}) | NULL (no axis label) |
| line_size | Numeric | Width of the spectral lines | 0.5 |
| palette | Character or vector |
Color setting. One of:
|
"black" |
| plot_mode | Character |
Plotting style. One of:
|
"individual" |
| display_names | Logical | If TRUE, adds file names as titles to individual spectra or a legend to combined spectra | FALSE |
| vertical_lines | Numeric vector | Adds vertical dashed lines at given x positions | NULL |
| shaded_ROIs | List of numeric vectors | Each vector must have two elements (xmin, xmax) to define shaded x regions | NULL |
| annotations | Data frame with columns file (file name without extension), x, y, and label. | Adds annotation labels to specific points in spectra | NULL |
| output_format | Character | File format for saving plots. Examples: "tiff", "png", "pdf" | "tiff" |
| output_folder | Character | Path to folder where plots are saved. If NULL, plots are not saved and the ggplot object is returned. If specified, plots are saved automatically; if ".", plots are saved in the working directory | NULL |
Return value
If
output_folder = NULL, the function returns a
ggplot object. Otherwise, returns NULL invisibly
after saving the plots to a specified output folder.
Practical examples
Each raw spectrum file must contain two columns: one for the x-axis (e.g.,
energy, wavelength or wavenumber) and one for the y-axis (e.g., counts,
reflectance or absorbance). In this example, we generate six near-infrared
(NIR) sample spectra using the
To save the spectra images instead of simply displaying them, the minimal
working example of the
NIRsoil dataset included in
the prospectr package. The code below randomly selects six spectra
from the dataset and saves each as a CSV file in a temporary folder on the
Desktop, with named columns for wavelength and reflectance:
# ---- Install & load package if needed ----
# install.packages("prospectr")
library(prospectr)
# ---- Load dataset ----
data(NIRsoil)
# Spectral matrix and wavelength axis
spectra_matrix <- NIRsoil$spc
wavelength <- as.numeric(colnames(spectra_matrix)) # wavelength in nm
# ---- Create TEMP folder on Desktop ----
desktop_path <- file.path(path.expand("~"), "Desktop")
temp_dir <- file.path(desktop_path, "TEMP")
if (!dir.exists(temp_dir)) {
dir.create(temp_dir, recursive = TRUE)
}
# ---- Randomly select 6 spectra ----
set.seed(260329) # for reproducibility
n_available <- nrow(spectra_matrix)
if (n_available < 6) stop("Dataset contains fewer than 6 spectra.")
selected_rows <- sample(seq_len(n_available), 6)
# ---- Save each spectrum as a CSV file ----
for (i in seq_along(selected_rows)) {
reflectance <- spectra_matrix[selected_rows[i], ]
output_df <- data.frame(
Wavelength = wavelength,
Reflectance = as.numeric(reflectance)
)
file_path <- file.path(
temp_dir,
paste0("NIRsoil_spectrum_", i, ".csv")
)
write.csv(
output_df,
file = file_path,
row.names = FALSE,
quote = FALSE
)
}
cat("6 random NIR spectra saved in:", temp_dir, "\n")
plotSpectra() function requires
specifying only the output_folder argument, while all other
arguments use their default values. In this case, it is set to the working
directory, which corresponds to the temporary Desktop folder containing
the spectra:
# ---- Install & load package if needed ----
# install.packages("spectrakit")
library(spectrakit)
setwd(temp_dir)
plotSpectra() # Display the spectra, or
plotSpectra(output_folder = ".") # Save the spectra to the current directory
This produces six individual TIFF images of the full-range,
non-normalized spectra, each automatically saved using its original
filename along with the date and time of export:
If the spectra were saved not as comma-separated CSV files in the
working directory but as tab-separated TXT files in a
text_version subfolder, and we wanted to save the images as
PNG files in the same folder, we should specify the following arguments:
plotSpectra(folder = "./text_version",
file_type = "txt",
sep = "\t",
output_format = "png",
output_folder = "./text_version")
In most cases, the function can also read
.dat and
.dpt files, provided they are in a compatible text format
(e.g., tab-delimited). Now, going back to the original CSV files,
suppose we want to display all spectra in a single plot rather than
plotting them individually. To do this, we use the
plot_mode argument and set it to
"overlapped":
plotSpectra(plot_mode = "overlapped", output_folder = ".")
Combined_Spectra, saved with the date and time of export:
This plot is not very informative and may even be misleading, as
several important details are missing. To improve it, we can name
the axes appropriately, normalize the spectra to the 0–1 range to
make their intensities comparable, assign a distinct,
colorblind-friendly color to each spectrum, and add a legend for
identification:
plotSpectra(
normalization = "min-max",
x_label = "Wavelength (nm)",
y_label = "Reflectance (a.u.)",
palette = "Dark2",
plot_mode = "overlapped",
display_names = TRUE,
output_folder = "."
)
Much better, but the x-axis labeling is cluttered. Using the
x_config argument, we can specify wider spacing between
the axis ticks, and we might also consider focusing on a narrower
spectral range. Importantly, unless norm_scope is set to
"range", selecting a spectral range with
x_config only enables zooming the x-axis and setting the
breaks between ticks, without affecting the normalization, which is by
default applied to the full spectrum (this is the standard approach in
spectroscopy, which avoids misleading intensity scaling that could
occur if normalization were applied only within the subset defined by
x_config):
plotSpectra(
normalization = "min-max",
x_config = c(1200, 2400, 200),
x_label = "Wavelength (nm)",
y_label = "Reflectance (a.u.)",
palette = "Dark2",
plot_mode = "overlapped",
display_names = TRUE,
output_folder = "."
)
A warning message indicates that several rows containing missing values
or values outside the scale range were removed; this is expected
behavior resulting from the applied filtering. The image now looks
considerably improved:
In some types of spectroscopies, such as FTIR, it is standard to reverse
the x-axis (i.e., from high to low wavenumber). We may also want to plot
the y-axis on a square root scale to emphasize low-intensity features in
the spectrum. For these purposes, we can use the
x_reverse and y_trans arguments:
plotSpectra(
normalization = "min-max",
x_config = c(1200, 2400, 200),
x_reverse = TRUE,
y_trans = "sqrt",
x_label = "Wavelength (nm)",
y_label = "Reflectance (a.u.)",
palette = "Dark2",
plot_mode = "overlapped",
display_names = TRUE,
output_folder = "."
)
However, it can be difficult to appreciate the details of each spectrum
when they are overlapped. By setting
plot_mode to
"stacked", we can display the spectra in a vertically
offset layout:
plotSpectra(
normalization = "min-max",
x_config = c(1200, 2400, 200),
x_reverse = FALSE,
y_trans = "linear",
x_label = "Wavelength (nm)",
y_label = "Reflectance (a.u.)",
palette = "Dark2",
plot_mode = "stacked",
display_names = TRUE,
output_folder = "."
)
Finally, to highlight specific bands, we can add vertical lines and
shaded regions of interest (ROIs), along with appropriate annotations,
using the optional
vertical_lines,
shaded_ROIs, and annotations arguments:
plotSpectra(
normalization = "min-max",
x_config = c(1200, 2400, 200),
x_reverse = FALSE,
y_trans = "linear",
x_label = "Wavelength (nm)",
y_label = "Reflectance (a.u.)",
palette = "Dark2",
plot_mode = "stacked",
display_names = TRUE,
vertical_lines = c(1415, 2208),
shaded_ROIs = list(c(1860, 2010)),
annotations = data.frame(file = c("Spec_1", "Spec_1", "Spec_1"),
x = c(1415, 1935, 2208),
y = c(0.9, 0.9, 0.9),
label = c("1415", "1860-2010", "2208")),
output_folder = "."
)
In this case, all annotations are lined up with the first spectrum.
However, they can also be arranged to align with different spectra, it
simply requires some experimentation. Annotations work reliably not
only in stacked mode but also in overlapped or individual display
modes. Here is an example of individual spectra plotted with their
respective titles and custom annotations:
plotSpectra(
normalization = "min-max",
x_config = c(1200, 2400, 200),
x_reverse = FALSE,
y_trans = "linear",
x_label = "Wavelength (nm)",
y_label = "Reflectance (a.u.)",
palette = "blue",
plot_mode = "individual",
display_names = TRUE,
shaded_ROIs = list(c(1412, 1416), c(1860, 2010), c(2206, 2210)),
annotations = data.frame(file = c("Spec_1", "Spec_3", "Spec_5"),
x = c(1415, 1935, 2208),
y = c(0.5, 0.75, 0.4),
label = c("1415", "1860-2010", "2208")),
output_folder = "."
)
It may be easier to prepare the annotation data frame in a spreadsheet
and then import it into R using
read_csv or
read_excel; you can assign the result to an object, which
can then be passed to the annotations argument.
Quick recap
TheplotSpectra() function from the spectrakit R
package reads multiple spectra files from a folder, optionally normalizes
the data, and generates publication-ready plots in various formats. Key
arguments include folder (file location),
file_type and sep (input format),
normalization (scaling method), x_config and
x_reverse (x-axis range and orientation),
y_trans (y-axis transformation),
plot_mode (individual, overlapped, stacked),
palette (colors), and output_format /
output_folder (saving plots). Typical usage involves pointing
the function to a folder of CSV or TXT spectra files and adjusting
normalization, axis labels, colors, and plot style for clear
visualization; the function saves the plots directly without returning an
R object. In sum, plotSpectra() streamlines reproducible,
customizable visualization of multiple spectral datasets with minimal
coding.
About the author
Gianluca Pastorelli is a Heritage Scientist (Senior Researcher) working at the National Gallery of Denmark (SMK).








Comments
Post a Comment