lp_theme() layer styles every plot type, and every panel of a
patchwork layout, from the pipeline (#60):
lp_theme(preset = "publication", palette = "okabe_ito", base_size = 8).
preset is "minimal" (the previous look, still the default),
"classic", "publication" (white background, axis lines, no minor grid,
8 pt base size), or any ggplot2 theme. palette is "okabe_ito",
"viridis", "ggplot2" (the previous hues), or a named or unnamed vector
of colours. line_width sets the width of the plotted lines and of the
theme's lines. lp_get_plot() + theme(...) still overrides the preset.lp_theme(palette = "ggplot2") for the previous hues. A series keeps its
colour across all the panels of a layout. Continuous scales (intensity
maps, peak count images, purity scores) are unchanged.highlight_peaks_factor
of lp_chromatogram() now defaults to NULL, meaning the group_by
column of lp_arrange(), else sample_id. Set it explicitly for the
previous behaviour.tests/testthat/fixtures/baseline are
unaffected: they record the values handed to the plotting functions, not
their colours.lp_spectra(mode = "precursor") plots the MS2 spectra of each feature from
data-dependent acquisition (#54): the MS2 scans whose precursor m/z lies
within ppm of the m/z of the feature's detected peak and whose retention
time lies within the peak, or within the feature's extraction window in
samples where it has no detected peak. select keeps the scan with the
most intense precursor ("most_intense", falling back to the total ion
current), the scan closest to the apex ("closest_apex"), every scan
("all"), or one consensus spectrum per feature and sample
("consensus", tuned by consensus_ppm and consensus_min_prop).
Spectra keep their feature_id, mirror plots against spectral_match_db
work as before, and features without a matching MS2 scan are skipped with
a single warning listing them.precursor_marker_shape,
precursor_marker_position, and precursor_marker_color arguments of
lp_spectra().lp_spectra(mode = "closest_apex") and mode = "across_peak" now select
and report scans on the adjusted retention times when the data has them,
as the detected peaks and feature chromatograms already did. They used to
look up raw scan times with adjusted peak times, so the spectra could come
from a scan next to the apex and their RT lines sat slightly off the
chromatogram. The xcms_spectra_closest_apex baseline was re-recorded.MzTabMSource() reads mzTab-M 2.0 files (as exported by MS-DIAL,
MZmine, OpenMS, ...) alongside their raw files (#51). Small molecule
features (SMF) become peaks with their feature_id, adduct_ion and
charge, annotated with the name, formula, database_identifier and
reliability of the summary (SML) rows that reference them. The new
lp_mztab() layer selects the features to plot, e.g.
lp_mztab(features_query = "reliability <= 2").inst/extdata (MTBLS263.mztab,
mtbls263-mzml.zip); tools/mztab/make-mtbls263-example.R rebuilds them.lcmsPlotDataContainer now holds RforMassSpectrometry data
structures (#52). The sample metadata is the sampleData() of an
MsExperiment, chromatograms are a Chromatograms object, and spectra are
a Spectra object. Every dataset is keyed by sample_index, and feature
annotations (feature_id, name, formula, ...) are carried by the
chromatograms, spectra, and peaks they describe. Migrating:
create_data_container_from_obj() is replaced by
lcmsPlotDataContainer().data_obj, metadata, feature_metadata, and the per-dataset
data frames are gone. Use the accessors sampleMetadata(),
chromatograms(), spectra(), detectedPeaks(), and summaries()
(mass traces, intensity maps, total ion current, RT differences, peak
density, peak counts, and purity scores) on an lcmsPlot object or its
container.metadata_index and feature_metadata_id columns are replaced by
sample_index and the annotation columns themselves.XCMSnExp input is converted to an XcmsExperiment.aggregation_fun = "mean" on an XcmsRawList is now the mean of each
scan's centroids; the profile matrix is no longer used.MsRawReader and its subclasses) are
removed; raw data is read through Spectra backends.
MsBackendRawFileReader is needed to read the spectra of ThermoFisher
.raw files, while their chromatograms are still extracted with rawrr.subset_features() keeps the data matching a condition on its
annotations without reading the raw data again, for example to draw one
plot per compound out of a single extraction.data.table. On three faahKO files, 100 extracted ion chromatograms take
about 2 s instead of 15.1 s, closest_apex spectra 0.6 s instead of 12.2 s,
and an intensity map 2.0 s instead of 28.0 s..cdResult chromatograms are no longer duplicated
once per sample.lp_total_ion_current() gains initial, as in Spectra::tic(). The
default (TRUE) plots the total ion current recorded in each scan's
header for every input; FALSE sums each scan's peaks. Raw netCDF files
given as paths used to be summed, so their plot changes unless
initial = FALSE is set. netCDF headers include signal that is not among
the stored peaks, so on faahKO the header values are about twice the
sums.lp_total_ion_current(), lp_intensity_map(), and lp_rt_diff_plot() are
now replayed by iterate_plot_batches() and next_plot(), and
lp_total_ion_current() honours sample_ids.CONTRIBUTING.md and update README.md with latest features.across_peak spectra about 15
times and intensity maps up to 100 times. The extracted data is unchanged
(#48)..raw files are extracted much faster
for the Compound Discoverer node and LipidSearch. All compound XICs of a
sample are now read from its .raw file in a single rawrr call, rather
than one call per compound, and the mass traces these sources never plot are
no longer computed. The scan header of a .raw file is read once and reused,
which also speeds up feature chromatograms. The extracted chromatograms are
unchanged (#40).node_response.json now returns only the Compounds ID
column and the new plot column, in both the data file and the
ColumnDescriptions. Compound Discoverer adds every column it gets back, so
echoing the full Compounds table used to make columns such as Area and Gap
Fill Status appear twice (#45).XChromatograms features can be named. Setting the row names of an
XChromatograms object now sets the feature_id used for labelling and
faceting:
chrs <- chromatogram(xdata, mz = mzr, rt = rtr)
rownames(chrs) <- c("mz344", "mz360")
Row names take precedence over xcms::featureChromatograms() feature
identifiers; rows with neither keep the M<mz>T<rt> identifier.
Manually specified features can be named. A feature passed to
lp_chromatogram(features = ) as a matrix or data.frame now takes its
feature_id from the row names, or from a feature_id column of a
data.frame, so
lp_chromatogram(features = rbind(
mz335 = c(mzmin = 334.9, mzmax = 335.1, rtmin = 2700, rtmax = 2900)))
labels and facets the feature as mz335. Unnamed rows keep the
M<mz>T<rt> identifier derived from their ranges. Likewise, an
XChromatograms object from xcms::featureChromatograms() now uses the
feature definition row names (e.g. "FT0003") rather than M<mz>T<rt>.
Feature identifiers now come from the feature definition row
names. Where lcmsPlot previously derived its own xcms::groupnames()-style
M<mz>T<rt> labels from mzmed/rtmed, it now uses
rownames(xcms::featureDefinitions(obj)) — whatever you have set them to, or
the "FT0001"-style defaults xcms assigns during correspondence. This affects
both the identifiers you pass to lp_chromatogram(features = ...) and the
feature_id column used for labelling and faceting, so a call such as
lp_chromatogram(features = c('M205T2792', 'M283T3890'))
becomes
lp_chromatogram(features = c('FT002', 'FT027'))
Annotating features by renaming the rows of featureDefinitions() is now
enough to have those names appear on the plot; no separate labelling step is
needed. Objects whose feature definitions carry no row names at all still get
positional "FT..." identifiers, so a single nomenclature applies throughout.
Feature identifiers that match no feature are now reported. Previously an
unrecognised identifier was dropped silently and produced an empty plot;
lp_chromatogram() now warns, naming the identifiers it skipped, and plots
the ones that did match.
lp_compound_discoverer(compounds_query = ...) can now filter on the
checked column of the Compound Discoverer Compounds table, so a result
set curated by hand in Compound Discoverer can be plotted directly with
compounds_query = "checked". This works for both Compound Discoverer
sources:
For .cdResult files it is read from
ConsolidatedUnknownCompoundItems.Checked. Compound Discoverer only
materialises that column once compounds have been checked and the result
saved in the application, so its presence is probed per file: referencing
checked on a file that has none raises an explanatory error instead of
failing with a raw SQL error.
For the scripting-node source it is read from the Checked column of the
exported Compounds table, and parsed from Compound Discoverer's True /
False text (other spellings are accepted defensively, so a differently
encoded export does not silently read as all-NA).
The Compounds Chromatograms scripting node follows Compound Discoverer's
checked-compounds convention: if any compound is
checked in the Compounds table, only the checked ones are plotted; if none is
checked, all of them are. Checking compounds in Compound Discoverer is
therefore enough to pick exactly what gets plotted, and the Compounds Query
parameter is ignored while any box is ticked. A query that references checked
itself (for example checked & compound_rank <= 5) is used as written and is
never overridden, so the two can still be combined. The node logs which of
these applied on every run.
compounds_query = NULL (the default) no longer errors on the .cdResult
path, and now means "no filter", matching the scripting-node behaviour.
lp_spectra() gains mz_breaks_n, the approximate number of m/z axis
breaks, passed through to scales::pretty_breaks(n = ...). The break count was
previously hard-coded at 20, which crowded the axis on narrow m/z windows. It
defaults to 6.Closed six gaps between lcmsPlot and the plotting methods of xcms, so the
backend = "lcmsPlot" variants of those methods have an equivalent to call.
The Easy-to-use, intuitive, and efficient LC-MS data plotting with lcmsPlot vignette now covers all of this. A new Quality control of peak detection section documents the two new layers, and the four extended arguments are documented in the sections that already covered those layers.
New layer lp_chrom_peak_rects() draws one rectangle per detected
chromatographic peak, spanning rtmin-rtmax by mzmin-mzmax. It covers
both xcms methods that draw that primitive. Called on its own it owns a panel,
drawing the rectangles on an otherwise empty rt / m/z frame with one facet per
sample, as xcms::plotChromPeaks() does; rt_range and mz_range restrict it
the way that method's xlim and ylim do. Called after lp_mass_trace() or
lp_intensity_map() it decorates that panel instead, as
xcms::plot(type = "XIC") does, following the host's x_dim, window and
sample_ids so the axes are not widened and no extra facets appear. Which mode
applies is decided from the finished plot, so it does not depend on the order
the layers were added in. Every box is given a minimum height so that peaks on
m/z-binned data (where mzmin == mzmax) read as segments instead of vanishing.
New layer lp_peak_count_image() reproduces
xcms::plotChromPeakImage(): retention-time bins on x, samples on y, filled by
the number of chromatographic peaks per bin. Samples are ordered by injection
order, and bins with no peaks are kept at zero, so a sample that stopped
producing peaks half-way through a run reads as an empty stretch rather than
disappearing. Counts match the xcms method's binning exactly.
lp_peak_density() now accepts XChromatograms and XChromatogram
objects, which is what xcms::plotChromPeakDensity() takes. The type gate is
now a capability check through get_detected_peaks() rather than a class
check, the creator goes through that adapter instead of calling
xcms::chromPeaks() directly (the sample column is named column, not
sample, on chromatogram objects), and features is redundant for these
inputs because each extracted ion chromatogram already carries its own m/z
window. A new simulate argument mirrors the xcms method: TRUE descends the
density curve for candidate features, FALSE draws the feature definitions the
object already stores.
lp_chromatogram() gains stacked and transform, matching
xcms::plotChromatogramsOverlay(). stacked offsets each series up the y axis
in m/z order by a fraction of the intensity range so co-eluting traces stop
occluding each other, using the same offset formula as xcms, and suppresses the
y axis because a stacked axis has no single meaning; the offsets are returned
on the plot as a stacked_offsets attribute. transform (for example
log10) is applied to the intensities and to the peak-highlight geometry
alike, so shaded peaks stay attached to their traces.
lp_chromatogram(aggregation_fun = "mean") produces the averaged ion
chromatogram of xcms::plotChrom(base = FALSE). The ms_header() contract has
gained peaksCount and meanIntensity, letting each backend define the mean
faithfully: XcmsRawList inputs carrying a profile matrix use the
profile-matrix column mean and so reproduce the xcms trace exactly, while
file-based inputs average over the measured peaks of each scan. Unknown
aggregation functions now raise an error rather than silently returning a TIC.
lp_intensity_map() gains geom, point_size, bin_rt, bin_mz and
colour_scale. geom = "point" draws the individual centroids as
xcms::plotRaw() does, skipping the binning so gaps in the mass traces stay
visible instead of being implied away by a tile grid. The retention-time and
m/z bin widths, previously hard-coded at 0.1, are now arguments.
density argument of lp_intensity_map() has been removed. It is
replaced by geom = "density", which selects the same rendering. Two separate
switches could contradict each other, so there is now a single one. Replace
lp_intensity_map(..., density = TRUE) with
lp_intensity_map(..., geom = "density"); density = FALSE was the default
and can simply be dropped.lp_intensity_map() no longer errors with "argument is of length zero" on
narrow m/z windows. The peak matrix was subset without drop = FALSE, so any
scan with exactly one peak in range collapsed to a vector and the following
nrow() check failed. A narrow window is precisely what an XIC plot passes.
plot_chromatogram() no longer joins every series in a facet into a single
zig-zagging line when the colour aesthetic is something other than
sample_id. The ggplot group was pinned to sample_id while lp_arrange()
set only the colour; it is now a composite of the sample and the arrangement
column, so colouring by feature_id splits the lines while coarser factors
such as sample_group keep one line per sample as before.
lp_peak_density(simulate = TRUE) no longer draws overlapping feature
rectangles that all start at the same retention time. The internal descent
used to find each feature's boundaries compared neighbouring density values
with <=, so once the previous feature's range had been zeroed it walked
straight across that plateau and re-collected the peaks already assigned. Each
later rectangle therefore reached back to the first feature's leftmost peak,
and passed the min_fraction test on the strength of those peaks. The
comparison is now strict, matching the DescendMin routine of xcms, and the
rectangles agree with xcms::plotChromPeakDensity().
Every man page documenting an exported object now carries a runnable example.
The four \dontrun{} blocks that referenced unavailable vendor data
(CompoundDiscovererNodeSource(), LipidSearchSource(),
lp_compound_discoverer(), lp_lipid_search()) have been replaced with
self-contained code, and the four precursor-purity layers
(lp_purity_overlay(), lp_purity_timeline(), lp_purity_distribution(),
lp_isolation_window()) have gained examples where they previously had none.
This satisfies the Bioconductor requirement that at least 80% of such pages
have runnable examples; coverage is now 100% (33 of 33, up from 25 of 33).
The purity examples use the DDA files already shipped in
inst/extdata/standards-mzml.zip, whose MS2 scans carry real precursor
selection and isolation-window metadata, so msPurity::purityA() yields six
fragmentation events with informative inPurity scores. They are guarded with
@examplesIf requireNamespace("msPurity") because msPurity is a suggested
dependency. lp_isolation_window() uses half_width = 0.6 to match the
isolation width recorded in those files.
The Compound Discoverer scripting-node and LipidSearch examples build a
minimal vendor export in tempdir(), following the existing
MZmineFeatureListsSource() and MsDialPeaksSource() examples, and point
sample_paths at the shipped mzML files so the documented plots extract real
chromatograms rather than only constructing a data source.
Added support for LipidSearch result files (both 4.2 and 5.2; the
version is auto-detected). The new LipidSearchSource() constructor parses the
lipid table, reshapes the per-sample Area / Height / RT / observed-m/z
columns into an xcms-style peak table, and builds a plottable data source.
Rejected lipids are dropped unless keep_rejected = TRUE, and lipid ions
reported at several retention times get distinct plot labels. Plotting uses the
new lp_lipid_search(lipids_query, rt_extend) layer, whose query can reference
the lipid annotations (class, sub_class, grade, adduct, lipid_rank,
...).
LipidSearch 5.2 files carry no raw-file names, so their samples are keyed
s1, s2, … (from the OrgMeanArea[...] columns). For 5.2, map raw files by
naming sample_paths with those keys (c("s1" = "a.mzML", "s2" = "b.mzML")) —
order-independent and covering any subset — or pass an unnamed vector matched
positionally. 5.2 exports add a sub_class annotation and an explicit adduct,
and their per-lipid BaseRt provides an extraction window even for lipids
detected in no sample. 4.2's basename matching is unchanged. The rej
annotation is now a logical for both versions.
Samples plotted from a LipidSearch source are not limited to the ones
declared in the result file: sample_paths determines the sample list and is
matched to the declarations by file basename without extension (so a result
file listing .raw files works with converted .mzML files). A supplied
path that matches no declaration is still a full sample - every queried
lipid's chromatogram is extracted there using the lipid's consensus m/z and
retention-time window, it simply has no reported peak to highlight.
The per-compound chromatogram extraction loop is now shared between the
Compound Discoverer scripting-node and LipidSearch sources
(create_compound_chromatograms()), along with the compound ranking and
column-resolution helpers.
lp_total_ion_current() now works when raw files are passed directly to
lcmsPlot() (a character vector of .mzML, .mzXML, .CDF, or .raw
paths), in addition to XCMSnExp / MsExperiment objects. The per-scan TIC
is read from the raw file headers via the shared raw-file reader interface.
Added a runnable worked example for large, multi-sample LC-MS studies. Using
a 50-sample mzML study (the published Sacurine dataset, MetaboLights
MTBLS404), it demonstrates the batching API (batch_size +
iterate_plot_batches()) together with patchwork to build one
self-contained composite figure per sample (TIC and BPC, an EIC + mass trace
for a shared compound, and a zoomed intensity map), written to a multi-page
PDF report. It is distributed as a standalone script rather than a packaged
vignette, since it downloads and processes ~50 raw files.
lcmsPlot inside a Compound Discoverer custom
Scripting Node. The new CompoundDiscovererNodeSource() constructor reads
the node_args.json file passed by Compound Discoverer together with the
tab-delimited table exports it references (Compounds, Compounds per File,
Features, and their link tables), selects a representative ion per compound
and study file (preferring [M+H]+1 / [M-H]-1, otherwise the most
abundant feature), and builds a plottable data source. Chromatograms are
extracted from the raw (mzML) files supplied via sample_paths, which are
matched to study files by file basename (falling back to positional
matching by study-file ID). Plotting reuses the existing
lp_compound_discoverer(compounds_query, rt_extend) interface. jsonlite
was added to Imports.lcmsPlotApp() as a Tailwind-based dashboard: sticky topbar,
left navigation rail with a card-style file uploader and sample picker,
and a content area with the plot in a card. The Tailwind CSS is
precompiled and shipped under inst/www/lcmsPlot.css; no runtime network
or Node dependency. Dev sources live in tools/tailwind/ (excluded from
the installed package).lp_facets(), lp_arrange(),
lp_legend(), and lp_labels() directly from the UI. Users can now
facet, group, reposition the legend, and add titles without writing R
code.htmltools::htmlDependency() and the
Tailwind content scan + safelist were hardened so utility classes
referenced from R templates actually end up in the compiled stylesheet.
The UI is now wrapped in shiny::bootstrapPage() so the hidden
tabsetPanel switches correctly. Card corners reduced from
rounded-2xl to rounded-md, sidebar gap bumped to gap-6, and the
initial nav highlight is now set statically in markup..raw files (multi-file), Compound Discoverer .cdResult SQLite
results (single file), serialised XCMSnExp / MsExperiment objects
via .rds (single file), and saved workspaces containing one such
object via .RData / .rda (single file). All existing mzML / CDF
workflows are unchanged.lcmsPlotApp(), an interactive Shiny app for exploring raw LC-MS
files. Users can upload one or more mzML / CDF files and view base-peak
and total-ion chromatograms, extract ion chromatograms by m/z and ppm
(with an optional retention-time window), inspect peak density across
samples, and plot spectra by scan index. The app follows Bioconductor's
Shiny code-organisation guidelines: all UI/server code lives in R/
and lcmsPlotApp() returns a shinyApp object rather than calling
runApp() internally. shiny, shinytoastr, and shinytest2 were
added to Suggests.purityA objects (msPurity) as the data_obj input to
lcmsPlot(), enabling direct visualisation of precursor ion purity results.lp_purity_overlay(): overlays per-scan inPurity scores as coloured
points on a chromatogram, with a diverging colour scale and an optional
threshold midpoint.lp_purity_timeline(): scatter plot of inPurity versus retention
time per sample, with an optional horizontal threshold line.lp_purity_distribution(): violin or boxplot distribution of
inPurity scores grouped by sample, with an optional threshold line.lp_isolation_window(): MS1 spectrum plot annotated with the
isolation window rectangle, precursor m/z dashed line, and inPurity score
as a subtitle.purity_scores slot to lcmsPlotDataContainer for storing per-scan
purity data extracted from purityA@puritydf.msPurity to Suggests in DESCRIPTION.lp_peak_density() for peak density plots that mirror
xcms::plotChromPeakDensity(): y-axis shows sample indices positioned
within the kernel density range, x-axis shows RT, coloured points mark
individual detected peaks per sample, and a density line is overlaid.
When min_fraction and sample_groups are provided the density-descent
grouping algorithm is simulated and semi-transparent rectangles highlight
RT regions that would form feature groups.
When used after lp_chromatogram(), features is inherited automatically.
Supports rt_unit ("second" / "minute"), bw, min_samples,
max_features, and multiple m/z windows with auto-faceting.highlight_peaks_mode = "rectangle" and "point" in
lp_chromatogram(): geoms now use inherit.aes = FALSE to avoid
evaluating the global x = rt_plot aesthetic against detected_peaks,
which previously caused an object 'rt_plot' not found error.
RT values for rectangle and point modes are now scaled correctly when
rt_unit = "minute".line_type parameter to lp_chromatogram() (passed through to
geom_line(); any ggplot2 linetype string is accepted).x_dim, y_dim, and fill_scale parameters to
lp_intensity_map(), allowing the m/z and RT axes to be swapped and
the fill colour scale to be replaced with any ggplot2 scale object.lcms_data_plotting
vignette with explanatory prose and a combined chromatogram + peak
density example.data.frame to tibble;
tibble is now a formal Imports dependency.all_of() call in the DBIConnection chromatogram creator to pass
column names as a single character vector.tibble() calls in MZmineFeatureListsSource and
MsDialPeaksSource examples as tibble::tibble() to avoid
could not find function "tibble" errors during R CMD check.get_metadata() documentation with dedicated sections describing
the behaviour for all nine dispatch methods: character, XCMSnExp,
MsExperiment, MChromatograms, XChromatograms, XChromatogram,
XcmsRawList, ExternalDataSource, and DBIConnection.xcmsRaw objects via the new XcmsRawList S4 container
and create_xcms_raw_list() convenience helper that reads files in parallel
via BiocParallel.XcmsRawReader, a MsRawReader subclass that reads scan headers and
peaks directly from in-memory xcmsRaw slots without opening a file
connection.XChromatograms, XChromatogram, and MChromatograms
as direct data inputs to lcmsPlot().XChromatograms now automatically derive a feature_id from the m/z and
RT ranges of each row, enabling faceting and gridding on feature_id.create_chromatograms()
S4 generic replacing the four previous specialised generics.na.rm argument to lp_chromatogram() to remove data points with
NA intensity before plotting..github/workflows/R-CMD-check.yaml) that
runs devtools::test() and rcmdcheck::rcmdcheck() against the Bioconductor
devel Docker image on every push and pull request to devel.<- vs = assignment NOTE raised by R CMD CHECK.\dontrun{} examples to MZmineFeatureListsSource and
MsDialPeaksSource documentation.MZmineFeatureListsSource.MsDialPeaksSource..cdResult) via a new
SQL-based data source backed by DBI / RSQLite.lp_compound_discoverer() for loading and querying Compound Discoverer
results directly within the lcmsPlot pipeline.lcmsPlot class documentation.lcmsPlotClass documentation.get_metadata() for XCMSnExp and MsExperiment now falls back to
deriving sample_id from file basenames when no sample_id_column is
present.fig.height, fig.width) to vignette
chunks for consistent rendered output.@return documentation across all exported
functions.@return documentation to exported functions.AnnotatedDataFrame (was incorrectly using
NAnnotatedDataFrame in some code paths).xcms and patchwork calls.MulticoreParam call in vignette.BiocParallel namespace registration in vignette.testthat (edition 3) test suite covering chromatogram, spectra, and
intensity map creators.lcmsPlot.lcmsPlot() entry point accepting MsExperiment, XCMSnExp, and raw file
paths (character) as data sources.lp_chromatogram(): base peak chromatograms (BPC), total ion chromatograms
(TIC), and extracted ion chromatograms (XIC) with configurable m/z and RT
tolerances.lp_spectra(): mass spectra extraction with "closest", "closest_apex",
and "across_peak" scan-selection modes; standalone and chromatogram-linked
display; spectral mirror plots.lp_intensity_map(): two-dimensional m/z vs RT intensity maps with optional
density smoothing.lp_total_ion_current(): TIC distributions as violin or box plots.lp_mass_trace(): mass trace overlays below chromatogram panels.lp_rt_line(): vertical reference lines at specified retention times.lp_rt_diff_plot(): retention-time correction diagnostic plot.lp_facets(), lp_grid(), lp_arrange(), lp_layout(): flexible panel
layout helpers.lp_labels(), lp_legend(): axis and legend annotation helpers.highlight_peaks and highlight_apices options in lp_chromatogram().MsExperiment support including retention-time corrected chromatograms
(rt_type = "corrected" / "both").