3D plot from tables in timeline

Hello!
I am trying to plot my data (contains water depth and absorbance at 2 different wavelengths for each measured depth) into a 3D plot. I have pre-procressed the data so all datasets (approx 100/year) contain the same variables and the same number of columns in a table, but the number of rows sometimes varies (I don't have equal numbers of depth measurements). I would like to plot my data into a 3D plot so all data from one year can be in one surface-3D plot to visualize the development over one year.
I have tried putting all my data into a 3D matrix and then plotting it, but I have multiple problems: I tried using table2array and then creating a 3D array, but the different row numbers keep giving me problems. I tried using zeros() and then an array overlay with all smaller tables, but 1) I don't know which one is my biggest dataset and 2) I don't want to do this manually/ I would like to use some kind of loop to first fill the 'empty' rows with zeros and then put everything together in one 3D matrix and then plot it into a 3D plot.
Can anybody help here?
Thanks!! :)

7 个评论

Is it the case that when you have more rows, that the additional rows are in a fixed progression along some length axes? For example, all row #17 that exist are the same depth as each other, all row #18 that exist are at the same depth as each other and that is greater than for row #17 ?
If you put the arrays into a cell array as you read / preprocess them, then you can
cols = size(TheCell{1},2);
row_sizes = cellfun(@(M) size(M,1), TheCell);
max_rows = max(row_sizes);
PaddedCells = arrayfun(@(M, R) [M{1}; nan(R-max_rows, cols)], TheCell, row_sizes, 'uniform', 0);
Array3D = cat(3, PaddedCells{:});
For the 3d plot, what are the x, y and z axis ?
@Walter Roberson:
No, unfortunately not. The data I have are somewhere between 1m and 100m depthe, but they do not have the same depth values as the probe just measures approx. 3 times per second while being lowered into the lake... Also some measurements start at 1m (I chopped everything above that) but sometimes the measurement fails and the probe just starts measuring e.g. at 30m depth or stops at 80m etc.
@Mohammad Sami:
My x axis is the lake depth, I currently have two y axis but i can limit that to one, it contains absorbance measurements, and my z should be the time scale, e.g. it should contain all data from one year basically stacked above each other
What if you just scaled your z axis between 0 and 1 (or some other values) ? E.g 0 will be 1st January and 1 would be 31st December.
You would then be able to handle variable number of rows.
So I tried stacking the 2D plots now and I am pretty sure I scaled my z-axis between 0 and 39 and then I used plot3, but it tells me that I still need to have vectors of the same length..
I included some code here, so basically I just want to stack all files in the inputfolder above each other (they are all txt files with which I can plot my 2D figures for the different sampling days)
Also, this is an example of one 2D plot:
inputdir = 'C:\Users\Eva\Desktop\matlab_eva\Moldaenke2008output'
allFiles = dir(fullfile(inputdir, '*.txt'));
for k = 1:numel(allFiles)
fnm = fullfile(inputdir, allFiles(k).name);
data = readtable (fnm);
corrData = table2array(data);
N = 39;
t = 1:110;
figure
hold on
for i = 1:N
plot3(corrData, t, corrData(i,:))
end
view(3)
end
What is the size of the data you are loading. What do the rows and columns correspond to ?
For plot3, the X,Y,Z values must satisy either of these properties for the function to work
Vector of same length or
Specify at least one of X, Y, or Z as a matrix, and the others as vectors. Each of X, Y, and Z must have at least one dimension that is same size. For best results, specify all vectors of the same shape and all matrices of the same shape.
Thanks for your patience already!!! :)
So my data has three columns (depth, absorbance, cryptophyta content) and for each row (each depth) the measured parameters of the other two columns.
The dimension that is the same size will then be column number I guess, because all datasets have three columns, Z is kind of a timescale as an add-on, as I am basically just trying to stack the 2D images. I tried saving everything as a matrix, like below but then I get problems with my row number again :(
data1 = readtable ('data1.txt');
data2 = readtable ('data2.txt');
modData1 = table2array(data1);
modData2 = table2array(data2);
matrix = data1;
matrix(:,:,2) = data2;

请先登录,再进行评论。

 采纳的回答

Based on my understanding each file 'data1.txt' is from one particular time
Different number of rows means, you are missing certain depth values.
One option would be to use interpolation to standardise your data into a standard format.
Assuming you have depth measurement from 0 to 100m, you can interpolate to a desired interval
function out = read_data(filename)
data = readtable (filename);
modData = table2array(data);
depthinterval = 0.1; % 0.1m
newdepth = 0:depthinterval:100;
olddepth = modData(:,1); % first column = depth
olddata = modData(:,2:3) % data columns
newdata = interp1(olddept,olddata,newdepth);
out = [newdepth newdata];
end
The output will then have the same number or rows, so that you can stack them easily.

4 个评论

Oh this is a good idea, thanks a lot!
I tried but I keep getting errors...
ArrayData = table2array(finalTable);
depth = ArrayData(:,1);
crypto = ArrayData(:,2);
LED = ArrayData(:,3);
depthinterval = 0.1;
newdepth = 0:depthinterval:100;
cryptoLED = [crypto LED];
interpData = interp1(depth, cryptoLED, newdepth);
This is the code I am using (as you suggested) but it only returns me this:
Error using matlab.internal.math.interp2
Sample points must be unique and sorted in ascending order.
Error in interp1 (line 151)
VqLite = matlab.internal.math.interp2(Xext,V,method,method,...
but I mean I cannot sort the data differently since then it all gets mixed up?!
Matlab wants the X Variable (depth values) to be sorted. You can sort the array before interpolating.
ArrayData = table2array(finalTable);
% sort the data by the depth column.
ArrayData = sortrows(ArrayData,1);
depth = ArrayData(:,1);
crypto = ArrayData(:,2);
LED = ArrayData(:,3);
depthinterval = 0.1;
newdepth = 0:depthinterval:100;
cryptoLED = [crypto LED];
interpData = interp1(depth, cryptoLED, newdepth);
Also if there are multiple entries for the same depth, you can also get the above error.
In that case you can use unique to remove the duplicate depth entries.
% find the index of unique depth values
[~,uniquedepthindex] = unique(ArrayData(:,1));
% use the index to filter out the duplicates
ArrayData = ArrayData(uniquedepthindex,:);
% continue with interpolation
Thanks so much! This has worked out great and I was able to create and save the matrix with my interpolated data. I had already sorted the data in a previous step, but I the unique command really helped me.
ArrayData = table2array(finalTable);
% find the index of unique depth values
[~,uniquedepthindex] = unique(ArrayData(:,1));
% use the index to filter out the duplicates
ArrayData = ArrayData(uniquedepthindex,:);
depth = ArrayData(:,1);
crypto = ArrayData(:,2);
LED = ArrayData(:,3);
depthinterval = 0.1;
newdepth = 0:depthinterval:100;
cryptoLED = [crypto LED];
interpData = interp1(depth, cryptoLED, newdepth);
% interpolation of depth data
depthforFinalMatrix = transpose(newdepth);
finalMatrix = [depthforFinalMatrix interpData];
% creation of new matrix with 3 columns: depth, crypto content, LED
Now I am trying to plot it in some 3D matrix, but not sure whether I would use plot3 or surf....

请先登录,再进行评论。

更多回答(1 个)

darova
darova 2020-6-24
Can you interpolate your data to make it equal size? Concantenate it and use surf

类别

帮助中心File Exchange 中查找有关 Interpolation 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by