Can sfit objects be plotted to specific axis in GUI (not a figure window)?

4 views (last 30 days)
Hi,
I have been given a code that fits a surface to a 3D data set. My task is to add it to an existing GUI, that I have developed using App Designer in Matlab R2020a.
X=1:10; %Made-up data
Y=1:10;
Z=1:10;
n=(1:length(Z));
Ztop=(max(Z)+10).*ones(1,length(n));
plot3(app.Map, X(n),Y(n),Ztop,'.k','markersize',12); %plot datapoints
hold(app.Map, 'on')
options = fitoptions('Method','BiharmonicInterpolant');
[sf,gof] = fit([X', Y'],Z','biharmonicinterp',options); %create sfit obj
axis(app.Map,'equal')
caxis(app.Map,'auto')
%caxis([0 maxV]) ;
colormap(app.Map);
plot(app.Map, sf); %plot fitted surface - THAT'S THE ISSUE, IT WORKS UNTIL THIS LINE!
%shading interp
colorbar(app.Map);
%view(2)
hold(app.Map, 'off')
The code works just fine in a figure window but, when I try to display the output to a graphic axis (app.Map) integrated in the GUI, I get the following:
Error using plot
Data must be numeric, datetime, duration or an array convertible to double.
I read the help for plot() and it seems that plot(ax,_) is the right format. However, I also tried another common format, just in case:
H = plot(sf, 'Parent', app.Map )
This returns a long list of errors. At this point, I think I need some guidance.
Thank you!
PS: one work-around might be plotting to a figure window, set with visibility 'off'. Then export the result to jpg and display it with imshow inside the GUI. But I would still like to know what I am doing wrong, if possible.

Accepted Answer

Giorgio Menallo
Giorgio Menallo on 20 Jun 2020
This is the solution:
X=[wL,wIN1,wIN2,wIN3,wIN1,wIN2,wIN3,wR,wL,wIN1,wIN2,wIN3,wR];
Y=[hIN,hB,hB,hB,hIN,hIN,hIN,hIN,hBC,hBC,hBC,hBC,hBC];
Z=[lL,lB1,lB2,lB3,lIN1,lIN2,lIN3,lR,BC1,BC2,BC3,BC4,BC5];
n=(1:length(Z));
Ztop=(max(Z)+10).*ones(1,length(n));
plot3(app.Map, X(n),Y(n),Ztop,'.k','markersize',12)
view(app.Map, 2)
hold(app.Map, 'on')
[x y] = meshgrid([min(X):1:max(X)],[min(Y):1:max(Y)]);
options = fitoptions('Method','BiharmonicInterpolant');
sf = fit([X',Y'],Z','biharmonicinterp',options);
z = sf(x,y);
surf(x,y,z,'Parent', app.Map,'FaceColor','interp', 'EdgeColor','None')
axis(app.Map, 'equal')
caxis(app.Map, 'auto')
app.Map.YLim = [hB hBC];
app.Map.XLim = [wL wR];
view(app.Map, 2)
colormap(app.Map);
colorbar(app.Map);
hold(app.Map, 'off')

More Answers (2)

Geoff Hayes
Geoff Hayes on 16 Jun 2020
Giorgio - from Plot cfit or sfit object, the code to plot the sf object would be
plot(sf, 'Parent', app.Map)
. When you try to plot as
plot(app.Map, sf);
then you are calling the 2-D line plot function.
  7 Comments
Geoff Hayes
Geoff Hayes on 19 Jun 2020
Gorigio - it may be that the UIAxes is not compatible with the fit object (see this older post https://www.mathworks.com/matlabcentral/answers/274880-app-designer-uiaxes-doesn-t-show-results-of-fitting-curve). It suggests that you need to do something similar to
load census;
f=fit(cdate,pop,'poly2');
x = 1700:2000;
y = feval(f,x);
plot(app.UIAxes,x,y)
but I'm not sure if that is valid for your use case.
Giorgio Menallo
Giorgio Menallo on 20 Jun 2020
Geoff, thanks for all the help.
I actually had found the same post and I was already working on a similar solution.
In the end, that's what worked for me:
X=[wL,wIN1,wIN2,wIN3,wIN1,wIN2,wIN3,wR,wL,wIN1,wIN2,wIN3,wR];
Y=[hIN,hB,hB,hB,hIN,hIN,hIN,hIN,hBC,hBC,hBC,hBC,hBC];
Z=[lL,lB1,lB2,lB3,lIN1,lIN2,lIN3,lR,BC1,BC2,BC3,BC4,BC5];
n=(1:length(Z));
Ztop=(max(Z)+10).*ones(1,length(n));
plot3(app.Map, X(n),Y(n),Ztop,'.k','markersize',12)
view(app.Map, 2)
hold(app.Map, 'on')
[x y] = meshgrid([min(X):1:max(X)],[min(Y):1:max(Y)]);
options = fitoptions('Method','BiharmonicInterpolant');
sf = fit([X',Y'],Z','biharmonicinterp',options);
z = sf(x,y);
surf(x,y,z,'Parent', app.Map,'FaceColor','interp', 'EdgeColor','None')
axis(app.Map, 'equal')
caxis(app.Map, 'auto')
app.Map.YLim = [hB hBC];
app.Map.XLim = [wL wR];
view(app.Map, 2)
colormap(app.Map);
colorbar(app.Map);
hold(app.Map, 'off')

Sign in to comment.


Adam Danz
Adam Danz on 18 Sep 2023
Starting in MATLAB R2023b, provide the axis handle as the first input to plot the fit line in your app's axes.
plot(app.UIAxes, fitline, a, b)
For a workaround prior to R2023b, see this answer.

Products

Community Treasure Hunt

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

Start Hunting!