Trouble controlling x-axis values in stackedplot (or having all plots vertically stacked in tiledlayout for 14 columns)

11 views (last 30 days)
Hi,
I am working on a project to import and graph EEG data, but I am having trouble using stackedplot (or, alternatively, having 14 tiled plots stacked vertically).
For stackedplot: I want to have Timestamp (or timestamp) as the x-axis and, if possible, I'd like to have the y-axes scaled the same. Also, I eventually want to use findpeaks on the plots. Is this possible in stackedplot, or should I go with the tiled plots?
For the tiled plots: I want the 14 plots vertically stacked on the same x-axis (basically, I want it to look like the stackedplot).
I've attached my Matlab code and the csv file I got my data from. Line 23 is where the plotting starts. (Lines 26 and 27 are my attempt at stackedplot. Everything after line 28 is my attempt at tiledplots)
Thank you so much for your help!

Accepted Answer

dpb
dpb on 13 Jul 2021
Edited: dpb on 13 Jul 2021
tTry=readtable('Try 4.csv');
stackedplot(tTry,tTry.Properties.VariableNames(2:end),'XVariable','Timestamp')
works just fine per the documentation...you have to increase the height of the default figure window or it won't display all of them, but will refresh when do enlarge the window.
The timestamp isn't a very conducive variable; what's the encoding to convert to datetime?
findpeaks graphics won't work directly; you would be able to save the peak locations and add the markers, but if want to use some of the more in-depth features like the half-width plots and the like, those will be somewhar more of a challenge.
I've never dived into the detail plotting code to see if it could be munged to plot into an existing axes or not -- hold on works for an existing axes; you can get access to the y-axis properties (limited subset) of the stackdplot object axes, but I do not believe there as an axes handle itself that can be used as a target to add additional information onto the plot...not sure, I didn't try anything here now yet.
If you have ambitions along that route, I think the nexttile route may be the way; you can get an axes handle to each tiled axes from it.
ADDENDUM:
hTL=tiledlayout(14,1,'TileSpacing',"compact");
for i=2:width(tTry)
nexttile
findpeaks(tTry{:,i},tTry.Timestamp)
ylabel(extractAfter(tTry.Properties.VariableNames(i),'_'))
xticklabels('')
end
xticklabels(xticks)
puts them all on the figure (again, you'll have to increase the vertical height) but with the default parameters for findpeaks it finds and draws peak locators at every uptick in each time trace so the plot is just a big blob of down-facing triangles--you'll have to use judicious selection of parameters to only locate peaks of interest.
But, the graphing itself isn't of any real problem it doesn't seem...
  2 Comments
Christina Diersing
Christina Diersing on 13 Jul 2021
Stacked Plot:
The first bit of code was exactly what I needed! I think I missed the 'tTry.Properties.VariableNames(2:end)' and I don't think I had both 'XVariable' and 'Timestamp' in single-quotes.
Thank you so much for your help!
For anyone who is interested, what I basically ended up with was:
T=readtable('Try 4.csv');
T.Timestamp=T.Timestamp-1622835751.18846; %This changes the official Timestamp column so it is 0 at the start of the recording
%Plot all 14 EEG signals on separate (stacked) plots with the same x-axis (timestamp)
figure
stackedplot(T,T.Properties.VariableNames(2:end),'XVariable','Timestamp')
grid;
title('EEG Signals');
Tiled Layout:
For tiledlayout, I tried using both 'compact' and 'none', but neither worked. I also tried it in double-quotes, like you had, but it still didn't work. For some reason, it only seems to work when I use a for loop like you did. Do you know how I can make the tiledlayout work without the for loop?
Also, is there a way I can change the y-label in the for loop to include the units ' (uV)' after the label? I tried several versions of the following line of code, but nothing worked.
ylabel({extractAfter(T.Properties.VariableNames(i),'_'), ' (uV)'})
Again, thank you so much for your help! This has helped me so much. I sometimes have trouble fully understanding the documentation and they don't have examples for everything so, even though I try using the documentation, I still have trouble sometimes. Thank you again!
For anyone who is interested, for the tiledlayout, this is what I put:
fig1=figure('Name', 'EEG Signals and Peaks (Prominence=100)');
hTL=tiledlayout(7,2,'TileSpacing',"tight");
for i=2:width(T)
nexttile
findpeaks(T{:,i},T.Timestamp, 'MinPeakProminence', 100)
ylabel(extractAfter(T.Properties.VariableNames(i),'_'))
xticklabels('')
if i==14
xticklabels(xticks)
xlabel('Timestamp (s)');
end
end
xticklabels(xticks)
grid on;
xlabel('Timestamp (s)');
fig1.WindowState = 'maximize';
dpb
dpb on 13 Jul 2021
Your code for stackedplot didn't define the X-axis variable in the same call as the one that tried to plot the variables--you had two calls, one with variables but no X variable so it used the default row number as the x-variable and a second call that had an X variable but no other variables to plot. The two calls don't know anything about each other so each did what was asked but neither was what you wanted/intended.
There isn't any way to use the tiled layout without a loop -- so what's wrong with that? It is a completely different animal than stackedplot in that each plot is a separate axes; in stackedplot all axes share a single x axis and the code is interfaced to the user by expecting an array of all lines to be placed on a separate axis by variable; it was coded to behave that way whereas the tiled layout is a generic tiling of axes inside a figure with no a priori presumptions about what the user will decide is either the layout nor what will go into each axes. Hence, each of those has to be drawn independently and the only way to get from one axes to the next is via nexttile and it must be called explicitly. It is possible to save the handle of the axes object to be able to refer to later or to address a given axes location, but nexttile is the only way to populate the figure once tiledlayout is called -- any other attempt by using axes() or plot() without nexttile simply reverts the figure back to an ordinary figure and single axes.
To add text of any sort to the label, just concatenate static text or use format string -- it's simplest given already have a cellstr() from the stored variable names to just catenate
ylabel(strcat(extractAfter(tTry.Properties.VariableNames(i),'_'),' (uV)'))
I don't know what is meant by the comment about the tiled layout spacing argument -- it can be either a char() or cellstr() or string() but must be one of the three options. Playing around, one gets more vertical space for each axis by 'none' than either of the other two; they only seem to affect the horizontal spacing between the columns if there are more than one. Since your Q? asked about replicating stackedplot, I just used the one.
tiledlayout wasn't introduced until R2019b while I have R2020b installed, but unless TileSpacing wasn't introduced until R2020x, (which I don't know whether was in original release or not), it certainly should work.

Sign in to comment.

More Answers (0)

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!