Package ggspectra
extends ggplot2
with
stats, geoms and annotations suitable for light spectra. It also defines
ggplot()
and autoplot()
methods specialized
for the classes defined in package photobiology
for storing
different types of spectral data. This vignette describes the use of
these autoplot()
methods.
The package uses ‘ggplot2’, ‘photobiology’ and ‘photobiologyWavebands’. More importantly it defines specializations of methods defined in ‘ggplot2’ and exports methods epecialized for classes defined in package ‘photobiology’, consequently both ‘ggplot2’ and ‘photobiology’ are loaded automatically when package ‘ggspectra’ is loaded. This is the behaviour from version 0.9.26 onwards, when using earlier versions these packages needed to be loaded explicitly.
library(ggplot2)
library(photobiologyWavebands)
library(ggspectra)
library(ggrepel)
<- packageVersion('ggrepel') != "0.9.0" # >= 0.9.0 required
good_label_repel options(ggrepel.max.overlaps = Inf) # needed for 'ggrepel' (>= 0.9.0)
We bind two spectra into an object to be used later to demonstrate grouping.
<- source_mspct(list(sun1 = sun.spct, sun2 = sun.spct * 2))
two_suns.mspct <- rbindspct(list(sun1 = sun.spct, sun2 = sun.spct * 2)) two_suns.spct
We change the default theme.
theme_set(theme_bw(10))
The most automatic way of plotting spectral data stored in one of the
classes defined in package photobiology
is to use the
autoplot()
methods (for compatibility with versions <
0.9.25 plot()
remains as a deprecated name for the same
methods). As autoplot()
methods defined by ‘ggplot2’ they
take advantage of all the data and metadata stored in objects of the
special classes used to store spectra. This allows the automatic
construction of axis labels as quantities and units are well
defined.
Here we use the same example source_spct
object from
package ‘photobiology’ used in User Guide 1. In contrast to the
examples in the User Guide 1, here we obtain with a very simple
statement an annotated plot of the solar spectrum at ground level. The
plotting of objects of all the classes defined in package ‘photobiology’
is similar except to those objects of the base class
generic_spct
. Function spct_classes()
lists
them.
spct_classes()
## [1] "calibration_spct" "raw_spct" "cps_spct" "filter_spct"
## [5] "reflector_spct" "source_spct" "object_spct" "response_spct"
## [9] "chroma_spct" "solute_spct" "generic_spct"
The simplest call to autoplot()
, using default arguments
for all parameters is:
autoplot(sun.spct)
We can change the basis of expression of spectral irradiance and
irradiance from "energy"
to "photon"
. Be aware
that by design, all values, summaries and spectral data will always use
the same base of expression.
autoplot(sun.spct, unit.out = "photon")
If a single object contains multiple spectra in long form, they are all plotted. In addition no summary values are displayed as they would overlap.
autoplot(two_suns.spct)
Collections of spectra can be plotted also automatically. See next section for examples.
In addition to autoplot()
methods for individual
spectra, autoplot()
methods are available for collections
of spectra. We use in the examples a simple collection of two spectra.
The output and acceptable arguments are the same as those in the
autoplot()
methods for multiple spectra in long form
described above. The plotting of objects of all the classes for
collections of spectra defined in package ‘photobiology’ is similar
except to those objects of the base class generic_mspct
.
Function mspct_classes()
lists them.
mspct_classes()
## [1] "calibration_mspct" "raw_mspct" "cps_mspct"
## [4] "filter_mspct" "reflector_mspct" "source_mspct"
## [7] "object_mspct" "solute_mspct" "response_mspct"
## [10] "chroma_mspct" "generic_mspct"
<- source_mspct(list(sun1 = sun.spct, sun2 = sun.spct / 2))
two_suns.mspct <- generic_mspct(list(sun = sun.spct, filter = polyester.spct)) mixed.mspct
Plot accepting all defaults.
autoplot(two_suns.mspct)
We can choose a different name for the factor identifying the spectra in the collection.
autoplot(two_suns.mspct, idfactor = "Spectra")
Facets in one column. As there is only one spectrum per panel, the summaries per waveband are shown.
autoplot(two_suns.mspct, facets = 1)
In two columns with facets = 2
.
autoplot(two_suns.mspct, facets = 2)
Plot as separate plots. This approach is specially useful with
heterogeneous generic_mspct
objects, although it works with
any collection of spectra.
multiplot(plotlist = mslply(mixed.mspct, autoplot))
All the examples above of plotting collections of spectra were done
with the defaults plot.data = "as.is"
. We can also plot a
row-wise summary (wavelength by wavelength) of the spectra in the
collection, here the mean
of the spectra. Currently
implemented only for spectra with identical wavelength vectors and of
the same class.
autoplot(two_suns.mspct, plot.data = "mean")
In the case the spectra plotted have been previously normalized or
scaled, the y-axis label will reflect this. In the case of
normalized spectral data, and transmittance, reflectance and absorptance
spectra expression as percent is supported. Finally, it is possible to
normalize spectra on-the-fly by passing an argument to parameter
norm
. The default for norm
varies with the
type spectrum.
autoplot(sun.spct, norm = "max")
autoplot(sun.spct, norm = 400, pc.out = TRUE)
### Summary quantities in labels
Although the defaults provide a useful plot, the
autoplot()
methods accepts arguments for several parameters
that allow to tweak the looks and contents of the plots without explicit
manipulation of the spectral data. Numerical summaries can be added
automatically to plots only when a single spectrum is plotted per plot
panel.
In this first example we pass "mean"
as argument to
label.qty
, to print means instead of integrals in the
labels. Note that the units and quantity labels for the waveband
summaries have also changed.
autoplot(sun.spct, label.qty = "mean")
Two label.qty
values need explanation. The first one,
"relative"
displays in labels the relative contribution of
the integral of each waveband, to the sum of the integrals of all
wavebands. The second one, "contribution"
displays in
labels the integral of each waveband divided by the integral of the
whole spectrum. Consequently, this second option should be interpreted
with caution, as the spectral data is unlikely in many cases to include
the whole emission or absorption spectrum of a source. Using
"relative.pc"
or "contribution.pc"
results in
the corresponding values being expressed as percentages.
autoplot(sun.spct, label.qty = "contribution")
autoplot(sun.spct, label.qty = "relative")
Which annotations are included can be controlled through
parameter annotations
of the autoplot()
methods, taking a vector of character strings as argument. Three values
have special meaning if at the head of the vector (with index = 1):
"="
means override the current defaults with the
annotations that follow in the vector, "+"
means add to the
current default the annotations that follow, and "-"
means
remove from the current default the annotations that follow. A
NULL
value means use package-defined defaults as is,
""
means no annotations, and "reserve.space"
means no annotations, but expand axis limits and set identity scales
ready for manually adding annotations. Used together with
"-"
, "title*"
, "peaks*"
and
"valleys*"
are wildcards that remove all flavours
of each of these annotations. In cases when the intention is to both add
and remove annotations from the default, the argument to parameter
annotations
can be a list of character vectors, which are
interpreted as above but operated upon sequentially.
Which annotations are included by default can be changed by setting R
option "photobiology.plot.annotations"
to a character
vector with the names of the desired default annotations. Function
set_annotations_default()
allows to set this option using
the same syntax as described for parameter annotations
.
annotation | default for classes | overrides |
---|---|---|
“boxes” | all | “segments” |
“segments” | none | “boxes” |
“color.guide” | all | |
“peaks” | all | “peak.labels” |
“peak.labels” | none | “peaks” |
“valleys” | none | “valley.labels” |
“valley.labels” | none | “valleys” |
“wls” | none | “wls.labels” |
“wls.labels” | none | “wls” |
“labels” | all | |
“summaries” | source_spct , response_spct ,
filter_spct , reflector_spct |
|
“boundaries” | raw_spct |
|
“title” | none | |
“title:type” | none | |
“title:type:type” | none | |
“title:type:type:type” | none |
Titles come in different flavours. Package ‘ggplot2’ supports titles,
subtitles and captions. The "title"
as argument to
parameter annotation
of autoplot()
methods and
of function autotitle()
takes up to three optional
modifiers separated by colons that can be used to specify the contents
of the automatic title, subtitle and caption. Currently
supported modifiers are shown in the table below. If the metadata item
is not stored in the plotted spectral object, the title or subtitle will
show NA
. See the documentation of packages ‘photobiology’
and ‘ooacquire’ for information on how to set and unset attributes of
spectral objects. To add an arbitrary title and/or subtitle to a plot,
use either function ggtitle()
or function
labs()
from package ‘ggplot2’.
Modifier | text source used |
---|---|
objt |
name of the object plotted |
class |
class of the plotted object |
what |
what.measured attribute |
when |
when.measured attribute |
where |
where.measured attribute |
how |
how.measured attribute |
inst.name |
spectrometer name |
inst.sn |
spectrometer serial number |
comment |
comment attribute |
none |
no title, no subtitle or no caption |
For example "title:objt"
, the default for
"title"
, adds a title with the name of the object being
plotted. what
, when
, where
and
how
use these attributes if available. For example
"title:what:when" will use the
what.measuredattribute for the title and the
when.measured`
attribute for the subtitle.
We can add an annotation to the defaults.
autoplot(sun.spct,
annotations = c("+", "title:objt:when:where"))
We use “none” as a filler so that only subtitle and caption are added to the plot.
autoplot(sun.spct,
annotations = c("+", "title:none:what:where"))
In this case "boundaries"
, an annotation that adds a
horizontal dashed line and does not override any other annotation.
autoplot(sun.spct,
annotations = c("+", "boundaries"))
We can list all the annotations to be included in a plot, in which
case "="
is optional so as to maintain compatibility with
earlier versions.
autoplot(sun.spct,
annotations = c("=", "labels", "summaries", "color.guide", "peaks", "boundaries"))
As indicated in the table above, some annotations override other
annotations which fulfil a similar role. Here "segments"
overrides "boxes"
, in the default.
autoplot(sun.spct,
annotations = c("+", "segments"))
We can also remove some of the default annotations on a case by case basis.
autoplot(sun.spct, annotations = c("-", "summaries", "peaks"))
The behaviour of some annotations can be tweaked. Below we add
"valleys"
as annotations, and control with
span
how close to each other are the peaks and valleys
found.
autoplot(sun.spct, annotations = c("+", "valleys"), span = 41)
The annotations "peak.labels"
and
"valley.labels"
override "peaks"
and
"valleys"
. They use the repulsive geometry
geom_label_repel
from package ‘ggrepel’.
autoplot(sun.spct,
annotations = list(c("+", "peak.labels"),
c("-", "boxes", "summaries", "labels")),
span = 51)
autoplot(sun.spct,
annotations = list(c("+", "valley.labels"),
c("-", "peaks")),
span = 51)
autoplot(sun.spct, annotations = c("+", "peak.labels", "valley.labels"), span = 51)
Passing ""
as argument to annotations
results in a plot with no annotations, and no scales set.
autoplot(sun.spct, annotations = "")
Passing "reserve.space"
as argument to
annotations
results in a plot with no annotations, but
scales set and expanded so as to receive annotations.
autoplot(sun.spct, annotations = "reserve.space")
The size of the font used for the annotations is controlled by
argument text.size
.
autoplot(sun.spct, annotations = c("=", "segments", "labels", "color.guide"),
text.size = 3.5)
Argument ylim
allows to mannually set the limits of the
\(y\) axis using the same syntax as in
package ‘ggplot2’. The annotations are still automatically possitioned,
and the range extended to make space for them. In other words the values
passed to ylim
still give the “space” available for
plotting data.
autoplot(sun.spct, ylim = c(NA, 1))
Arguments range
and w.band
play very different
roles. The first one determines the range
of wavelengths to
include in the data plotted, which is slightly different to the effect
of ggplot2::xlim()
as range
is used to
trim the spectral data before passing it to
ggplot
, using interpolation when needed (see
photobiology::trim_wl()
). The second one,
w.band
is only used for the annotations and
decorations. The default for range
is always the range of
the spectrum being plotted.
Which wavebands are used by default can be changed by setting R
option "photobiology.plot.bands"
to a single waveband
object or to a list waveband objects. Function
set_w.band_default()
allows to set this option using the
same syntax as described for parameter w.band
.
autoplot(sun.spct, range = VIS())
autoplot(sun.spct, w.band = PAR())
autoplot(sun.spct, w.band = CIE())
NULL
as argument for w.band
is replaced by
a waveband covering the full range of the spectral data.
autoplot(sun.spct, w.band = NULL)
The whole range is the range plotted, which is controlled by
the argument passed to range
.
autoplot(sun.spct, w.band = NULL, range = c(400,700))
The argument passed to range
can also be a
waveband
or and spectrum, in which case their wavelength
range is used.
autoplot(sun.spct, w.band = NULL, range = PAR())
autoplot(sun.spct, w.band = PAR(), range = PAR())
autoplot(sun.spct, w.band = VIS_bands(), range = VIS())
The time unit is also stored in the metadata, as demonstrated here. The units in axis labels have changed to the units used in the spectral data.
getTimeUnit(sun.daily.spct)
## [1] "day"
autoplot(sun.daily.spct)
Even though the autoplot()
methods can return a finished
plot, the returned object is a ggplot
object and can be
built upon by adding additional elements like facets,
aesthetics and even additional layers. We pass
idfactor = NA
to suppress the mapping of the spectra to
linetype
.
autoplot(two_suns.spct, idfactor = NA) + facet_wrap(~spct.idx)
It is possible to construct and bind the spectra on-the-fly, and to
use arbitrary variable names for the index factor. This works
automatically as long as row binding is done with function
rbindspct()
which saves the name of the factor.
<-
filter_no_yes.spct rbindspct(list(sun = sun.spct, filtered = yellow_gel.spct * sun.spct),
idfactor = "Source")
autoplot(filter_no_yes.spct)
In the examples above the source_spct
object
sun.spct
was used. The autoplot()
methods for
other spectral classes have slight differences. We show some examples
for filter_spct
objects. For a long-pass filter the
wavelength at half maximum is more interesting than peaks or
valleys.
autoplot(yellow_gel.spct,
annotations = list(c("-", "peaks"), c("+", "wls")))
By default transmittance, reflectance and absorptance are expressed as fractions of one, as in the plot above, but optionally percents can be plotted.
autoplot(yellow_gel.spct, pc.out = TRUE,
annotations = list(c("-", "peaks"), c("+", "wls")))
In many cases it is possible to convert on-the-fly the quantity plotted. In this case, given that the data are clipped as absorbance, a fixed target of A = 2 is appropriate.
autoplot(yellow_gel.spct, plot.qty = "absorbance", wls.target = 2,
annotations = list(c("-", "peaks"), c("+", "wls")))
If one needs to, one can add a suitable stat using ‘local’ data. A peak annotation could be added manually.
autoplot(sun.spct) + geom_spct(fill = color_of(sun.spct)) +
geom_spct(data = yellow_gel.spct * sun.spct, color = "black",
fill = color_of(yellow_gel.spct * sun.spct))
The examples above use an emission spectrum. All the spectral classes defined in package ‘photobiology’ are supported, however.
In the case of quantities like transmittance which have a certain range of valid values, both upper and lower boundaries are highlighted, but in other cases only one, or even none depending on the possible valid ranges for the spectral quantities.
autoplot(yellow_gel.spct, annotations = c("+", "boundaries"))
In the case of raw instrument counts data, if the spectral object contains an instrument descriptor as metadata, the upper boundary is set to the maximum counts of the detector.
autoplot(white_led.raw_spct, annotations = c("+", "boundaries"))
Changes in ‘dplyr’ have broken the next two
examples. Both raw_spct
and cps_spct
objects contain multiple data columns when integration time bracketing
has been used during data acquisition. In such cases, if one wants to
plot only one of the raw spectra, method select()
from
package ‘dplyr’ should be used instead of subscripting
([ ]
) so as to preserve the metadata. In addition renaming
of the variable is needed as shown below when a single column is
extracted.
autoplot(dplyr::select(white_led.raw_spct, w.length, counts = counts_1),
annotations = c("+", "boundaries"))
autoplot(dplyr::select(white_led.raw_spct, w.length, counts_1, counts_3),
annotations = c("+", "boundaries"))
If the supplied data include off-range values such as negative irradiance or fractional transmittance, reflectance, or absorptance outside the zero to one range the exceeded boundary is highlighted in red.
# Not run so as to pass CRAN checks!!
autoplot(yellow_gel.spct - 0.01, annotations = c("+", "boundaries"))
Using colors is slightly more involved as the identity scale is in
use for color in annotations. For this same reason no color key in
generated automatically. (In the case of more than two spectra it is
easier to use plyr::mapvalues
instead of several nested
ifelse
calls.)
autoplot(two_suns.mspct) +
aes(color = ifelse(spct.idx == "sun1", "darkgreen", "darkred"))
Plots created with autoplot()
methods are
ggplot
objects and can be customized, bearing in mind that
any added layers will be plotted on top or existing layers (that is
unless we make use of methods from package ‘gginnards’ that allow
insertion of layers at any position in a ggplot
object).
Here we replace the default peaks annotations with a custom one, but still take advantage of other defaults like nice axis labels and other annotations.
autoplot(two_suns.mspct, annotations = c("-", "peaks")) +
stat_peaks(span = NULL, color = "red") +
stat_peaks(span = NULL, geom = "text",
label.fmt = "max at %3.1f nm",
vjust = -0.5, hjust = 0,
color = "red", size = 3)
A autoplot()
method for waveband
objects is
also provided.
autoplot(VIS())
autoplot(CIE(), range = CIE(), annotations = c("-", "color.guide"))
autoplot(DNA_N(), range = c(270, 420), annotations = c("-", "color.guide"))