Hello MATLAB Community,
I have the following script and data where i would like to plot a 3d Surface and it works well for some data and it doesn't work because of the dimensions in some cases. Can someone please suggest where is the mistake in the script and how to fix it?
opts = detectImportOptions('Data123.xlsx');
opts = opts.setvartype('Y','double');
opts = opts.setvartype('Z','double');
% Load data
data = readtable('Data123.xlsx', opts);
data.Properties.VariableNames = ["X","F_sw","Y","Z"];
% order the data
data = sortrows(data,["X","Y"]);
X = unique(data.X);
Y = unique(data.Y);
Z = reshape(data.Z,[length(Y),length(X)]);
% View
figure(1)
scatter3(data.X,data.Y,data.Z,12,[1 0 0],"filled","MarkerEdgeColor",[0 0 0])
hold on
s = surf(X,Y,Z,"FaceColor",'interp');
hold off

6 Kommentare

Steven Lord
Steven Lord am 26 Jul. 2021
What does "does not work" mean?
  • Do you receive warning and/or error messages? If so the full and exact text of those messages (all the text displayed in orange and/or red in the Command Window) may be useful in determining what's going on and how to avoid the warning and/or error.
  • Does it do something different than what you expected? If so, what did it do and what did you expect it to do?
  • Did MATLAB crash? If so please send the crash log file (with a description of what you were running or doing in MATLAB when the crash occured) to Technical Support using the telephone icon in the upper-right corner of this page so we can investigate.
Exploring the data with:
[X,ix1] = unique(data.X)
seg_len = diff([ix1;numel(data.X)])
produces results: [32; 56; 56; 39]
It is going to be difficult to use reshape with that and get any consistent results.
.
Dear Mr. Steven Lord,
When i run the script with the attached data set, i get the following error related to reshape. I am not able to figure out the exact reason for this. I suppose
And if i have to fix this error so that I can make a surface plot according to this script, how do i proceed?
Error using reshape
Number of elements must not change. Use [] as one of the size inputs to automatically calculate the appropriate size for that dimension.
Error in Plot_fixDC (line 14)
Z = reshape(data.Z,[length(Y),length(X)]);
I see a error in the way you're using reshape
Error using reshape
Number of elements must not change. Use [] as one of the size inputs to automatically calculate the appropriate size for that dimension.
You are trying to reshae the Z array into a matrix thant changes the number of elements. Please read the dosucmentation on reshape. Also, please let give more details on what you're trying to achieve here.
ragnor
ragnor am 26 Jul. 2021
If i don't use unique, is there any other way, i can create a surface plot with the data.
I just want to make a 3d surface plot to display the results.
Thanks in advance.
ragnor
ragnor am 26 Jul. 2021
I just want to make a 3D surface plot as displayed in the attached figure.

Melden Sie sich an, um zu kommentieren.

 Akzeptierte Antwort

Star Strider
Star Strider am 27 Jul. 2021

0 Stimmen

The only solution I can propose is to use either griddata or scatteredInterpolant .
Try this —
opts = detectImportOptions('https://www.mathworks.com/matlabcentral/answers/uploaded_files/695269/Data123.xlsx');
opts = opts.setvartype('Y','double');
opts = opts.setvartype('Z','double');
% Load data
data = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/695269/Data123.xlsx', opts)
data = 184×4 table
X F_sw Y Z _____ ____ ___ ______ 10000 350 0.5 2.9008 10000 350 1 3.0802 10000 350 1.5 3.2261 10000 350 2 3.3174 10000 350 2.5 3.3299 10000 350 3 3.3618 10000 350 3.5 3.4404 10000 350 4 3.5091 10000 350 4.5 3.5816 10000 350 5 3.6302 10000 350 5.5 3.6945 10000 350 6 3.7262 10000 350 6.5 3.7544 10000 350 7 3.7761 10000 350 7.5 3.7944 10000 350 8 3.8067
data.Properties.VariableNames = ["X","F_sw","Y","Z"];
% order the data
data = sortrows(data,["X","Y"]);
% X = unique(data.X);
% Y = unique(data.Y);
X = data.X;
Y = data.Y;
Z = data.Z;
N = 50;
xv = linspace(min(X), max(X), N);
yv = linspace(min(Y), max(Y), N);
[Xm,Ym] = ndgrid(xv, yv);
Zm = griddata(X,Y,Z,Xm,Ym);
% Z = reshape(data.Z,[length(Y),length(X)]);
% View
figure(1)
scatter3(data.X,data.Y,data.Z,12,[1 0 0],"filled","MarkerEdgeColor",[0 0 0])
hold on
s = surf(Xm,Ym,Zm,"FaceColor",'interp', 'EdgeColor','none');
hold off
If it is not the result you want, I will delete my Answer.
.

4 Kommentare

ragnor
ragnor am 27 Jul. 2021
@Star Strider: Thank you very much for the solution. I was looking for a similar result. Just a small question, is it possible to join the red dots so that it looks like 4 tansig curves.
Once again thank you.
As always, my pleasure!
Joining the red dots rerquires switching from scatter3 to plot3
opts = detectImportOptions('https://www.mathworks.com/matlabcentral/answers/uploaded_files/695269/Data123.xlsx');
opts = opts.setvartype('Y','double');
opts = opts.setvartype('Z','double');
% Load data
data = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/695269/Data123.xlsx', opts)
data = 184×4 table
X F_sw Y Z _____ ____ ___ ______ 10000 350 0.5 2.9008 10000 350 1 3.0802 10000 350 1.5 3.2261 10000 350 2 3.3174 10000 350 2.5 3.3299 10000 350 3 3.3618 10000 350 3.5 3.4404 10000 350 4 3.5091 10000 350 4.5 3.5816 10000 350 5 3.6302 10000 350 5.5 3.6945 10000 350 6 3.7262 10000 350 6.5 3.7544 10000 350 7 3.7761 10000 350 7.5 3.7944 10000 350 8 3.8067
data.Properties.VariableNames = ["X","F_sw","Y","Z"];
% order the data
data = sortrows(data,["X","Y"]);
X = data.X;
Y = data.Y;
Z = data.Z;
N = 50;
xv = linspace(min(X), max(X), N);
yv = linspace(min(Y), max(Y), N);
[Xm,Ym] = ndgrid(xv, yv);
Zm = griddata(X,Y,Z,Xm,Ym);
% Z = reshape(data.Z,[length(Y),length(X)]);
% View
[Xu,Xix] = unique(data.X,'stable');
Xix = [Xix; numel(X)];
for k = 1:numel(Xix)-1
C{k} = data{(Xix(k):Xix(k+1)-1),[1 3 4]};
end
% C
figure(1)
hold on
% scatter3(data.X,data.Y,data.Z,12,[1 0 0],"filled","MarkerEdgeColor",[0 0 0])
for k = 1:numel(C)
plot3(C{k}(:,1),C{k}(:,2),C{k}(:,3),'o-r', 'MarkerSize',6, 'MarkerFaceColor',[1 0 0],"MarkerEdgeColor",[0 0 0], 'LineWidth',2.5)
end
s = surf(Xm,Ym,Zm,"FaceColor",'interp', 'EdgeColor','none', 'FaceAlpha',0.8);
hold off
xlabel('X')
ylabel('Y')
zlabel('Z')
grid on
view(-30,30)
However this did not turn out to be straightforward, since there were connecting lines between the plotted line segments. Sectioning them in the ‘C’ cell array and then plotting them separately in the loop solved this. (An alternative approach would have been to section them, concatenating ‘NaN(1,3)’ to the end of each section, then recombining them into a single matrix. Thie approach I took here is easier.)
Experiment with the various line properties to get the result you want.
.
ragnor
ragnor am 28 Jul. 2021
@Star Strider: Thank you very much. It was indeed very uselful and it is something i wanted to plot.
Thanks again.
Star Strider
Star Strider am 28 Jul. 2021
As always, my pleasure!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Produkte

Version

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by