Asked by Mahesh M S
on 19 Aug 2019

Hi,

I am working on a code that approximates a general bivariate function using a piecewise linear bivariate function. I am able to retrieve the data and plot it, my code works as follows:

It plots one subdomain at a time, as a surface plot. The plot is put inside a loop and so during each, iteration a new subdomain is plotted.

The issue here is that the final plot is displayed with discontinuities as shown in the figure attached.

Kindly help me remove those discontinuities, so as to make the final plot solid or suggest any alternate idea that would work.

Answer by darova
on 19 Aug 2019

Accepted Answer

Just collected all data and used griddata()

darova
on 19 Aug 2019

SOrry, attached wrong script. Try now

Mahesh M S
on 20 Aug 2019

Thank you for the code. It works fine for the above case.

But, the dummy code I provided was a bit specific. I tried to run the code with necessary modifications on a more general case and I am stuck with an error. Kindly help me rectify it.

The code is given below:

xdata = xlsread('debug2.xlsx','B1:AO7');

ydata = xlsread('debug2.xlsx','B9:AO15');

%The whole domain is a square with x_min = 0.2, y_min = 0.2, x_max = pi/2 &

%y_max = pi/2

%The whole domain is divided into 7 parts (sample code) and F{i}

%corresponds to the function values of each subdomain

%Here, F{1} is the subdomain bounded by X{1} and Y{1}

% F{2} is the subdomain bounded by X{2} and Y{2}

% F{3} is the subdomain bounded by X{3} and Y{3}

% F{4} is the subdomain bounded by X{4} and Y{4}

% F{5} is the subdomain bounded by X{5} and Y{5}

% F{6} is the subdomain bounded by X{6} and Y{6}

% F{7} is the subdomain bounded by X{7} and Y{7}

X{1} = xdata(1,1:20); X{2} = xdata(2,1:20); X{3} = xdata(3,1:20); X{4} = xdata(4,:);

X{5} = xdata(5,:); X{6} = xdata(6,:); X{7} = xdata(7,:);

Y{1} = ydata(1,1:20); Y{2} = ydata(2,1:20); Y{3} = ydata(3,1:20); Y{4} = ydata(4,:);

Y{5} = ydata(5,:); Y{6} = ydata(6,:); Y{7} = ydata(7,:);

F{1} = xlsread('debug2.xlsx','B18:U37');

F{2} = xlsread('debug2.xlsx','B39:U58');

F{3} = xlsread('debug2.xlsx','B60:U79');

F{4} = xlsread('debug2.xlsx','B81:AO120');

F{5} = xlsread('debug2.xlsx','B122:AO161');

F{6} = xlsread('debug2.xlsx','B163:AO202');

F{7} = xlsread('debug2.xlsx','B204:AO243');

l = 7;

%The requirement is to plot the total domain in a single plot

% Note: The size of X{i} and Y{i} can vary and also value of l can vary.

X = [];

Y = [];

Z = [];

% make all data in one array

for i = 1:7

[X0, Y0] = meshgrid(xdata(i,:),ydata(i,:));

X = [X; X0(:)];

Y = [Y; Y0(:)];

Z = [Z; F{i}(:)];

end

% create new mesh

x1 = linspace(min(xdata(:)), max(xdata(:)),40);

y1 = linspace(min(ydata(:)), max(ydata(:)),40);

[X1, Y1] = meshgrid(x1,y1);

% create set of data

Z1 = griddata(X,Y,Z,X1,Y1);

h = surf(X1,Y1,Z1);

set(h,'LineStyle','none');

I am getting the following error:

Mahesh M S
on 20 Aug 2019

Sorry. Modified the code myself. Thank you for your help.

Sign in to comment.

Answer by KSSV
on 19 Aug 2019

YOu can follow a samll demo code given here:

[X,Y,Z] = peaks(100) ;

surf(X,Y,Z)

%% Make surface discontinuous for demo

idx = meshgrid(10:10:100) ;

for i = 1:idx

Z(idx(:,i),:) = NaN ;

Z(:,idx(:,i)) = NaN ;

end

surf(X,Y,Z)

%% Have a continuous (x,y,z) data

idx = ~isnan(Z) ;

c = [X(idx) Y(idx) Z(idx)] ;

%% Make c continuous

x = c(:,1) ; y = c(:,2) ; z = c(:,3) ;

xi = linspace(min(x),max(x),100) ;

yi = linspace(min(y),max(y),100) ;

[X,Y] = meshgrid(xi,yi) ;

Z = NaN(size(X)) ;

% get nearest neighbors of new X, Y from (x,y)

idx = knnsearch([X(:) Y(:)],[x y]) ;

Z(idx) = z ;

%% fill gaps by interpolation

F = scatteredInterpolant(x,y,z) ;

idx = isnan(Z) ;

Z(idx) = F(X(idx),Y(idx)) ;

figure

surf(X,Y,Z)

YOu can also use griddata, fillgaps, fillmissing.

Mahesh M S
on 19 Aug 2019

Thanks for the code. But, my code doesnt have gaps as such (as depicted by the top view of the figure shown below) [The figure has been updated. sorry for the error].

Its just discontinuous.

Aso, I can only retrieve data of one subdomain at a time (loop) and thus interpolation is also difficult. A possible way is to extract all data separately from each subdomain and plot later but it takes a lot of time which I am not happy with.

Kinldy help me out with this.

darova
on 19 Aug 2019

i can extract it for you

Mahesh M S
on 19 Aug 2019

I can provide a dummy code.

Sign in to comment.

Answer by Mahesh M S
on 19 Aug 2019

Edited by Mahesh M S
on 19 Aug 2019

xdata = xlsread('debug.xlsx','B1:U4');

ydata = xlsread('debug.xlsx','B6:U9');

%The whole domain is a square with x_min = 0.2, y_min = 0.2, x_max = pi/2 & y_max = pi/2

%The whole domain is divided into 4 parts (sample code) and F{i}

%corresponds to the function values of each subdomain

%Here, F{1} is the subdomain bounded by X{1} and Y{1}

% F{2} is the subdomain bounded by X{2} and Y{2}

% F{3} is the subdomain bounded by X{3} and Y{3}

% F{4} is the subdomain bounded by X{4} and Y{4}

X{1} = xdata(1,:); X{2} = xdata(2,:); X{3} = xdata(3,:); X{4} = xdata(4,:);

Y{1} = ydata(1,:); Y{2} = ydata(2,:); Y{3} = ydata(3,:); Y{4} = ydata(4,:);

F{1} = xlsread('debug.xlsx','B11:U30');

F{2} = xlsread('debug.xlsx','B32:U51');

F{3} = xlsread('debug.xlsx','B53:U72');

F{4} = xlsread('debug.xlsx','B74:U93');

l = 4;

%The requirement is to plot the total domain in a single plot

% Note: The size of X{i} and Y{i} can vary and also value of l can vary.

The reference data has been updated in excel sheet attached herewith.

Sign in to comment.

Answer by Bruno Luong
on 20 Aug 2019

Edited by Bruno Luong
on 20 Aug 2019

Assuming your xdata and ydata are sorted. My code doest not make new resampling of x and y, or interpolation, I just stitch them together

% Read your data

xdata = xlsread('debug.xlsx','B1:U4');

ydata = xlsread('debug.xlsx','B6:U9');

X{1} = xdata(1,:); X{2} = xdata(2,:); X{3} = xdata(3,:); X{4} = xdata(4,:);

Y{1} = ydata(1,:); Y{2} = ydata(2,:); Y{3} = ydata(3,:); Y{4} = ydata(4,:);

F{1} = xlsread('debug.xlsx','B11:U30');

F{2} = xlsread('debug.xlsx','B32:U51');

F{3} = xlsread('debug.xlsx','B53:U72');

F{4} = xlsread('debug.xlsx','B74:U93');

% Stitching the sub-rectangule data

Xu = unique([X{:}]);

Yu = unique([Y{:}]);

Fu = nan(length(Yu),length(Yu));

for k=1:length(F)

[~,ix] = ismember(X{k},Xu);

[~,iy] = ismember(Y{k},Yu);

Fu(iy,ix) = F{k};

end

figure;

surf(Xu,Yu,Fu)

Bruno Luong
on 20 Aug 2019

MATFILE, we are all working with MATLAB here.

Mahesh M S
on 20 Aug 2019

The required X, Y and F data ar attached herewith for your reference.

Bruno Luong
on 20 Aug 2019

load('datareqd.mat')

% Stitching the sub-rectangule data

Xu = unique([X{:}]);

Yu = unique([Y{:}]);

Fu = nan(length(Yu),length(Yu));

for k=1:length(F)

[~,ix] = ismember(X{k},Xu);

[~,iy] = ismember(Y{k},Yu);

Fu(iy,ix) = F{k};

end

Fu = fillmissing(Fu,'linear');

close all

surf(Xu,Yu,Fu)

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 1 Comment

## darova (view profile)

## Direct link to this comment

https://es.mathworks.com/matlabcentral/answers/476645-surface-plots-inside-loop#comment_736594

Sign in to comment.