package overview
dynaSpec: dynamic spectrogram visualizations
Marcelo Araya-Salas & Matthew R. Wilkins
2026-11-06
Source:vignettes/dynaSpec.Rmd
dynaSpec.Rmd
The dynaSpec
package creates dynamic spectrograms: spectrograms that move along with
the sound. They can be shown as interactive web pages or saved as
videos. This vignette shows the basic usage of all features. The article
Customizing
dynamic spectrograms on the package website shows how to customize
them. For detailed information on each function, please refer to the function
reference or use the help files within R (e.g.,
?dynaspec).
Installation
Install the latest development version from GitHub:
Web pages do not need any external software. To create video files dynaSpec uses ffmpeg, which must be installed and available in the system path (see the installation instructions in the README).
Layers
Dynamic spectrograms are built in layers, as ‘ggplot2’ graphs:
dynaspec() takes the sound, and layers are added with
+:
dynaspec(wave, flim = c(1, 10)) + # the sound (and frequency and time ranges)
ds_spectrogram(wl = 300) + # panels: spectrogram, oscillogram, envelope, spectrum
ds_oscillogram() +
ds_annotations(st) + # highlight parts of the sound
ds_captions("song", start = 0, end = 2) + # text shown during a time range
ds_theme(xlab = "Time (s)") + # customize axis titles, text and colors
ds_player(speeds = c(1, 0.5)) + # customize playback buttons of web pages
ds_scrolling(t.display = 1.7) # spectro style: ds_static() (default), ds_scrolling() or ds_paged()| Layer | What it does |
|---|---|
ds_spectrogram() |
Adds a spectrogram (window length, palette, amplitude range, …) |
ds_oscillogram(), ds_envelope()
|
Add an oscillogram or an amplitude envelope (above or below the spectrogram) |
ds_spectrum() |
Adds a power spectrum next to the spectrogram |
ds_overview() |
Adds a lower panel with the whole sound to scrolling spectrograms |
ds_annotations() |
Highlights parts of the sound with translucent boxes, borders and labels (e.g. from a selection table) |
ds_captions() |
Text at a fixed position shown during a time range, like subtitles |
ds_theme(), ds_theme_dark(), … |
Axis titles, fonts, colors of the figure and plot, and preset themes |
ds_player() |
Playback controls of web pages (speed slider, loop, volume, download, …) |
ds_static(), ds_scrolling(),
ds_paged()
|
Style of the dynamic spectrogram |
Printing a dynaspec object shows an interactive web
page: press play to watch the spectrogram along with the sound, click on
it to play from that point, and use the speed slider to slow the sound
down. In the R console web pages are shown in the RStudio viewer (or the
web browser), and in R Markdown and Quarto documents (like this
vignette) they are embedded in the document.
save_dynaspec() saves them as web pages, videos or images
(see Saving).
The examples use the songs of a brown-billed scythebill and a great antshrike (scrolling spectrograms) included in the package. Sounds can be ‘Wave’ objects or ‘.wav’ and ‘.mp3’ files.
Panels
Only the panels added as layers are shown. A spectrogram:
data("scythebill")
ds_scythebill <- dynaspec(scythebill, flim = c(0.2, 4)) +
ds_spectrogram(wl = 512, collevels = seq(-50, 0, 1), ovlp = 95)
ds_scythebillThe spectrogram background is the color of the lowest amplitude of
the palette (white for the default gray palette), so quiet parts of the
sound and the background look the same. Use
ds_spectrogram(colbg = ) to set another background.
Layers can be stored in an object (as ds_scythebill
above) and added later. A spectrogram with an oscillogram below it:
ds_scythebill + ds_oscillogram()Oscillograms and amplitude envelopes can go above or below the spectrogram, and a power spectrum can be added on its left or right side. An envelope above the spectrogram and a power spectrum on its right side:
ds_scythebill +
ds_envelope(position = "above") +
ds_spectrum(side = "right")Without ds_spectrogram() only the other panels are shown
(e.g. only the oscillogram), and dynaspec() alone shows an
empty panel with a time axis and the play line:
dynaspec(scythebill) + ds_oscillogram()flim sets the frequency range (in kHz) and
tlim the time range of the sound used (in s):
dynaspec(scythebill, flim = c(1.5, 5.5), tlim = c(1.1, 1.76)) +
ds_spectrogram(wl = 200, collevels = seq(-50, 0, 1))Styles
Static spectrograms
The default style: a line moves over the whole figure as the sound
plays, so ds_static() is not needed to create static
spectrograms (all examples above are static). It is used to change the
settings of static spectrograms, or to switch back to them from another
style (the last style added is used). Long sounds can be split in
several rows (rows; height sets the height of
each row), and play.line = FALSE hides the moving line:
data("antshrike")
ds_antshrike <- dynaspec(antshrike, flim = c(0.5, 4)) +
ds_spectrogram(wl = 256, collevels = seq(-50, 0, 1))
ds_antshrike +
ds_static(rows = 2, height = 350)Scrolling spectrograms
The spectrogram scrolls along a fixed play line, as in the Macaulay
Library. t.display sets the time window (in s) shown at
once, and ds_overview() adds a lower panel with the whole
sound, in which the part being shown is highlighted:
ds_antshrike <- dynaspec(antshrike, flim = c(0.5, 5.5)) +
ds_spectrogram(wl = 256, collevels = seq(-50, 0, 1))
ds_antshrike +
ds_overview() +
ds_scrolling(t.display = 2)Scrolling spectrograms show a single lower panel: an overview, an oscillogram or an envelope.
Paged spectrograms
The spectrogram is split into pages (t.display sets the
duration of each page), and a translucent box reveals the part of each
page being played, as in Adobe Audition’s spectral view. Pages turn as
the sound plays:
ds_scythebill + ds_paged(t.display = 1)Settings not supplied take the defaults of each style. For instance, paged spectrograms use the ‘inferno’ palette and no axes by default.
Playback
The speed slider slows the sound down. Slowing down also lowers the
pitch (as when slowing down a tape), which makes fast features such as
pulses easier to hear. The keep pitch button switches to
slowing down while keeping the original pitch. ds_player()
sets the speeds offered (the first one is the initial speed) and whether
the pitch is kept by default:
buttons adds more controls: a time readout (shown by
default), a seek bar, a zoom slider (scrolling spectrograms), a loop
button, a volume control, a button to download the sound and a full
screen button:
ds_scythebill +
ds_player(
buttons = c("progress", "time", "loop", "volume", "download", "fullscreen")
)Several players can be included in the same document or web page; only one sound plays at a time.
Highlighting and labeling sounds
ds_annotations() highlights parts of the sound with
translucent boxes, borders and labels (e.g. from a selection table of warbleR or ohun), and
ds_captions() adds text at a fixed position of the figure
shown during a time range, like subtitles. Both work in the three
styles, and are shown in the article Customizing
dynamic spectrograms.
Themes
ds_theme() sets the look of the figure in the same way
for all styles: axis titles, text sizes and fonts, colors of axes and
text, boxes, grid lines, backgrounds, the colors of the plot (e.g. the
spectrogram palette, used when not supplied in
ds_spectrogram()) and the colors of the player
controls:
dynaspec(scythebill, flim = c(1.5, 5.5)) +
ds_spectrogram(wl = 200, pal = viridis::mako, collevels = seq(-100, 0, 1)) +
ds_theme(
xlab = "Time (s)",
ylab = "Frequency (kHz)",
cex.lab = 1.3,
font.lab = 2
)Preset themes set several settings at once:
ds_theme_dark(), ds_theme_mako(),
ds_theme_presentation(), ds_theme_paper(),
ds_theme_minimal(), ds_theme_transparent(),
ds_theme_void(), ds_theme_xenocanto() and
ds_theme_macaulay(). Their settings can be changed in the
call:
ds_scythebill + ds_oscillogram() + ds_theme_dark(cex.lab = 1.3)ds_set_theme() sets a theme for all the spectrograms
shown afterwards (e.g. in all the code chunks of a document), as
ggplot2::theme_set(). Themes added to a spectrogram change
it (ds_theme()) or replace it (preset themes):
All the theme settings and preset themes are shown in the article Themes for dynamic spectrograms.
Saving web pages, videos and images
save_dynaspec() saves dynaspec objects. The
extension of the file sets the output:
-
.html: interactive web page, which can be shared as a single file or pasted into any web page -
.mp4: video, with the same settings. Videos can be used where web pages cannot, such as presentation slides (e.g. PowerPoint) or social media. ffmpeg must be installed to create videos (see the installation instructions in the README) -
.png: still image of static spectrograms, or one image per page of paged spectrograms
save_dynaspec(ds_scythebill, "scythebill.html")
save_dynaspec(ds_scythebill, "scythebill.png")
save_dynaspec(ds_scythebill, "scythebill_static.mp4")
save_dynaspec(ds_antshrike + ds_scrolling(t.display = 2), "antshrike_scrolling.mp4")Videos of static and paged spectrograms are created in a few seconds. Videos of scrolling spectrograms take longer, as every frame is rendered (a progress bar shows the progress).
Note that embedding sounds makes web pages larger (about 1.4 times
the size of the sound file), so cut (e.g. with tlim) or
downsample long recordings before creating web pages.
Embedding players in other web pages
Web pages created by save_dynaspec() are self-contained:
the images, the sound and the code of the player are embedded in the
file, so they work without R or a server (even offline, by opening the
file). They can be added to other web pages (e.g. a lab website, a
course page or GitHub Pages) in three ways:
-
As a page of its own, uploaded and linked, or shown
within another page with an
iframe. This is the safest option, as the styles of the page and the player do not affect each other, and it also works in site builders that remove scripts from pasted code:
-
Pasting the code of the player into the HTML of a
page. Without a file name,
save_dynaspec()returns only the code of the player (no page header), which can be saved and pasted. Several players can be included in the same page; only one sound plays at a time:
player_code <- save_dynaspec(ds_scythebill, play = FALSE)
writeLines(player_code, "scythebill_player.html")-
As a video (
.mp4), with the HTMLvideoelement (<video controls src="scythebill.mp4"></video>), in social media or in presentation slides. Videos have no speed controls or click-to-play, but work wherever videos do.
Pages that block scripts written within the page (with a strict
‘Content-Security-Policy’) show the spectrogram but not the player; use
an iframe in that case.
Session information
Click to see
#> R version 4.6.2 (2026-10-29)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 26.04.1 LTS
#>
#> Matrix products: default
#> BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so; LAPACK version 3.12.0
#>
#> locale:
#> [1] LC_CTYPE=C.UTF-8 LC_NUMERIC=C LC_TIME=C.UTF-8
#> [4] LC_COLLATE=C.UTF-8 LC_MONETARY=C.UTF-8 LC_MESSAGES=C.UTF-8
#> [7] LC_PAPER=C.UTF-8 LC_NAME=C LC_ADDRESS=C
#> [10] LC_TELEPHONE=C LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: UTC
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] seewave_2.2.4 dynaSpec_2.0.0.9000
#>
#> loaded via a namespace (and not attached):
#> [1] gtable_0.3.6 jsonlite_2.0.0 compiler_4.6.2 Rcpp_1.1.2
#> [5] stringr_1.6.0 bmp_0.3.1 signal_1.8-1 gridExtra_2.3.1
#> [9] jquerylib_0.1.4 png_0.1-9 systemfonts_1.3.2 scales_1.4.0
#> [13] textshaping_1.0.5 yaml_2.3.12 fastmap_1.2.0 ggplot2_4.0.3
#> [17] R6_2.6.1 igraph_2.3.4 knitr_1.52 MASS_7.3-66
#> [21] viridis_0.6.5 backports_1.5.1 checkmate_2.3.4 imager_1.0.8
#> [25] desc_1.4.3 readbitmap_0.1.5 tiff_0.1-12 bslib_0.12.0
#> [29] RColorBrewer_1.1-3 rlang_1.3.0 stringi_1.8.9 cachem_1.1.0
#> [33] xfun_0.62 fs_2.1.0 sass_0.4.10 S7_0.2.2
#> [37] otel_0.2.0 viridisLite_0.4.3 cli_3.6.6 magrittr_2.0.5
#> [41] pkgdown_2.2.1 digest_0.6.39 grid_4.6.2 lifecycle_1.0.5
#> [45] vctrs_0.7.3 evaluate_1.0.5 glue_1.8.1 farver_2.1.2
#> [49] tuneR_1.4.7 ragg_1.5.2 purrr_1.2.2 rmarkdown_2.32
#> [53] jpeg_0.1-11 pkgconfig_2.0.3 tools_4.6.2 htmltools_0.5.9