Animate surface plot in Matlab - matlab

I have a matrix representing height of a 10x10 square grid over time. The height is updated in a for loop over the rows and columns. My attempt was to simply put the surf(height) within the this loop, with a 0.1 second pause between plots, because this is how I done it with a 2-d plot. How can I make this work?

I think the best way is to update the data directly from your surface plot.
To do so, assign it a handles (eg. named hSurf) during its creation and then update the ZData property using, for example,
set(hSurf,'ZData',SomeValues)
Sample code:
clear
clc
close all
figure(1)
%// Generate data
Z = peaks(25);
%// Create handles to access/modify data.
hSurf = surf(Z);
k = 0;
%// Set up name to create animated gif.
filename = 'AnimateSurf.gif';
%// Just a loop
while k < 10
%// IMPORTANT part. Update the Z data
set(hSurf,'ZData',k*Z);
%// Set limits so the graph looks nice.
zlim([-80 80])
drawnow
%// Capture frame to write to gif.
frame = getframe(1);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if k == 0;
imwrite(imind,cm,filename,'gif', 'Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
pause(.15)
k = k+1;
end
And output:

Related

Get X Y coordinates of image

I need to find out how can i put obtained coordinates form image into a matrix and saving it.
clc
clear all
k=imread('l.jpg');
for i=1:4
figure(1),imshow(k)
axis on
hold on
title(i)
[x,y]=ginput(1)
pause
end
As the comments have suggested, here is a method thats stores the values into arrays by indexing the arrays x and y using and indexing variable i that is incremented on each loop iteration. As you probably know any Key must be pressed to continue the loop. The built-in MATLAB image 'tire.tif' is used in this example.
clc;
clear;
Image = imread('tire.tif');
imshow(Image);
axis on
Number_Of_Coordinates = 4;
x = zeros(1,Number_Of_Coordinates);
y = zeros(1,Number_Of_Coordinates);
for i = 1: Number_Of_Coordinates
title( i)
[x(i),y(i)] = ginput(1);
fprintf("Coordinates Stored: (%f,%f) -> Press and key to continue\n",x(i),y(i));
pause
end

creating a loop to save images from contour slice

I have the following code to plot a slice at any location in a fluid volume.
clc, clear all, close all
format long
%a ddpath('\\ds.leeds.ac.uk\staff\staff6\censsar\Polydisperse'); % <------Change
%% Import data
input = importdata('lci_000210.dat',' ',3);
nx = 96;
ny = 96;
nz = 49;
x = input.data(:,1);
y = input.data(:,2);
z = input.data(:,3);
Lci = input.data(:,4);
L3d = reshape(Lci,[nx,ny,nz]);
x3d = reshape(x,[nx,ny,nz]);
y3d = reshape(y,[nx,ny,nz]);
z3d = reshape(z,[nx,ny,nz]);
contourslice(y3d,x3d,z3d,L3d,[],[],[0.3]);
ax=gca;
ax.Children(1).LineStyle='none';
ax.Children(2).LineStyle='none';
ax.Children(3).LineStyle='none';
view(25,20);
colormap jet
colorbar
What I would like to do is have the contour slice in a loop so that it creates and saves a slice at each z location. I want to hopefully create a movie of the z slice moving from zero and going up the 3d axis.
I have tried something like:
Z=[0 0.1 0.5];
for S = 1:length(Z)
h = figure
contourslice(y3d,x3d,z3d,L3d,[],[],[Z],10);
saveas(h,sprintf('Fig%d.png',S));
end
but this is not working, I am not sure how to define the z axis in the loop, so it creates a slice at each point.
Here is the link to my data, it is a .dat file so it contains the data in 4 columns.
To create a set of slices in a loop you have to modify your code by replacing the last but one parameter in the call to contourslice by specifiybg the i-th element of the array Z.
Since you did not post your input data I've tested the proposed solution on an example data from MatLab contourslice help slightly modified in which
are created nine contour plots in the y-z plane, no plots in the x-z plane, and one plot in the x-y plane by specifying Sx as a vector of nine elements, Sy as an empty vector, and Sz as a scalar (from MatLab help).
Yoy have to adapt the definition of the Sx, Sy and Sz parameters to your needs.
To create a movie you can use the functions:
videowriter to create the video object
open to open the video file
getframe to capture axes or figure as movie frame
close to close and save the video file
As an alternative to the movie, you can create an animated gif by using the function imwrite
% Load input data
[X,Y,Z,V] = flow;
% Define the parameters for the set of slices
Sx = 1:9;
Sy = [];
Sz = [];
cvals = linspace(-8,2,10);
% Open the FIGURE window
figure
% Create the axes and set tehiur properties
axis([0,10,-3,3,-3,3])
hold on
daspect([1,1,1])
campos([0,-20,7])
box on
% Create the movie object
mov=VideoWriter('contour_slice_movie.avi');
% Open the movie file
open(mov);
% Define the number of frames to be captured for each slice
n_frame_x_image=33;
% Loop over the desired number of slices
for i=1:length(Sx)
contourslice(X,Y,Z,V,Sx(i),Sy,Sz,cvals)
% Capture the frames
for j=1:n_frame_x_image
FF=getframe(gcf);
writeVideo(mov,FF);
end
end
% Close the movie file
close(mov);

Add space between plots for the plotmatrix function

Is there a way to add some space between the plots for the plotmatrix function? (I would like to label every x and y axis)
You can do it by using a specific output argument in the call to plotmatrix. You can then retrieve the position of each individual axes and modify it (making it smaller).
Example:
clc
clear
rng default
X = randn(50,3);
Y = reshape(1:150,50,3);
%// Use this output argument
[~,AX,~,~,~] = plotmatrix(X,Y);
%// Fetch all the positions and alter them (make axes smaller)
AllPos = get(AX(:),'Position');
AllPos = vertcat(AllPos{:});
NewPos = [AllPos(:,1)+.05 AllPos(:,2)+.05 AllPos(:,3)-.1 AllPos(:,4)-.1]
%// Update the plot
for k = 1:numel(AX)
axes(AX(k))
set(AX(k),'Position',NewPos(k,:))
xlabel(sprintf('Axes %i',k))
end
Outputs the following:
In contrast to the original plot:

Background Image for Plot

Is there an easy way to put a bitmap image in the background of a Matlab plot which does not fill the whole available space und keeps its aspect ratio when the figure is resized?
TIA
I'm not quite sure to understand what you mean by
plot which does not fill the whole available space
however the following solution should help you solve your problem (or at least get you started).
Basically read an image (here grayscale) and display it using the imagesc command along with the grayscale colormap, then issue the hold on command and plot the data. Notice that you need to reverse the direction of the x-axis in order to get the right direction for the plot.
Here is the code:
clear
clc
close all
A = imread('cameraman.tif');
x = 1:10;
y = x;
figure
%// Notice the fliplr(A) to reverse the direction of the x data
imagesc([min(x(:)) max(x(:))], [min(y(:)) max(y(:))],fliplr(A));
colormap gray
%// Here reverse the direction of the x axis, otherwise the plot is
%// reversed
set(gca,'XDir','reverse')
hold on
plot(x,y,'--r')
axis off
And the result:
If your background image is RGB, you can use the image function: (modified from answer here): You need to flip the x data from the image for each channel separately, because fliplr only accepts 2D arguments:
DataXImage = linspace(min(x), max(x), size(A, 2));
DataYImage = linspace(min(y), max(y), size(A, 1));
%// flip dimensions for each channel
B = cat(3,fliplr(A(:,:,1)),fliplr(A(:,:,2)),fliplr(A(:,:,3)));
image(DataXImage, DataYImage, B, 'CDataMapping', 'scaled');
which, using the peppers.png image, gives this:
Is this what you had in mind? If not please tell me!
img = imread('myimage.png');
% set the range of the axes
% The image will be stretched to this.
min_x = 0;
max_x = 8;
min_y = 0;
max_y = 6;
% make data to plot - just a line.
x = min_x:max_x;
y = (6/8)*x;
imagesc([min_x max_x], [min_y max_y], img);
hold on;
plot(x,y);

How to do an animated plot in matlab

I was wondering if anyone knew how to do an animation plot of
x = (dataset of 1000 points)
y = (dataset of 1000 points)
plot(x,y)
big problem is these are datasets that i am trying to plot , or x,y coordinates as opposed to a function which I would know how to plot via an animation.
I tried to do frames in a for loop but it gave me dots and didn't join them in a line graph so I couldn't really watch the path being traced out.
code I used was
for i = 1:length(DATASET1)
pause(0.1)
plot(DATASET1(i),DATASET2(i))
draw on
end
If what you want is for the plot to "grow" point by point: the easiest way is to create an empty plot and then update its XData and YData properties at each iteration:
h = plot(NaN,NaN); %// initiallize plot. Get a handle to graphic object
axis([min(DATASET1) max(DATASET1) min(DATASET2) max(DATASET2)]); %// freeze axes
%// to their final size, to prevent Matlab from rescaling them dynamically
for ii = 1:length(DATASET1)
pause(0.01)
set(h, 'XData', DATASET1(1:ii), 'YData', DATASET2(1:ii));
drawnow %// you can probably remove this line, as pause already calls drawnow
end
Here's an example1 obtained with DATASET1 = 1:100; DATASET2 = sin((1:100)/6);
1 In case someone's interested, the figure is an animated gif which can be created by adding the following code (taken from here) within the loop, after the drawnow line:
frame = getframe(1);
im = frame2im(frame);
[imind,cm] = rgb2ind(im,256);
if ii == 1;
imwrite(imind,cm,filename,'gif','Loopcount',inf);
else
imwrite(imind,cm,filename,'gif','WriteMode','append');
end
Looks like you were close. Not sure draw on is any command though.
See if the code here inspires you to solve your case -
%// Sample x and y values assumed for demo.
x = 1:1000;
y = x.^2;
%// Plot starts here
figure,hold on
%// Set x and y limits of the plot
xlim([min(x(:)) max(x(:))])
ylim([min(y(:)) max(y(:))])
%// Plot point by point
for k = 1:numel(x)
plot(x(k),y(k),'-') %// Choose your own marker here
%// MATLAB pauses for 0.001 sec before moving on to execue the next
%%// instruction and thus creating animation effect
pause(0.001);
end
Since R2014b, you can work with annimatedline object (doc and how-to) that is meant to handle animated graphs pretty well. Basically, the annimatedline object has a addpoints function that adds new points to the line without having to redefine the existing points, along with a clearpoints function that clears lines for more complex animations.
Here is an example:
h = animatedline;
axis([0,4*pi,-1,1])
x = linspace(0,4*pi,1000);
y = sin(x);
for k = 1:length(x)
addpoints(h,x(k),y(k));
drawnow
end