ggspectra
0.1.6.9005Package ggspectra
extends ggplot2
with stats, geoms and annotations suitable for light spectra. It also defines ggplot()
and plot()
methods specialized for the classes defined in package photobiology
for storing different types of spectral data.
The new elements can be freely combined with methods and functions defined in packages ggplot2
, scales
, ggrepel
and cowplot
.
Although the package uses internally ggplot2
, photobiology
and photobiologyWavebands
it does not re-export these packages, which need to loaded if used.
library(ggplot2)
library(photobiology)
library(photobiologyWavebands)
library(ggspectra)
We bind two spectra, to later on demonstrate grouping.
two_suns.spct <- rbindspct(list(sun1 = sun.spct, sun2 = sun.spct * 2))
We change the default theme.
theme_set(theme_bw())
The only difference between these specializations and the base ggplot()
method is that the aesthetics for \(x\) and \(y\) have suitable defaults. These are just defaults, so if needed they can still be supplied with a mapping
argument with an user-defined aes()
.
ggplot(sun.spct) + geom_line()
It is possible to the defaults by means of +
and aes()
as shown below.
ggplot(two_suns.spct) + aes(color = spct.idx) + geom_line()
If a mapping is supplied directly through ggplot
, \(x\) and \(y\) should be included.
ggplot(two_suns.spct, aes(w.length, s.e.irrad, color = spct.idx)) + geom_line()
In the case of ggplot.source_spct()
an additional parameter allows setting the type of units to use in the plot. This not only sets a suitable aes()
for \(y\) but also if needed converts the spectral data. The two possible values are "energy"
and "photon"
and the default, depends on option photobiology.radiation.unit
.
ggplot(sun.spct, unit.out = "photon") + geom_line()
ggplot(yellow_gel.spct) + geom_line()
In the case of ggplot.filter_spct()
the additional parameter is called plot.qty
and allows choosing between "transmittance"
and "absorbance"
.
ggplot(yellow_gel.spct, plot.qty = "absorbance") + geom_line()
The names of the additional parameters are consistent with those by method plot()
in this package and in the now deprecated package photobiologygg
.
Several ggplot
stats are defined by this package. All of them target light spectra, as they expect \(x\) to represent wavelengths expressed in nanometres. However, they should behave correctly as long as this is true, with any ggplot
object, based on any data format acceptable to ggplot
. The name of the original variable is irrelevant, and it is the user responsibility to supply the correct variables through aes()
. Of course, when using the spectral classes defined in package photobiology
the defaults easy this task.
These stats do not fit peaks, simply search for local maxima and local minima in the data as supplied. The stats set several aesthetics based on calculated values. Not all of these are used by the default geom, make using other geoms easy. Furthermore text labels are formatted with sptintf()
and these two stats accept format definitions through parameter label.fmt
. Both the \(x\) and \(y\) values at the maxima or minima are returned. The stats use internally function photobiology::find_peaks()
and arguments are passed down to it.
ggplot(sun.spct) + geom_line() + stat_peaks()
Because of the conversion, the location of maxima and minima when an spectrum is expressed in photon and energy based units may differ. This is expected and not a bug.
ggplot(sun.spct, unit.out = "photon") + geom_line() + stat_peaks()
The complement to stat_peaks()
is stat_valleys
.
ggplot(sun.spct) + geom_line() + stat_valleys()
One of the values calculated and mapped is the colour as seen by humans corresponding to the wavelength at the location of peaks and valleys. The colour is mapped to the fill
aesthetic, so using a ‘filled’ shape results in a colourful plot. The identity scale is needed so that the correct colours are displayed using the colour definitions in the calculated data instead of a palette.
ggplot(sun.spct) + geom_line() +
stat_peaks(shape = 21) + scale_fill_identity()
We can use any of the aesthetics affecting the default geom, "point"
, and also with other _geom_s.
ggplot(sun.spct) + geom_line() +
stat_peaks(span = 21, shape = 4, color = "red", size = 2) +
stat_peaks(span = 21, color = "red", geom = "rug", sides = "b")
We can use several other geoms as needed, demonstrated here with geom "text"
.
ggplot(sun.spct) + geom_line() +
stat_peaks(span = 21, geom = "text")
The same stat can be included more than once in the same plot, using different geoms. We here in addition demonstrate the use of several different parameters. The span
argument determines the number of consecutive observations tested when searching for a local extreme, and it should be an odd integer number. In addition we here demonstrate the use of a geom new to ggplot2
2.0.0 called "label"
which again results in colourful labels by default.
ggplot(sun.spct) + geom_line() +
stat_peaks(shape = 21, span = 25, size = 2) + scale_fill_identity() +
stat_peaks(geom = "label", span = 25, vjust = "bottom", size = 3,
color = "white")
Setting span
to NULL
results in the span set to the range of the data, and so in this case the stat returns the global extreme, instead of a local one. In this case we use geoms "vline"
and "hline"
taking advantage that suitable aesthetics are set by the stats.
ggplot(sun.spct) + geom_line() +
stat_peaks(span = NULL, geom = "vline", linetype = "dotted") +
stat_peaks(span = NULL, geom = "hline", linetype = "dotted")
By default the label
aesthetic is mapped to a calculated label ..x.label..
giving the wavelength in nanometres. This mapping can be changed to give to a label giving the \(y\)-value at the peak.
ggplot(sun.spct) + geom_line() +
stat_peaks(span = 21, geom = "text", aes(label = ..y.label..))
As aesthetics can use values computed on-the-fly we can even use paste()
to map a label that combines both values and adds additional text.
ggplot(sun.spct) + geom_line() +
stat_peaks(span = NULL) +
stat_peaks(span = NULL, geom = "text", vjust = -0.5, size = 2.5,
aes(label = paste(..y.label.., "at", ..x.label.. , "nm")))
Finally we demonstrate that both stats can be simultaneously used. One can also choose to use different spans as demonstrated here, resulting in more maxima being marked by points than labelled with text.
ggplot(sun.spct) + geom_line() +
stat_peaks(span = 21, geom = "point", colour = "red") +
stat_valleys(span = 21, geom = "point", colour = "blue") +
stat_peaks(span = 51, geom = "text", colour = "red",
vjust = -0.3, label.fmt = "%3.0f nm") +
stat_valleys(span = 51, geom = "text", colour = "blue",
vjust = 1.2, label.fmt = "%3.0f nm")
This final example shows a few additional tricks used in the case to mark and label the maximum of the spectrum. This example also demonstrates why it is important that these are stats. The peaks are searched and labels generated once for each group, in this case each facet.
ggplot(two_suns.spct) + aes(color = spct.idx) +
geom_line() + ylim(NA, 1.8) +
stat_peaks(span = NULL, color = "black") +
stat_peaks(span = NULL, geom = "text", vjust = -0.5, size = 3,
color = "black",
aes(label = paste(..y.label.., "at", ..x.label.. , "nm"))) +
facet_grid(spct.idx~.)
This stat calculates the colour corresponding to each \(x\)-value (assumed expressed in nanometres) and adds it to the data. It does not summarize the data like stat_summary()
nor does it subset the data like stat_peaks
, consequently the plot does not require any additional geom to have all observations plotted. It sets both color and fill aesthetics to a suitable default.
ggplot(sun.spct) +
stat_color() + scale_color_identity()
By use of a filled shape and adding a black border by overriding the default color aesthetic and over-plotting these point on top of a line, we obtain a better separation from the background.
ggplot(sun.spct) +
geom_line() +
stat_color(shape = 21, color = "black") +
scale_fill_identity()
With a trick using many narrow bars we can fill the area under the line with a the calculated colours. This works satisfactorily as the data set has a small wavelength step, as in this case we are using a bar of uniform colour for each wavelength value in the data set.
ggplot(sun.spct) +
stat_color(geom = "bar") +
geom_point(shape = 21, color = "black", stroke = 1.2, fill = "white") +
scale_fill_identity() +
scale_color_identity() +
theme_bw()
As final example we demonstrate a plot with facets and shape based groups.
ggplot(two_suns.spct) + aes(shape = spct.idx) +
stat_color() + scale_color_identity() +
geom_line() +
facet_grid(spct.idx~., scales = "free_y")
Our stat_wl_summary()
is quite different to ggplot2
s stat_summary()
. One could criticize that it calculates summaries using a grouping that is not based on a ggplot aesthetic. This is a deviation from the grammar of graphics but allows the calculation of summaries for an arbitrary region of the range of \(x\)-values in the spectral data.
The summary is calculated for a range of wavelengths, and the range
argument defaults to the range of wavelengths in each group defined by other aesthetics. The default geom is "text"
.
ggplot(sun.spct) + geom_line() + stat_wl_summary()
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
We can optionally supply an argument for range
to limit the summary to a certain part of the spectrum, in which case the use of the default "text"
geom is misleading. We add the line last so that it is drawn on top of the rectangle.
ggplot(sun.spct) +
stat_wl_summary(range = c(300,350), geom = "rect") +
geom_line()
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
Here we show how to add horizontal line and label for the overall mean, by adding the same stat twice, using different values for geom
.
ggplot(sun.spct) +
geom_line() +
stat_wl_summary(geom = "hline", color = "red") +
stat_wl_summary(label.fmt = "Mean = %.3g", color = "red", vjust = -0.3)
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
Or we can add the aesthetic twice with two different geoms to get the value plotted as a rectangular area and the value as formatted text. We use vjust
to move the text above the end of the bar, instead of it being centred on the value itself.
ggplot(sun.spct) +
stat_wl_summary(range = c(400,500), geom = "rect", alpha = 0.2, fill = color(450)) +
stat_wl_summary(range = c(400,500), label.fmt = "Mean = %.3g", vjust = -0.3, geom = "text") +
geom_line()
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
An example using the color
aesthetic for grouping and moving the text label down. Setting
ggplot(two_suns.spct) + aes(color = spct.idx) +
geom_line() +
stat_wl_summary(geom = "hline") +
stat_wl_summary(label.fmt = "Mean = %.3g", vjust = 1.2, show.legend = FALSE) +
facet_grid(spct.idx~.)
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
Same example as above but using a free scale for \(y\), still working as expected.
ggplot(two_suns.spct) + aes(color = spct.idx) +
geom_line() +
stat_wl_summary(geom = "hline") +
stat_wl_summary(label.fmt = "Mean = %.3g", vjust = 1.2, show.legend = FALSE) +
facet_grid(spct.idx~., scales = "free_y")
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
## Warning: Computation failed in `stat_average()`:
## unused argument (default.range = range(data$x))
Our stat_wb_mean()
is quite different to ggplot2
s stat_summary()
. One could criticize that it calculates summaries using a grouping that is not based on a ggplot aesthetic. This is a deviation from the grammar of graphics but allows the calculation of summaries for an arbitrary waveband of the spectrum based on photobiology::waveband
objects, or lists of such objects. In contrast to stat_wl_summary()
this allows the use of several ranges, and also of different weighting functions. This function returns both mean and total values for each waveband. It differs from stat_wb_total()
only in the default aesthetics set.
The first example uses a waveband
object created on-the-fly and defining a range of wavelengths.
ggplot(sun.spct) +
stat_wb_mean(w.band = PAR(), geom = "rect", alpha = 0.5) +
stat_wb_mean(w.band = PAR(), geom = "text") +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
If a numeric vector or a spectrum is supplied as argument to waveband
, its range is calculated and used to construct a temporary waveband
object.
ggplot(sun.spct) +
stat_wb_mean(w.band = c(400,500), geom = "rect", alpha = 0.5) +
stat_wb_mean(w.band = c(400,500), geom = "text") +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
Lists of wavebands, either user-defined or as in this case using constructor defined in package photobiologyWavebands
can be also used.
ggplot(yellow_gel.spct) +
stat_wb_mean(w.band = Plant_bands(), geom = "rect", alpha = 0.7) +
stat_wb_mean(w.band = Plant_bands(), angle = 90, hjust = 0, geom = "text", ypos.fixed = 0.1,
aes(label = paste(..wb.name.., " = ", ..y.label.., sep = ""))) +
geom_line() +
scale_fill_identity() +
theme_bw()
Our stat_wb_total()
is quite different to ggplot2
s stat_summary()
. One could criticize that it calculates summaries using a grouping that is not based on a ggplot aesthetic. This is a deviation from the grammar of graphics but allows the calculation of summaries for an arbitrary waveband of the spectrum based on photobiology::waveband
objects, or lists of such objects. In contrast to stat_wl_summary()
this allows the use of several ranges, and also of different weighting functions. This function returns both mean and total values for each waveband. It differs from stat_wb_mean()
only in the default aesthetics set.
The first example uses a waveband
object created on-the-fly and defining a range of wavelengths.
ggplot(sun.spct) +
stat_wb_total(w.band = PAR(), geom = "rect", alpha = 0.5) +
stat_wb_total(w.band = PAR(), geom = "text") +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
If a numeric vector or a spectrum is supplied as argument to waveband
, its range is calculated and used to construct a temporary waveband
object.
ggplot(sun.spct) +
stat_wb_total(w.band = c(400,500), geom = "rect", alpha = 0.5) +
stat_wb_total(w.band = c(400,500), geom = "text") +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
Lists of wavebands, either user-defined or as in this case using constructor defined in package photobiologyWavebands
can be also used.
ggplot(yellow_gel.spct) +
stat_wb_total(w.band = Plant_bands(), geom = "rect", alpha = 0.4, color = "white",
ypos.fixed = 1) +
stat_wb_mean(w.band = Plant_bands(), geom = "text", label.fmt = "%1.2f",
ypos.fixed = 1) +
geom_line() +
scale_fill_identity() +
theme_bw()
The _stat_s in previous sections can be used for unweighted irradiances, but not for BSWFs. These irrad
_stat_s have additional formal parameters for passing metadata, and use method photobiology::irrad()
internally on a photobiology::source_spct
object constructed from the data for \(x\) and \(y\) aesthetics. Function stat_wb_sirrad()
is equivalent to stat_wb_mean()
and function stat_wb_irrad()
is equivalent to stat_wb_total()
following the same convention naming as in package photobiology
.
ggplot(sun.spct) +
stat_wb_irrad(w.band = PAR(), geom = "rect", alpha = 0.5,
unit.in = "energy", time.unit = "second") +
stat_wb_irrad(w.band = PAR(), geom = "text",
unit.in = "energy", time.unit = "second") +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
ggplot(sun.spct, unit.out = "photon") +
stat_wb_irrad(w.band = PAR(), geom = "rect", alpha = 0.5,
unit.in = "photon", time.unit = "second") +
stat_wb_irrad(w.band = PAR(), geom = "text",
unit.in = "photon", time.unit = "second",
aes(label = sprintf("%s = %.3g", ..wb.name.., ..yint.. * 1e6))) +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
ggplot(sun.spct) +
stat_wb_irrad(w.band = CIE(), geom = "rect", alpha = 0.5,
unit.in = "energy", time.unit = "second") +
stat_wb_irrad(w.band = CIE(), geom = "text",
unit.in = "energy", time.unit = "second") +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
ggplot(sun.daily.spct) +
stat_wb_irrad(w.band = CIE(), geom = "rect", alpha = 0.5,
unit.in = "energy", time.unit = "day") +
stat_wb_irrad(w.band = CIE(), geom = "text",
unit.in = "energy", time.unit = "day", label.mult = 1e-3) +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
ggplot(sun.spct, unit.out = "photon") +
stat_wb_irrad(w.band = VIS_bands(), geom = "rect", alpha = 0.5,
unit.in = "photon", time.unit = "second") +
stat_wb_irrad(w.band = VIS_bands(), geom = "text",
unit.in = "photon", time.unit = "second",
label.mult = 1e6, size = rel(2)) +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
ggplot(sun.spct) +
stat_wb_sirrad(w.band = PAR(), geom = "rect", alpha = 0.5,
unit.in = "energy", time.unit = "second") +
stat_wb_sirrad(w.band = PAR(), geom = "text",
unit.in = "energy", time.unit = "second") +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
ggplot(sun.spct, unit.out = "photon") +
stat_wb_sirrad(w.band = PAR(), geom = "rect", alpha = 0.5,
unit.in = "photon", time.unit = "second") +
stat_wb_sirrad(w.band = PAR(), geom = "text",
unit.in = "photon", time.unit = "second",
aes(label = sprintf("Total %s = %.3g", ..wb.name.., ..yint.. * 1e6))) +
stat_wb_sirrad(w.band = PAR(), geom = "text",
unit.in = "photon", time.unit = "second",
mapping = aes(label = sprintf("Mean %s = %.3g", ..wb.name.., ..ymean.. * 1e6)),
ypos.mult = 0.45) +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
ggplot(sun.spct) +
stat_wb_sirrad(w.band = CIE(), geom = "rect", alpha = 0.5,
unit.in = "energy", time.unit = "second") +
stat_wb_sirrad(w.band = CIE(), geom = "text",
unit.in = "energy", time.unit = "second") +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
ggplot(sun.daily.spct) +
stat_wb_sirrad(w.band = CIE(), geom = "rect", alpha = 0.5,
unit.in = "energy", time.unit = "day") +
stat_wb_sirrad(w.band = CIE(), geom = "text",
unit.in = "energy", time.unit = "day", label.mult = 1e-3) +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
ggplot(sun.spct) +
stat_wb_sirrad(w.band = VIS_bands(), geom = "rect", alpha = 0.5,
unit.in = "energy", time.unit = "second") +
stat_wb_sirrad(w.band = VIS_bands(), angle = 90, geom = "text",
unit.in = "energy", time.unit = "second", ypos.fixed = 0.05, hjust = 0,
aes(label = paste(..wb.name.., ..y.label.., sep = " = "),
color = "black")) +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
ggplot(sun.spct, unit.out = "photon") +
stat_wb_sirrad(w.band = VIS_bands(), geom = "rect", alpha = 0.5,
unit.in = "photon", time.unit = "second") +
stat_wb_irrad(w.band = VIS_bands(), angle = 90, geom = "text", label.mult = 1e6,
unit.in = "photon", time.unit = "second", ypos.fixed = 1e-7, hjust = 0,
aes(label = paste(..wb.name.., ..y.label.., sep = " = "),
color = "black")) +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
my.bands <- split_bands(c(300,800), length.out = 10)
ggplot(sun.spct) +
stat_wb_sirrad(w.band = my.bands, geom = "rect", alpha = 0.5,
unit.in = "energy", time.unit = "second") +
stat_wb_irrad(w.band = my.bands, angle = 90, geom = "text",
unit.in = "energy", time.unit = "second", ypos.fixed = 0.05, hjust = 0,
color = "black") +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
my.bands <- split_bands(c(300,800), length.out = 10)
ggplot(sun.spct, unit.out = "photon") +
stat_wb_sirrad(w.band = my.bands, geom = "rect", alpha = 0.5,
unit.in = "photon", time.unit = "second") +
stat_wb_sirrad(w.band = my.bands, geom = "text", angle = 90,
unit.in = "photon", time.unit = "second", label.mult = 1e6,
color = "black") +
geom_line() +
scale_color_identity() +
scale_fill_identity() +
theme_bw()
The stat_wl_summary()
and stat_wb_mean()
return a reduced data set with fewer rows than the original data. stat_wl_strip()
depending on the input, can also return a data set with more rows than the input data. This is the default behaviour, with w.band
with argument NULL
. This stat operates only on the variable mapped to the \(x\) aesthetic, a \(y\)-mapping is not required as input.
my.data <- data.frame(x = 300:800)
ggplot(my.data, aes(x)) + stat_wl_strip(ymin = -1, ymax = 1) +
scale_fill_identity()
The default geom is "rect"
which with suitable mappings of ymin
and ymax
aesthetics can be used to add a colour guide to the \(x\)-axis (if its scale maps wavelengths in nanometres). When w.band
is NULL
a long series of contiguous wavebands is generated to create the illusion of a continuous colour gradient.
ggplot(sun.spct) +
geom_line() +
stat_wl_strip(ymin = -Inf, ymax = -0.025) +
scale_fill_identity() +
theme_bw()
When a list of wavebands is supplied, it is used for the calculation of colours. These calculations do not use the spectral irradiance, they simply assume a flat spectrum, so the represent the colours of the wavelengths, rather than the colour of the light described by the spectral irradiance.
ggplot(sun.spct) +
geom_line() +
stat_wl_strip(w.band = VIS_bands(), ymin = -Inf, ymax = -0.025) +
scale_fill_identity() +
theme_bw()
stat_wl_strip()
can also used to produce a background layer with colours corresponding to wavebands. Here we use alpha = 0.5
to add transparency.
ggplot(sun.spct) +
stat_wl_strip(w.band = VIS_bands(), ymin = -Inf, ymax = Inf, alpha = 0.4) +
scale_fill_identity() +
geom_line() +
theme_bw()
By default an almost continuous colour gradient can be generated for the background.
ggplot(sun.spct) +
stat_wl_strip(alpha = 0.4, ymin = -Inf, ymax = Inf) +
scale_fill_identity() +
geom_line() +
theme_bw()
The stats described above can be used together to produce more complex plots. This is just one possibility out of a vast range. Be aware that when adding many layers to the same plot, the order of the layers and adjusting their transparency using the alpha
aesthetic is very important, and best tuned by trial and error.
ggplot(sun.spct, unit.out = "photon") +
stat_wl_strip(alpha = 0.4, ymin = -Inf, ymax = Inf) +
stat_wb_total(w.band = PAR(), color = "black", geom = "rect") +
stat_wb_total(w.band = PAR(), label.mult = 1e6,
geom = "text", color = "black",
aes(label = paste(..wb.name.., " = ", ..y.label.., sep = ""))) +
geom_line() +
scale_fill_identity() +
theme_bw()
A simple geom called "spct"
is defined. It differs from geom "area"
only in the default position
which is "stacked"
for geom "area"
and "identity"
for geom "spct"
which is usually better for spectra.
ggplot(sun.spct) + geom_spct()
Using as fill the color calculated from the spectral data is different to earlier examples in that the spectral irradiance is actually taken into account in the calculation of the colour, instead of just the wavelength range.
ggplot(sun.spct) +
geom_spct(fill = color(sun.spct))
ggplot(sun.spct * yellow_gel.spct) +
geom_spct(fill = color(sun.spct * yellow_gel.spct))
Some of the examples in previous sections can be simplified by use of wl_guide()
and wb_guide()
which add both the statistics and the scale, and provide a default mapping for both ymin
and ymax
. This is handy for simple plots, but it can generate spurious warnings due to the replacement of existing scales with identical ones. In general only one of wl_guide()
or wb_guide()
should be used in a plot, and each one, only once. They just save some typing for the simplest uses, but are not suitable for complex decorations.
The examples for stat_wl_strip
can be simplified by use of wl_guide()
which adds both the statistics and the scale, and provides default mappings for both ymin
(-Inf
) and ymax
(Inf
). Another important difference is that the "rect"
geom used cannot be set to a different one by the user.
ggplot(sun.spct) +
wl_guide(alpha = 0.4) +
geom_line()
ggplot(sun.spct) +
wl_guide(ymax = -0.025) +
geom_line()
This example produces a plot with a very different look than earlier ones, but can also be achieved with a very succinct statement.
ggplot(sun.spct) +
wl_guide() +
geom_spct(alpha = 0.75, colour = "white", size = 1)
In the next example we demonstrate a trick achieved by overploting two line of different width (size
) to make the spectrum visible on a background of variable luminosity.
ggplot(sun.spct) +
wl_guide() +
geom_line(size = 2, colour = "white") +
geom_line(size = 1, colour = "black") +
geom_hline(yintercept = 0, colour = "grey92") +
theme_bw()
The most automatic way of plotting spectral data stored in one of the classes defined in package photobiology
is to use the plot()
methods. These go much further than the plot()
method defined in base-R for numeric data, as these classes store metadata that 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 earlier in the User Guide. In contrast to earlier examples, here we obtain with a very simple statement a very complete and properly annotated plot of the solar spectrum at ground level.
plot(sun.spct)
Although the defaults provide a useful plot, the plot()
method accepts arguments for several parameters that allow to tweak the looks and contents of the plots significantly, without having to do any explicit manipulation of the spectral data.
This first example, shows means instead of integrals in the labels. Note that the units and quantity labels for the waveband summaries have also changed automatically.
plot(sun.spct, label.qty = "mean")
Two label.qty
values need explanation. The first one, "contribution"
uses for labels the relative contribution of the integral of each waveband, to the sum of the integrals of all wavebands. The second one, "participation"
uses for labels the integral for 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.
plot(sun.spct, label.qty = "contribution")
plot(sun.spct, label.qty = "relative")
plot(sun.spct, label.qty = "mean", unit.out = "photon")
plot(sun.spct, label.qty = "relative.pc")
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.
plot(sun.spct, unit.out = "photon")
Which annotations are included can be also controlled through parameter annotations
.
plot(sun.spct,
annotations = c("segments", "labels", "summaries", "color.guide"))
plot(sun.spct,
annotations = NULL)
plot(sun.spct, annotations = c("segments", "labels", "color.guide"))
The size of the font used for the annotations is controlled by argument text.size
.
plot(sun.spct,
annotations = c("segments", "labels", "color.guide"),
text.size = 3.5)
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 (see photobiology::trim_wl()
) the spectral data before passing it to ggplot
. The second one, w.band
is only used for the annotations and decorations. It should be however noted, that a waveband
object is a valid argument for both range
and w.band
.
plot(sun.spct, range = VIS())
plot(sun.spct, w.band = PAR())
plot(sun.spct, w.band = CIE())
plot(sun.spct, w.band = NULL)
plot(sun.spct, w.band = NULL, range = c(400,700))
plot(sun.spct, w.band = NULL, range = PAR())
plot(sun.spct, w.band = UVB(), range = c(400,700))
## Warning: Computation failed in `stat_color_guide()`:
## missing value where TRUE/FALSE needed
## Warning: Computation failed in `stat_wb_irrad()`:
## replacement has 1 row, data has 0
The time unit is also stored in the metadata, as demonstrated here. The units in axis labels have suitably adapted to the different units.
plot(sun.daily.spct)
Even though the plot()
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.
plot(two_suns.spct, label.qty = "mean") + facet_wrap(~spct.idx)
plot(two_suns.spct) + aes(linetype = spct.idx)
plot(yellow_gel.spct, pc.out = TRUE)
Here we demonstrate something that may look like a bug, but is not. The annotations are based only on the data supplied as argument to plot()
(or in other cases ggplot()
) because these are the only data visible in all layers. The data
argument in geom_spct()
only affects the data seen by this geom. This way of building a plot is very different than when using grouping within a single data set, and it is best to avoid it in most situations.
plot(sun.spct) + geom_spct(fill = color(sun.spct)) +
geom_spct(data = yellow_gel.spct * sun.spct, color = "black",
fill = color(yellow_gel.spct * sun.spct))
However, if one really needs to, one can add a suitable stat using ‘local’ data. As this is just a demonstration, I will avoid adding all the additional arguments needed to make the annotations of peaks match those produced by plot()
.
plot(sun.spct) + geom_spct(fill = color(sun.spct)) +
geom_spct(data = yellow_gel.spct * sun.spct, color = "black",
fill = color(yellow_gel.spct * sun.spct)) +
stat_peaks(data = yellow_gel.spct * sun.spct, color = "yellow",
ignore_threshold = 0.1, span = 21)
As with any ggplot
object, the ‘looks’ of the returned object depends on both the local and global ggplot
theme.
theme_set(theme_bw(8))
plot(yellow_gel.spct, annotations = "colour.guide")
theme_set(theme_bw())
two_suns.mspct <- source_mspct(list(sun1 = sun.spct, sun2 = sun.spct * 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(two_suns.mspct, plot))
Plot with one panel per spectrum by first converting the collection-of-spectra into a spectrum object.
plot(rbindspct(two_suns.mspct)) + facet_wrap(~spct.idx, ncol = 1)
Plot using grouping with tweaking of annotations by first converting the collection-of-spectra into a spectrum object.
plot(rbindspct(two_suns.mspct),
annotations = c("color.guide", "labels", "boxes", "peaks")) +
aes(linetype = spct.idx)
Plot using “lower-level” functions.
ggplot(rbindspct(two_suns.mspct)) +
aes(linetype = spct.idx) +
wl_guide(ymax = -0.05) +
geom_line()
A plot()
method for waveband
objects is also provided.
plot(VIS())
plot(CIE(), range = CIE())
plot(DNA_N(), range = c(270, 420))