2.4 Plotting of spectral data

The VIBES Toolbox has comprehensive plot functionality for the following classes:

  • vibes.TimeBlocks
  • vibes.TimeSeries
  • vibes.FreqBlocks
  • vibes.FRFMatrix

This tutorial focuses on the plotting capabilities of the vibes.FRFMatrix and vibes.FreqBlocks classes.

All plot settings are available by using the Property, Value syntax. By default, the plot methods of the classes in the above configure the axes according to the units of the Channels and/or RefChannels.

Plotting transfer functions

An object of class vibes.FRFMatrix has lots of predefined plot settings for easy and convenient visualization of the data. This ranges from logarithmic, phase, dB(A), Nth-octave spectra, sum-levels, and many more.

% Load a FRFMatrix object of which FRFs have to be visualized.
Y = vibes.load('VIBES,Examples,Datasets','mat','Benchmark','YA.FRFMatrix.mat');

Create a figure and plot a transfer function. By default, an amplitude plot is shown with semilog Y-scale (base 10). One can select specific FRFs by inserting the Channel/RefChannel indices as input arguments, in this example the 1st Channel and 3rd RefChannel, in a frequency range of 0-1000 Hz.


Y.plot(1,3,[0 1000]);

Plotting a transfer function

The first two arguments, hence Channel and RefChannel, accept an array of class vibes.Channel as well. This can be especially useful for smart selection of the (Ref-)Channels using the vibes.Channel/find and/or vibes.Channel/select methods on the properties of the Channel objects.

Here’s an example of partial and exact channel matching using the logical == in the latter case:

ch_i = Y.Channels.select('Name','Sensor 1');
idx_j = Y.RefChannels.find('Name','==','Impact 1');

Y.plot(ch_i,idx_j,[0 1000]);

Plotting multiple channels of an FRF

Plot settings

Choose plot settings with property and value arguments. The plot method accepts, amongst others, the following properties:

  1. PlotType: Select a plot type. See below for the options
  2. Style: Plot Curve style, e.g. 2b- as LineSpec shorthands: LineWidth,Color,LineStyle
  3. Label: Custom legend label
  4. Smoothing: Linear or logarithmic smoothing

Changing plot settings

The plot function also accepts a structure S with properties as its fields:

S = struct();

S.PlotType  = 'log';
S.Label     = 'Linear smoothing';
S.Style     = '2b-';
S.Smoothing = 10;

Y.plot(1,3,[100 3000], S);

Changing plot settings using a structure

The short-hand options for PlotType are:

  • log,maglog,loglog,phase,magphase,area,...
  • db,magdb,logdb,dba,magdba,logdba,... oct,oct3,oct12,...
  • octdb,oct3db,oct12db,... octdba,oct3dba,oct12dba,...
  • sum,sumlog,sumdb,suma,sumloga,sumdba;


You can add linear (i.e. moving average) smoothing when Smoothing is a positive scalar:

S.Smoothing = 10;

Logarithmic smoothing when Smoothing is a scalar fraction < 1. This is interpreted as N-th octave smoothing, N being the denominator of the octave fraction, for instance:

S.Smoothing = 1/3;

S.Label = '3rd-octave smoothing';
S.Style = '2g--';

hold on
Y.plot(1,3,[100 3000],S);

Linear and logarithmic smoothing

Octave plots

Nth-octave plots are available as well; note that these are not energy-normalized (the energy-normalized variant is chosen by setting the option Density to PSD):

hold on
Y.plot(1,3,[100 3000], 'plottype','oct3','Style','2y--','Label','3rd-octave plot');
xlim([100 3000])

Plotting octaves

Spectrum objects

All of the functionality mentioned above can also be accessed through the vibes.graph.Spectrum class. A vibes.graph.Spectrum object is created automatically for every plot you make. You can access it by right-clicking on a line in your spectrum plot. You can change settings from the context menu such as the plot type, plot style, and smoothing.

You can also access the spectrum object from your workspace. Edit some properties of the spectrum plot and notice how the figure updates accordingly.

h = Y.plot();

h.Style = '2r--';

Editing properties of the spectrum plot

Frequency Block plots

The same possibilities are available for plotting of data from vibes.FreqBlocks objects. This will be illustrated using the data from a vehicle measurement.

% Load the data
FB = vibes.load('VIBES,Examples,Datasets','mat','i3','i3Measurement.FreqBlocks.mat');
close all

When plotting measurement data, it is often useful to define two structures: one for the plot options and one for the plot style.

plotOpts = struct();

plotOpts.PlotType = 'oct';
plotOpts.XLim = [100 2000];

% Define two structures for the styling.
st1 = struct();
st1.Style = '1b-';

st2 = struct();
st2.Style = '2k:';

vibes.figure('Spectra'); clf

% Plot the acceleration channels using one style
FB.plot(1:2,3,plotOpts,st1); hold on

% Plot the microphone channel with the same options but a different style

Plotting measured data

Waterfall plots

In order to visualize the spectra of all blocks at once, a waterfall plot can be created. This is done through the plot3d method. The [] argument means all blocks should be included in the plot. The plot3d method returns a vibes.graph.WaterfallPlot object, which can be used in a similar way to the vibes.graph.Spectrum objects discussed before.

vibes.figure('Waterfall diagram'); clf

% Create a waterfall plot
wf = FB.plot3d(1,[],[100 3000]);

% Set limits of the values (YLim)
wf.YLim = [60 100];

A waterfall plot

Waterfall plots are not limited to have time on their Z-axis. In fact, any operational data can be used if it is stored in the blocks of the dataset. This will be illustrated by plotting the measured spectra against an estimate of the car’s velocity. This will make a so-called Campbell diagram.

% Load the velocity data from the examples folder
Z = vibes.load('VIBES,Examples,Datasets','mat','i3','i3Measurement.ZData.mat');

% Add the operational data to the Z data of the vibes.Block array.
FB.Blocks.setZData('Speed (km/h)',Z.v);

% Update the waterfall plot, only select the run-up section
wf.Columns = {'tc','<',10.5};
wf.ZScale = 'Speed';

A Campbell diagram

Partial plots

For vibes.FreqBlocks objects, an additional class of plots is available: partial plots. These plots help to visualize and compare the contributions of individual datasets to a reference. This is useful for, for example, a Transfer Path Analysis comparison. The use cases will be illustrated with some data from a simulated operational measurement.

% Load the measurement data and FRF of the system.
YAB = vibes.load('VIBES,Examples,Datasets','mat','Benchmark','YABm.FRFMatrix.mat');
TS  = vibes.load('VIBES,Examples,Datasets','mat','Benchmark','uAB.TimeSeries.mat');

% Convert the simulated data to the frequency domain.
TB = TS.toTimeBlocks();
u = TB.toFreqBlocks('hann',YAB.Freq);

% Specify the measurement channels and force reference channels.
ch_u4 = {'Grouping',1};
ch_f2 = {'Grouping',1};

% Calculate excitation forces for the measured operational condition
f2 = YAB.subs(ch_u4,ch_f2) \ u;

% Calculate the partial contribution of each force channel. Notice that
% this operation returns an array of FreqBlocks objects.
u_partials = YAB .* f2;

% Select which channels, blocks and frequencies to plot.
i = u_partials(1).Channels.select('Label','Sensor 3 +X');
b = {'StartTime','><',[2 3]};
frq = [400 3000];

Show the partial contribution of each force channel by calling the plotPartials method on the entire array of FreqBlocks objects. Request the vibes.graph.PartialPlot object as output.

vibes.figure('Partial contributions'); clf
pp = u_partials.plotPartials(i,b,frq);

% Add some white space before the next plot with the 'addSeparator' method.

% Use the 'add' method to add the original measurement as a reference.
% Specify 'Reference' as its label.

Plotting partial contributions and reference measurement

Calling the plotPartials method on a single FreqBlocks object will plot the spectrum data per channel. In this example, we will use this functionality to compare the force contributions calculated in the previous section.

% Plot partials for all channels in the dataset by specifying '[]' for the
% channels.
pp = f2.plotPartials([],b,frq);

% Add a small, 0.1 width separator after the third channel to make a
% distinction between forces and moments.

Comparing force contributions

Bar plots

The last class of plots that will be discussed in this tutorial is the bar plot. A bar plot can be created by calling the plotBars method on an array of vibes.FreqBlocks objects, a single vibes.FreqBlocks object or a vibes.FRFMatrix object. It allows you to select one or more metrics (plot types), that are calculated over the specified frequency range and shown in a bar graph. Currently, the supported metrics are: min, mean, max and sum. Note that sum calculates the energetic sum.

% Open a new, full screen figure and create two subplots.
vibes.figure('Comparison','Units','Normalized','OuterPosition',[0.25 0.25 0.5 0.5]);
ax1 = subplot(1,2,1);

% Copy the previously created partial plot to the new axes.

% Create a bar graph in the second subplot. In this case, we will show the
% maximum force over the previously defined frequency range. Set the
% 'Horizontal' property to true, so that the channel axis is aligned with
% that of the partial plot.
ax2 = subplot(1,2,2);
bp = f2.plotBars([],b,frq,'PlotType','max','Parent',ax2,'Horizontal',true);

% Add the same separator as for the partial plot to completely align the
% two.

Bar plots

Other plots

Plot a dashed line crossing the x-axis or y-axis at a specified value using the dashedline function. This function is especially handy when used in combination with the vibes.TimeSeries and the values in the vibes.Block, to visualize the selection of time-data.

% Activate the left subplot

% Plot a dashed line at two points on the frequency axis.
dashedline('x', [440 1178],'color','k')

Plotting dashed lines on the frequency axis

    Contact us for more VIBES

    Contact our support team or call us on +31 85 822 50 49