Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Visualising acoustic data

This practical introduces some simple techniques for visualising acoustic data in R by generating spectrograms from field recorder inputs. We can start by cleaning up your R environment and loading the required packages,

# Clear your global environment
rm(list = ls())

#load packages
library(tuneR)
library(seewave)

Now we need to get the path to a WAV file - we will use one of the Monkswood files. The data directory contains a set of files recorded across dawn on a single day.

#Check which sound files are in your directory
monkswood_files <- list.files(
    path='../data/Acoustics/Monkswood_dawn', pattern = "wav", full.names=TRUE
)
length(monkswood_files)
Loading...
head(monkswood_files)
Loading...

We can read in the first file and then look at some brief details on the kind of acoustic data in the file:

soundfile <- readWave(monkswood_files[1])

# Print the object to show details
print(soundfile)

Wave Object
	Number of Samples:      2880000
	Duration (seconds):     60
	Samplingrate (Hertz):   48000
	Channels (Mono/Stereo): Mono
	PCM (integer format):   TRUE
	Bit (8/16/24/32/64):    16 

The recording contains a wider range of frequencies than we want to use, so we can apply a simple band pass filter using the seewave::fir() function to keep the the main bird calling frequencies.

# Filter out unwanted frequencies using 'fir()' function
soundfile <- fir(wave = soundfile,
                 from = 1000, # lower bound frequency in Hz
                 to = 20000, # upper bound frequency in Hz
                 bandpass = TRUE, output = "Wave")

We can then use the seewave::spectro() function to visualise the intensity of different frequencies through time - a spectrogram.

spectro(wave = soundfile, fastdisp=TRUE)
plot without title

The seewave::spectro() function can be customised to show different parts of the WAV file, filtering by frequency (flim) or time (tlim) limits. The plot below zooms in on a 10 second section between 1 and 8 kHz:

spectro(wave = soundfile, fastdisp=TRUE,
        flim = c(1,8), # Set frequency limits of the spectrogram (kHz)
        tlim = c(10,20), #Set displayed time limits of the recording (sec)
        scale = TRUE, # Keeps the amplitude scale bar (FALSE to remove)
        colgrid = "gray", # Changes colour of the background grid
        palette = temp.colors, # Changes the colour palette
        dB="max0",
        cex.axis = 1.5, # Increase the axes label size
        cex.lab = 2) # Increase axes titles size)
plot without title

The next plot zooms in further to catch a specific call between 14 and 15 seconds into the recording:

spectro(wave = soundfile, fastdisp=TRUE,
        flim = c(1,8), # Set frequency limits of the spectrogram (kHz)
        tlim = c(14,15), #Set displayed time limits of the recording (sec)
        scale = TRUE, # Keeps the amplitude scale bar (FALSE to remove)
        colgrid = "gray", # Changes colour of the background grid
        palette = temp.colors, # Changes the colour palette
        dB="max0",
        cex.axis = 1.5, # Increase the axes label size
        cex.lab = 2) # Increase axes titles size)
plot without title

Finally, you can start a graphics device before creating the plot to export a spectrogram to file. The tricky part here is usually choosing an output file size in pixels that gives a good result.

# Start the graphics device
jpeg("outputs/Spectrogram_zoomed.jpg", width = 900, height = 500)

# Plot the spectrogram
spectro(wave = soundfile, flim = c(1,8),
        tlim = c(14,15),
        scale = TRUE,
        colgrid = "gray",
        palette = temp.colors,
        dB="max0",
        cex.axis = 1.5,
        cex.lab = 2
)
# Close the device to save the file
dev.off()
Loading...

The graphic below shows the exported JPEG file.

Display exported graphic