How to make a contourf plot follow a line?

Good morning! I plotted a contourf plot in a figure, until then evrything is working, but now, I awant to make that contour follow a line. I have been trying to use a for loop but I cannot make it work. Any idea on what I could try to achieve my goal?
Here is my foor loop:
for i = 1:200
c = contourf(X, Y, -) %% different variables from my code to make it easier
xticks([])
yticks([])
cmap = colormap("summer");
xline(0, "black", "LineWidth", 2)
view([180 90]); % changes the view so that the pattern is facing down
pause(2)
drawnow
end
Thank you

2 Comments

hello
can you share your data ? and a picture / sketch of what you want to achieve
Hi! Sadly, I cannot share the data as it is way to big. But currently, the output looks like this (image). it is basically an ellipse and an xline is going right down the middle. What I want (image(1)), is basically that same ellipse, just following the lne and leaving a trail behind so it basically becomes a big line. I hope that makes sense.
Thank you

Sign in to comment.

 Accepted Answer

hello again
here a small demo code based on a first given elipse (bottom left on the picture)
you can use a spacing between them if needed (xr_spacing)
the intersections function is attached
% dummy ellipse
n = 100;
alpha = pi/n+(0:n)/n*2*pi;
a = 1;
b = 3;
x0 = 2.5;
y0 = 3;
x = x0 + a*cos(alpha);
y = y0 + b*sin(alpha);
% create the reference line
xref = (0:0.1:10);
yref = y0*ones(size(xref));
figure(1);
plot(x,y,'*-b',xref,yref,'r--')
xlim([0 8])
ylim([0 8])
axis square
% for fun let's apply a rotation angle to this
% rotation around the origin(0,0)
% Create rotation matrix
theta = 45; % to rotate 25 degrees counterclockwise
R = [cosd(theta) -sind(theta); sind(theta) cosd(theta)];
% Rotate your point(s)
for k =1:numel(x)
rotpoint = R*([x(k) ;y(k)]);
xr(k) = rotpoint(1);
yr(k) = rotpoint(2);
end
for k =1:numel(xref)
rotpoint = R*([xref(k) ;yref(k)]);
xrefr(k) = rotpoint(1);
yrefr(k) = rotpoint(2);
end
%
figure(2);
plot(xr,yr,'*-b',xrefr,yrefr,'r--')
xlim([-4 8])
ylim([0 12])
axis square
hold on
% now create replicates of the rotated elipse along the reference line
% intersections makes finding the intersection points very easy.
[xout,yout] = intersections(xr,yr,xrefr,yrefr,1);
dx = diff(xout);
dy = diff(yout);
% do n duplicates
xr_spacing = 0.25; % along the reference line (rotated)
xy_spacing = R*([xr_spacing ;0]); % gives the true x and y spacing in the absolute referential
for n = 1:3
newx = xr + n*(dx+xy_spacing(1));
newy = yr + n*(dy+xy_spacing(2));
plot(newx,newy);
end

19 Comments

Would it work with a contourf instead of a plot command?
forgot the top and bottom lines
here is it :
% dummy ellipse (a,b)
n = 100;
alpha = pi/n+(0:n)/n*2*pi;
a = 1;
b = 3;
x0 = 2.5;
y0 = 3;
x = x0 + a*cos(alpha);
y = y0 + b*sin(alpha);
% create the reference line
xref = (0:0.1:10);
yref = y0*ones(size(xref));
% create top and bottom lines
[val,id_top]= max(y);
x_top = (x(id_top):0.1:xref(end));
y_top = val*ones(size(x_top));
[val,id__bottom]= min(y);
x_bottom = (x(id__bottom):0.1:xref(end));
y_bottom = val*ones(size(x_bottom));
figure(1);
plot(x,y,'*-b',xref,yref,'r--',x_bottom,y_bottom,'g--',x_top,y_top,'k--')
xlim([-1 8])
ylim([-1 8])
axis square
% for fun let's apply a rotation angle to this
% rotation around the origin(0,0)
% Create rotation matrix
theta = 45; % to rotate 25 degrees counterclockwise
R = [cosd(theta) -sind(theta); sind(theta) cosd(theta)];
% Rotate your point(s)
for k =1:numel(x)
rotpoint = R*([x(k) ;y(k)]);
xr(k) = rotpoint(1);
yr(k) = rotpoint(2);
end
for k =1:numel(xref)
rotpoint = R*([xref(k) ;yref(k)]);
xrefr(k) = rotpoint(1);
yrefr(k) = rotpoint(2);
end
for k =1:numel(x_top)
rotpoint = R*([x_top(k) ;y_top(k)]);
x_topr(k) = rotpoint(1);
y_topr(k) = rotpoint(2);
end
for k =1:numel(x_bottom)
rotpoint = R*([x_bottom(k) ;y_bottom(k)]);
x_bottomr(k) = rotpoint(1);
y_bottomr(k) = rotpoint(2);
end
%
figure(2);
plot(xr,yr,'*-b',xrefr,yrefr,'r--',x_bottomr,y_bottomr,'g--',x_topr,y_topr,'k--')
xlim([-4 8])
ylim([0 12])
axis square
hold on
% now create replicates of the rotated elipse along the reference line
% intersections makes finding the intersection points very easy.
[xout,yout] = intersections(xr,yr,xrefr,yrefr,1);
dx = diff(xout);
dy = diff(yout);
% do n duplicates
xr_spacing = 0.25; % along the reference line (rotated)
xy_spacing = R*([xr_spacing ;0]); % gives the true x and y spacing in the absolute referential
for n = 1:3
newx = xr + n*(dx+xy_spacing(1));
newy = yr + n*(dy+xy_spacing(2));
plot(newx,newy);
end
to your comment
you can access the contourf lines by using this FEX submission
example
x = 0:0.1:2;
y = 0:0.1:3;
[X,Y] = meshgrid(x,y);
Z = X.*exp(-X.^2-(Y-1.5).^2);
[cm, h] = contourf(X,Y,Z);
[contourTable, contourArray] = getContourLineCoordinates(cm);
% Show all lines that match the 7th level
hold on
levelIdx = contourTable.Level == h.LevelList(7);
x_elipse = contourTable.X(levelIdx);
y_elipse = contourTable.Y(levelIdx);
plot(x_elipse, y_elipse, 'r*-', 'MarkerSize', 10)
So I was looking into it, it's just plotting everything at the same time. How would you delay each ellipse?
combine the two codes and you get the result :
x = 0:0.1:2;
y = 0:0.1:5;
[X,Y] = meshgrid(x,y);
Z = X.*exp(-X.^2-0.25*(Y-2.5).^2);
figure(1);
[cm, h] = contourf(X,Y,Z);
[contourTable, contourArray] = getContourLineCoordinates(cm);
% Show all lines that match the 7th level
hold on
levelIdx = contourTable.Level == h.LevelList(7);
x = contourTable.X(levelIdx);
y = contourTable.Y(levelIdx);
plot(x, y, 'r*-', 'MarkerSize', 10)
% create the reference line
xref = (0:0.1:10);
yref = mean(y)*ones(size(xref));
% create top and bottom lines
[val,id_top]= max(y);
x_top = (x(id_top):0.1:xref(end));
y_top = val*ones(size(x_top));
[val,id__bottom]= min(y);
x_bottom = (x(id__bottom):0.1:xref(end));
y_bottom = val*ones(size(x_bottom));
figure(2);
plot(x,y,'*-b',xref,yref,'r--',x_bottom,y_bottom,'g--',x_top,y_top,'k--')
xlim([-1 8])
ylim([-1 8])
axis square
% for fun let's apply a rotation angle to this
% rotation around the origin(0,0)
% Create rotation matrix
theta = 45; % to rotate 25 degrees counterclockwise
R = [cosd(theta) -sind(theta); sind(theta) cosd(theta)];
% Rotate your point(s)
for k =1:numel(x)
rotpoint = R*([x(k) ;y(k)]);
xr(k) = rotpoint(1);
yr(k) = rotpoint(2);
end
for k =1:numel(xref)
rotpoint = R*([xref(k) ;yref(k)]);
xrefr(k) = rotpoint(1);
yrefr(k) = rotpoint(2);
end
for k =1:numel(x_top)
rotpoint = R*([x_top(k) ;y_top(k)]);
x_topr(k) = rotpoint(1);
y_topr(k) = rotpoint(2);
end
for k =1:numel(x_bottom)
rotpoint = R*([x_bottom(k) ;y_bottom(k)]);
x_bottomr(k) = rotpoint(1);
y_bottomr(k) = rotpoint(2);
end
%
figure(3);
plot(xr,yr,'*-b',xrefr,yrefr,'r--',x_bottomr,y_bottomr,'g--',x_topr,y_topr,'k--')
xlim([-4 8])
ylim([0 12])
axis square
hold on
% now create replicates of the rotated elipse along the reference line
% intersections makes finding the intersection points very easy.
[xout,yout] = intersections(xr,yr,xrefr,yrefr,1);
dx = diff(xout);
dy = diff(yout);
% do n duplicates
xr_spacing = 0.25; % along the reference line (rotated)
xy_spacing = R*([xr_spacing ;0]); % gives the true x and y spacing in the absolute referential
for n = 1:3
newx = xr + n*(dx+xy_spacing(1));
newy = yr + n*(dy+xy_spacing(2));
plot(newx,newy);
end
Margaux
Margaux on 23 Jun 2023
Edited: Margaux on 23 Jun 2023
I'm not sure I am getting the desired output... am I?
seems not to work on your side
did you get an error message ?
do you have this function downloaded and in your path ? : getContourLineCoordinates - File Exchange - MATLAB Central (mathworks.com)
I attach here for convenience if you prefer
and also intersections (attached again ) ?
this is my first plot
and my last
from the same code :
x = 0:0.1:2;
y = 0:0.1:5;
[X,Y] = meshgrid(x,y);
Z = X.*exp(-X.^2-0.25*(Y-2.5).^2);
figure(1);
[cm, h] = contourf(X,Y,Z);
[contourTable, contourArray] = getContourLineCoordinates(cm);
% Show all lines that match the 7th level
hold on
levelIdx = contourTable.Level == h.LevelList(7);
x = contourTable.X(levelIdx);
y = contourTable.Y(levelIdx);
plot(x, y, 'r*-', 'MarkerSize', 10)
% create the reference line
xref = (0:0.1:10);
yref = mean(y)*ones(size(xref));
% create top and bottom lines
[val,id_top]= max(y);
x_top = (x(id_top):0.1:xref(end));
y_top = val*ones(size(x_top));
[val,id__bottom]= min(y);
x_bottom = (x(id__bottom):0.1:xref(end));
y_bottom = val*ones(size(x_bottom));
figure(2);
plot(x,y,'*-b',xref,yref,'r--',x_bottom,y_bottom,'g--',x_top,y_top,'k--')
xlim([-1 8])
ylim([-1 8])
axis square
% for fun let's apply a rotation angle to this
% rotation around the origin(0,0)
% Create rotation matrix
theta = 45; % to rotate 25 degrees counterclockwise
R = [cosd(theta) -sind(theta); sind(theta) cosd(theta)];
% Rotate your point(s)
for k =1:numel(x)
rotpoint = R*([x(k) ;y(k)]);
xr(k) = rotpoint(1);
yr(k) = rotpoint(2);
end
for k =1:numel(xref)
rotpoint = R*([xref(k) ;yref(k)]);
xrefr(k) = rotpoint(1);
yrefr(k) = rotpoint(2);
end
for k =1:numel(x_top)
rotpoint = R*([x_top(k) ;y_top(k)]);
x_topr(k) = rotpoint(1);
y_topr(k) = rotpoint(2);
end
for k =1:numel(x_bottom)
rotpoint = R*([x_bottom(k) ;y_bottom(k)]);
x_bottomr(k) = rotpoint(1);
y_bottomr(k) = rotpoint(2);
end
%
figure(3);
plot(xr,yr,'*-b',xrefr,yrefr,'r--',x_bottomr,y_bottomr,'g--',x_topr,y_topr,'k--')
xlim([-4 8])
ylim([0 12])
axis square
hold on
% now create replicates of the rotated elipse along the reference line
% intersections makes finding the intersection points very easy.
[xout,yout] = intersections(xr,yr,xrefr,yrefr,1);
dx = diff(xout);
dy = diff(yout);
% do n duplicates
xr_spacing = 0.25; % along the reference line (rotated)
xy_spacing = R*([xr_spacing ;0]); % gives the true x and y spacing in the absolute referential
for n = 1:3
newx = xr + n*(dx+xy_spacing(1));
newy = yr + n*(dy+xy_spacing(2));
plot(newx,newy);
end
I have to leave now but I'll be back monday
hello again
so how are you doing ? problem solved ?
Good morning, the code seems to work now. I have the same output as you do. I would just need to try to make it work with my own code, as I am trying to do something a little more complex it seems like. I want my shape to be moving more like an animation, and from what you've given me, I will try to figure it out. Again, thank you for your help!
ok
just fyi this is just another way to plot the elipse on top of your contourf plot
I added a pause of 1 second in the last for loop that plots the duplicate of the elipse with some x spacing (as you wish)
x = 0:0.1:5;
y = 0:0.1:5;
[X,Y] = meshgrid(x,y);
Z = X.*exp(-X.^2-0.25*(Y-2.5).^2);
figure(1);
[cm, h] = contourf(X,Y,Z);
[contourTable, contourArray] = getContourLineCoordinates(cm);
% Show all lines that match the 7th level
hold on
levelIdx = contourTable.Level == h.LevelList(7);
xc = contourTable.X(levelIdx);
yc = contourTable.Y(levelIdx);
% create the reference line
xref = x;
yref = mean(y)*ones(size(xref));
% create top and bottom lines
[val,id_top]= max(yc);
x_top = (xc(id_top):0.1:xref(end));
y_top = val*ones(size(x_top));
[val,id__bottom]= min(yc);
x_bottom = (xc(id__bottom):0.1:xref(end));
y_bottom = val*ones(size(x_bottom));
plot(xc,yc,'-r',xref,yref,'r--',x_bottom,y_bottom,'g--',x_top,y_top,'k--')
hold on
% now create replicates of the elipse along the reference line
[xout,yout] = intersections(xc,yc,xref,yref,1);
dx = diff(xout);
dy = diff(yout);
% do n duplicates
x_spacing = 0.25; %
y_spacing = 0; %
for n = 1:3
pause(1)
newx = xc + n*(dx+x_spacing);
newy = yc + n*(dy+y_spacing);
plot(newx,newy);
end
Thank you! I have another question I guess now: the ellipse is on the coutour plot and it is "animated". Instead, could I make the whole thing move? Like the ellipse still be on the contourf and move the coutourf as well as the axis together along the same line and contourf would leave a trace as well?
Thank you
you mean this ?
x = 0:0.1:5;
y = 0:0.1:5;
[X,Y] = meshgrid(x,y);
Z = X.*exp(-X.^2-0.25*(Y-2.5).^2);
figure(1); hold on
xlim([0 10]);
x_spacing = 2;
N = 5;
for k = 1:N
pause(1)
[cm, h] = contourf(X+(k-1)*x_spacing,Y,Z);
[contourTable, contourArray] = getContourLineCoordinates(cm);
% Show all lines that match the 7th level
hold on
levelIdx = contourTable.Level == h.LevelList(7);
xc = contourTable.X(levelIdx);
yc = contourTable.Y(levelIdx);
plot(xc,yc,'-r');
end
Yes!! That's exactly what I meant!!
glad we finally converged !!
if you're happy with my suggestion, would you mind accepting it ?
Oh yeah of course!
Again, thank you so much for your help! I will try to implement it that way!! Thank you!!!
as always, my pleasure !

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2023a

Asked:

on 23 Jun 2023

Commented:

on 26 Jun 2023

Community Treasure Hunt

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

Start Hunting!