Importing table and making a stacked plot with same x and y axis

Hello.
I am quite new to MatLab and the functionality compared to excel, but I wanted to do a stacked plot, where my graphs are placed above eachother.
For reference I want something where the 3 different file's graphs I've got is stacked so they look like a PXRD specta (see attached). Peaks (those 1 0 0, 1 0 2, 2 0 0 etc is not needed, just a simple way of stacking them and I suspect you can just use legends for the names?
Problem is I'm nowhere good at using MatLab and I've tried some things and I've managed to get the data inside MatLab and delete columns I don't want.
tbl1 = readtable('SrFe12O19_xy.csv');
tbl1.Properties.VariableNames = ["Degs", "Counts"]
tbl2 = readtable('Fe2O3_hematite_xy.csv');
tbl2.Properties.VariableNames = ["Degs", "Counts"]
tbl3 = readtable('SrFe12O19_Jonas_maj2021.csv');
tbl3(:, 3) = []; % Deletes column 3
tbl3.Properties.VariableNames = ["Degs", "Counts"]
Where the tbl1 and tbl2 are 660x2 table but tbl3 is 6976x2 table.

2 Comments

A bit more info is needed about your tables.
Assuming "Degs" contains the x-coordinates, are they all unique values within each table? Are they sorted in any way?
Since some tables are longer than others, the longer tables either have duplicate x-values or the shorter tables are missing x-values that are in the longer tables. Stackedplot is designed to visualize data along the same range of x-values so what's supposed to happen in the case of missing or duplicate x-coordinates?
Understood. I've attached the files, one original being a .ras file, but converted finely to .csv. Yes I would want the "Degs" to contain the x-coordinates and "Counts" are the intensity or peaks. SrFe12O19JonasMaj2021 contains the experimental data from a smple, when the rest of the files are theoretical data (but still contains "Degs" and "Counts"). I hope I've provided enough information, thanks!
EDIT: I have to mention that SrFe12O19JonasMaj2021.csv contains three rows, but as in my script I use
tbl3(:, 3) = []; % Deletes column 3
To delete the third column that just contains 1's. Else its comma seperated to generate two columns.

Sign in to comment.

 Accepted Answer

There are some non-finite values in ‘tbl3’ that made this interesting.
This approach interpolates all the data in the three tables to a common x-variable (‘xv’), then plots them. It creates a table, however it then recovers the data from the table and plot it as data, not as ‘tbl123’ simply because that is easier, given the constraints of stackedplot.
tbl1 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/623473/SrFe12O19_xy.csv');
tbl2 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/623478/Fe2O3_hematite_xy.csv');
tbl3 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/623468/SrFe12O19_Jonas_maj2021.csv');
tbl3(:, 3) = []; % Deletes column 3
Lv31 = isfinite(tbl3{:,1});
Lv32 = isfinite(tbl3{:,2});
tbl3 = tbl3(Lv31&Lv32,:);
% figure
% plot(tbl1{:,1}, tbl1{:,2})
% figure
% plot(tbl2{:,1}, tbl2{:,2})
% figure
% plot(tbl3{:,1}, tbl3{:,2})
xv = linspace(min([tbl1{1,1},tbl2{1,1},tbl3{1,1}]), max([tbl1{end,1},tbl2{end,1},tbl3{end,1}]), 1E+4);
tbl1i = interp1(tbl1{:,1},tbl1{:,2}, xv, 'linear','extrap');
tbl2i = interp1(tbl2{:,1},tbl2{:,2}, xv, 'linear','extrap');
tbl3i = interp1(tbl3{:,1},tbl3{:,2}, xv, 'linear','extrap');
tbl123 = table(xv.',tbl1i.',tbl2i.',tbl3i.', 'VariableNames',{'Theta_deg','SrFe12O19_xy','Fe2O3_hematite_xy','SrFe12O19_Jonas_maj2021'});
VN = tbl123.Properties.VariableNames;
figure
hsp = stackedplot(tbl123{:,1}, tbl123{:,2:4}, 'DisplayLabels',VN(2:4));
hsp.XLabel = 'Theta_deg';
.

8 Comments

Ahh thats interesting! So its because of the data from the tbl3. I noticed when importing I could set a rule for values of "NaN" to be something, or would that not work?
Also would it be possible to elaborate on whats going on in:
xv = linspace(min([tbl1{1,1},tbl2{1,1},tbl3{1,1}]), max([tbl1{end,1},tbl2{end,1},tbl3{end,1}]), 1E+4);
The rest seems "okay" but still a bit confusing for a new user, but I think I at least see the idea :-).
Thanks a lot for the help, I really appreciate you took your time to help me with my problem!
As always, my pleasure!
The ‘xv’ assignment creates a vector for subsequent interpolations by creating one that goes from the minimum of the first column in each table to the maximum of the first column in each table, assuming that the minimum is always the first element and the maximum is always the last. It creates enough elements in the vector to to account for all the values in each of the second variables (columns). It appears to be confusing because of the cell array indexing into the table (standard practice), however it actually is straightforward.
It took a bit of experimentation for me because I do not use stackedplot much, and had to go exploring.
.
Ah, of course! I'll have to look into it a bit more to fully understand it, but now I've somewhat of an idea whats actually going on in the script! Its quite interesting to learn something new as well.
Last question(s) I think I have is about the cosmetics - is it possible to do legend(s) like the reference picture, linewidth, colors and maybe change the
hsp.XLabel = 'Theta_deg';
to something like
hsp.XLabel = '2 \theta (\deg)';
like a LaTeX interpreter to get the symbols and correct units?
The easiest way to find out is to try it!
tbl1 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/623473/SrFe12O19_xy.csv');
tbl2 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/623478/Fe2O3_hematite_xy.csv');
tbl3 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/623468/SrFe12O19_Jonas_maj2021.csv');
tbl3(:, 3) = []; % Deletes column 3
Lv31 = isfinite(tbl3{:,1});
Lv32 = isfinite(tbl3{:,2});
tbl3 = tbl3(Lv31&Lv32,:);
% figure
% plot(tbl1{:,1}, tbl1{:,2})
% figure
% plot(tbl2{:,1}, tbl2{:,2})
% figure
% plot(tbl3{:,1}, tbl3{:,2})
xv = linspace(min([tbl1{1,1},tbl2{1,1},tbl3{1,1}]), max([tbl1{end,1},tbl2{end,1},tbl3{end,1}]), 1E+4);
tbl1i = interp1(tbl1{:,1},tbl1{:,2}, xv, 'linear','extrap');
tbl2i = interp1(tbl2{:,1},tbl2{:,2}, xv, 'linear','extrap');
tbl3i = interp1(tbl3{:,1},tbl3{:,2}, xv, 'linear','extrap');
tbl123 = table(xv.',tbl1i.',tbl2i.',tbl3i.', 'VariableNames',{'Theta_deg','SrFe12O19_xy','Fe2O3_hematite_xy','SrFe12O19_Jonas_maj2021'});
VN = tbl123.Properties.VariableNames;
figure
hsp = stackedplot(tbl123{:,1}, tbl123{:,2:4}, 'DisplayLabels',VN(2:4));
hsp.XLabel = '2 Θ (°)';
hsp.AxesProperties(1).LegendLabels = {'Legend 1'};
hsp.AxesProperties(1).LegendLocation = 'northeast';
hsp.AxesProperties(1).LegendVisible = 'on';
hsp.AxesProperties(2).LegendLabels = {'Legend 2'};
hsp.AxesProperties(2).LegendLocation = 'northeast';
hsp.AxesProperties(2).LegendVisible = 'on';
hsp.AxesProperties(3).LegendLabels = {'Legend 3'};
hsp.AxesProperties(3).LegendLocation = 'northeast';
hsp.AxesProperties(3).LegendVisible = 'on';
hsp.LineProperties(3).Color = 'r';
% get(hsp)
It seems that stackedplot does not allow an 'Interpreter' to be defined, so going with the characters is the only option. (I did several experiments, with the only result being error messages.) Getting the legends to work was an exercise in itself.
For the line widths, see the documentation section on Line since that appears to be the same as for other plots. I plotted red lines in the last plot, so follow that example to change the properties of the others. I caution against making the lines too thick, because that would likely obscure the fine details in the plots.
Experiment to get the result you want. The stackedplot documentation has several lilnks at the end of that page that link to other pages (that link to still other pages) with the necessary documentation to change various properties.
.
Thanks a lot for the help again1
I found this, but for the ylabel instead
s = stackedplot(...);
axesProps = struct(s.AxesProperties(2)); % using struct() is undocumented
axesProps.Axes.YLabel.Interpreter = 'tex';
Which I think is quite interesting, but I've tried to play a bit with and it seems its not possible (as far as I can do).
Link to the answer.
I did not see that.
Yair is certainly the master of MATLAB secrets, however that was two years ago, and there have likely been changes to stackedplot in the interim. (The inability to do these sorts of elementary tweaks is the reasson I rarely use it.)
Regardless, I tried everything I could think of (including something similar to that) and could not make similar code work.
Ahh okay, thats unfortunate. I have one last question if you don't mind, since I've tried to find out why I can't have the three variables (Var2, Var3, Var4) have the same name. I've tried to edit the file, delete displaylabels put it says that there needs to be those 4 different variables? Do I miss something?
That might be possible, however not with a table, because table objects do not allow multiple variables with the same names. It would be necessary to extract them from the table (using table2array for example), then plot them similarly to the way I did. You could then name them whatever you want (as the y-labels) in the plots.

Sign in to comment.

More Answers (0)

Categories

Find more on Creating, Deleting, and Querying Graphics Objects in Help Center and File Exchange

Products

Release

R2021a

Community Treasure Hunt

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

Start Hunting!