MATLAB keeps updating the wrong plot - matlab

I'm really hoping this isn't some stupid little thing I'm missing, but I've been trying to figure this thing out for a couple hours now and haven't made any progress. Basically, I've created a figure with 3 subplots. For neatness, I made a function out of setting up the plots, then I made another function that constantly updates the plot with real time data.
The problem is, in the real time update function, the third subplot works perfectly fine, but now I want my second subplot to also real-time update, which I have not gotten done yet. For some reason, whenever I put in my code to access the 2nd plot, it keeps updating the 3rd plot and writing right over it! Meanwhile, the second plot stays in it's initial state...
Here is the code...I've looked over it a billion times so I'm at a loss at this point, I don't know what else to do....like I said really hoping it isn't something dumb lol...thanks a bunch =).
EDIT: The part that's going wrong starts where it says "%refresh plot
Real Time Plot Function
function [ ] = EndoSliceViewerJP( Naviparam, DICOMparam)
%RGBparam should be included later - add +1 to nargin values
%visualizes:
%1st: RGB camera Live view
%2nd: Orientation and Position of Navigation System
%3rd: DICOM Slice relative to navigated Endoscope in a and its orientation
%in a Slice perpendicular to the endoscope
%assumes Navigation system running with referenced tool (Naviparam.tool=4 or Naviparam.tool=5)
%currently this plots slices according to Endoscope position, could add
%vector in plot that shows orientation of the scope...
disp('Endo Slice Viewer');
disp('" ": exit on space key');
global kpressed;
kpressed = 0;
global Fig
Fig=EndoSliceViewer_createFigure(1);
set(Fig.fig,'KeyPressFcn','global kpressed; global Fig; kpressed = get(Fig.fig,''CurrentChar'');');
%create matrices and filter for smoothing of Endo Slice Data
xrel=-(ones(Fig.resolEndoSlice,1)*(1:Fig.resolEndoSlice)-Fig.resolEndoSlice/2);
yrel=-(ones(Fig.resolEndoSlice,1)*(1:Fig.resolEndoSlice)-Fig.resolEndoSlice/2);
SLimage=zeros(Fig.resolEndoSlice,Fig.resolEndoSlice);
PosVec=zeros(Fig.resolEndoSlice,Fig.resolEndoSlice,3);
gfilt = fspecial('gaussian',5,1.5);
depth = 50;
exitflag = 0;
while (exitflag == 0)
%check on keyboard input
if kpressed ~= 0
switch kpressed
case 'r'
depth=depth+2
case 'f'
depth=depth-2
case ' '
exitflag = 1;
disp('**** Exit Endo Slice Viewer ****')
end
kpressed = 0;
end
if (nargin>=1) %Naviparam is passed - update Navigation View
%capture new navigation data
Naviparam=Navi_acquire(Naviparam);
Naviparam=Navi_calc_data(Naviparam);
%refreshN avigation View
%NOT YET IMPLEMENTED: UPDATE NAVIGATION PLOT
if (nargin==2) %DICOMparam is also passed - update EndoSlice View
EndoVecX=inv(DICOMparam.calib.navi2dicom(1:3,1:3))*inv(Naviparam.data.Endo_RefHomMat(1:3,1:3))*[1;0;0];
EndoVecY=inv(DICOMparam.calib.navi2dicom(1:3,1:3))*inv(Naviparam.data.Endo_RefHomMat(1:3,1:3))*[0;1;0];
EndoVecZ=inv(DICOMparam.calib.navi2dicom(1:3,1:3))*inv(Naviparam.data.Endo_RefHomMat(1:3,1:3))*[0;0;-1];
EndoVecX=EndoVecX/norm(EndoVecX);
EndoVecY=EndoVecY/norm(EndoVecY);
EndoVecZ=EndoVecZ/norm(EndoVecZ);
mask=ones(Fig.resolEndoSlice,Fig.resolEndoSlice);
S=[DICOMparam.Sx; DICOMparam.Sy; DICOMparam.Sz];
DICOMPos = DICOMparam.calib.navi2dicom*[Naviparam.data.Endo_RefOffsetPosVec;1];
for i=1:3
%Point on Plane defined by Endo Position plus distance*Viewing direction vector
PosVec(:,:,i)=(DICOMPos(i)+depth*EndoVecZ(i))+xrel*EndoVecX(i)+yrel*EndoVecY(i);
%limit positions to integer values inside DICOM data cube
PosVec(:,:,i)=round(PosVec(:,:,i));
PosVec(:,:,i)=min(max(PosVec(:,:,i),1),S(i));
%create mask to set Points outside the data cube to 0
mask=double(PosVec(:,:,i)>1).*double(PosVec(:,:,i)<S(i).*mask(:,:));
end
%access data cube via indexed labelling
XposTemp=PosVec(:,:,1); YposTemp=PosVec(:,:,2); ZposTemp=PosVec(:,:,3);
indexTemp=sub2ind(size(DICOMparam.Vd), XposTemp(:), YposTemp(:),ZposTemp(:));
SLimage(:)=DICOMparam.Vd(indexTemp(:));
SLimage=SLimage.*mask;
SLimage=imfilter(SLimage,gfilt);
%refresh plot
set(Fig.sub3im, 'cdata', SLimage);
hold on;
Fig.sub2im=plot3(PosVec(1),PosVec(2),PosVec(3),'b*',PosVec(1)+depth*EndoVecZ(1),PosVec(2)-depth*EndoVecZ(2),PosVec(3)+depth*EndoVecZ(3),'r*');
hold off;
end
end
%RGBparam is always passed - update RGB camera View
%capture new RGB data
%handles.RGBparam=RGB_acquire(handles.RGBparam);
%refresh RGB camera View
%set(Fig.sub1im, 'CData', imresize(handles.RGBparam.image,[Fig.resolEndoRGB(1) Fig.resolEndoRGB(2)]));
drawnow;
end
close(Fig.fig);
clear global;
end
And here is my function setting up the plot
function [Fig] = EndoSliceViewer_createFigure(Figindex)
%This function creates and returns a Figure object to visualizes DICOM data
%in the plane orthogonal to the endoscopic view, the RGB view of the camera
%and the orientation of the navigation
%set resolution for Endo Slice Plot
Fig.resolEndoSlice=300;
Fig.resolEndoRGB=[720 1280];
Fig.resolEndoNavi=[500 500 500];
%init figure on screen
Fig.fig=figure(Figindex); gcf;
set(Fig.fig,'Position',[50 500 1500 500],'Name','Endo Slice Viewer');
%set(Fig.fig,'KeyPressFcn','global kpressed; global Fig; kpressed = get(Fig.fig,''CurrentChar'');');
Fig.sub1=subplot(1,3,1);
Fig.sub1im=image(uint8(zeros(Fig.resolEndoRGB(1), Fig.resolEndoRGB(2),3)));
title('Endo Camera View');
daspect([1 1 1]);
Fig.sub2=subplot(1,3,2);
Fig.BoxX=[0;1;1;0;0;0;1;1;0;0;1;1;1;1;1;0;0]*Fig.resolEndoNavi(1);
Fig.BoxY=[0;0;1;1;0;0;0;1;1;1;1;1;0;0;0;0;1]*Fig.resolEndoNavi(2);
Fig.BoxZ=[0;0;0;0;0;1;1;1;1;0;0;1;1;0;1;1;1]*Fig.resolEndoNavi(3);
Fig.sub2im=plot3(Fig.BoxX,Fig.BoxY,Fig.BoxZ);
title('Navigation View');
xlim([-0.2*Fig.resolEndoNavi(1), 1.2*Fig.resolEndoNavi(1)]);
ylim([-0.2*Fig.resolEndoNavi(2), 1.2*Fig.resolEndoNavi(2)]);
zlim([-0.2*Fig.resolEndoNavi(3), 1.2*Fig.resolEndoNavi(3)]);
xlabel('X [vox]');
ylabel('Y [vox]');
zlabel('Z [vox]');
daspect([1 1 1]);
Fig.sub3=subplot(1,3,3);
Fig.sub3im=imagesc(zeros(Fig.resolEndoSlice, Fig.resolEndoSlice));
title('Endo Slice View');
xlim([0 Fig.resolEndoSlice]);
ylim([0 Fig.resolEndoSlice]);
xlabel('Xendo [vox]');
ylabel('Yendo [vox]');
daspect([1 1 1]);
colormap bone
drawnow;
%potentially: add subplot for navigation position display later
end

You need to set your second subplot as the current axes before plotting anything in it. You can use axes(Fig.sub2) before the plotting command.

Related

How to update / animate a complicated figure in MATLAB?

I need to animate a complex figure consisting of a chain of rectangles, forming an arm.
Here is an example of how this arm looks like when not animated :
To animate this figure, I made the following code :
function renderFrame(fig, data)
hold(ax, 'on'); % Need to hold so that new elements of the arm add themselves
showMembers(fig, data); % Create patches and rotate them to the right angle to create members
showJoints(fig, data); % Draw circles at the joints betwwen the members. Use the width of rectangle members
drawnow;
hold(ax, 'off'); % Next rendering will replace this one; No need to hold
end
function rotateMember(fig, data, iMember, rotAngle)
for iAngle = 1:rotAngle
updateMemberAngle(data, i, 1); % Change thew data so the i-th member rotates by 1
renderFrame(fig); % Show frame after the data was changed
end
end
function main()
fig = figure;
ax = gca;
axis(ax, 'equal');
setAxis(data); % Set axis limits and create axis arrows with totalLength of the arm
renderFrame(ax, data);
rotateMember(fig, data, 3, 90); % Rotate 3rd member by 90 degrees
end
main()
But the frames of my animation doesn't clear at all. It results in this figure :
What am I doing wrong ? Is there a way to plot complicated figures with multiple parts and to animate it, by clearing frame ?
I looked into using newplot and nextplot, but MATLAB's documentation on the subject is incomplete, as always. I also tried creating graphic objects and then setting the data at each iteration, but it rejects an exception every time the figure is deleted since "graphics objects are deleted".
It seems to me as if in your approach, you're not erasing the plot when drawing the next frame. Maybe calling cla() prior to drawing the next frame would make it work? However, this may produce a flickering behavior if the redrawing is done in the wrong order.
I suggest taking a look at animation techniques in Matlab to see three different ways to produce animations.
Found a way to clear the axis childrens, except the two axis quivers (arrows).
Here is a code that works properly:
function renderFrame(renderAxes, data)
% CHECK IF THERE ARE MORE GRAPHIC OBJECTS THAN ONLY THE QUIVERS
if ~(length(renderAxes.Children) == 2)
% DELETE EVERYTHING EXCEPT THE AXIS QUIVERS THAT WERE RENDERED AT THE BEGINNING
% MATLAB ADDS NEW GRAPHIC OBJECTS TO THE BEGINNING OF AX.CHILDREN
delete(renderAxes.Children(1:length(renderAxes.Children)-2))
end
showMembers(renderAxes, data); % Create patches and rotate them to the right angle to create members
showJoints(renderAxes, data); % Draw circles at the joints betwwen the members. Use the width of rectangle members
drawnow;
end
function rotateMember(ax, data, iMember, rotAngle)
for iAngle = 1:rotAngle
updateMemberAngle(data, i, 1); % Change thew data so the i-th member rotates by 1
renderFrame(ax, data); % Show frame after the data was changed
end
end
function main()
fig = figure;
ax = gca;
axis(ax, 'equal');
% HOLD AXES AT THE BEGINNING OF THE SCRIPT
hold(ax, 'on');
setAxis(data); % Set axis limits and create axis arrows with totalLength of the arm
renderFrame(ax, data);
rotateMember(ax, data, 3, 90); % Rotate 3rd member by 90 degrees
end
main()

How to subplot + imagesc with a Position in Matlab?

Situation: change Position of a single subplot with imagesc
%% Matlab recommends this structure if axes(); in loop
a1 = subplot(1,2,1);
a2 = subplot(1,2,2);
while 1    
plot(a1, rand(3))    
plot(a2, rand(3))    
drawnow
end
%% Test code
unitsPerInches=[0 0 15 15];
figure('Units', 'inches');
a1 = subplot(1,2,1);
a2 = subplot(1,2,2);
while 1    
set(a1, 'Position', unitsPerInches); % TODO how to affect a1's Position here only?
imagesc(a1, rand(3))    
imagesc(a2, rand(3))    
drawnow
end
Open
What is imagesc corresponding structure to plot(a1,rand(3))?
How to change Position of figure inside the loop?
Forward in Q1 - almost done
%% Extension to imagesc
figure
a1=subplot(1,2,1);
a2=subplot(1,2,2);
for counter=1:2;
imagesc(a1,rand(3))
imagesc(a2,rand(3))
drawnow
end
Fig. 1 Output of Docs example, Fig. 2 Output of Imagesc, Fig. 3 about Q2 where Position affects both subplots
Q1 is almost done; I have just forgotten how to get corresponding plot in imagesc; x-values should be put there but pseudocode imagesc(a1,XDATA,rand(3)) is unsuccessfuly.
Backward in Q2
Code
%% Extension to imagesc
unitsPerInches=[0 0 15 15];
figure
a1=subplot(1,2,1);
a2=subplot(1,2,2);
for counter=1:2;
set(a1, 'Position', unitsPerInches); % TODO how to affect a1's Position here only?
imagesc(a1,rand(3))
imagesc(a1,rand(3))
drawnow
end
Output: position affects both images in Fig. 3.
I think I have misunderstood the meaning of Position here because so strange output.
Testing EBH's proposal for Q2
The implicit assignments cause problems when having two figures where subplots
unitsPerInches=[0 0 15 15];
aFig=figure();
a1=subplot(1,2,1);
a2=subplot(1,2,2);
bFig=figure();
b1=subplot(1,2,1);
b2=subplot(1,2,2);
for counter=1:2;
if counter==1
set(a1, 'Position', unitsPerInches); % affect only position of a1
end
subplot(1,2,counter);
imagesc(rand(3));
drawnow
subplot(1,2,counter);
imagesc(rand(3));
drawnow
end
Output: second figure of subplots fails.
System: Linux Ubuntu 16.04 64 bit
Linux kernel 4.6
Matlab: 2016a
Related threads: Matlab7 'bug' when using "subplot" + "imagesc"?
I'm not 100% sure what you're asking, but I think it's about combining multiple imagesc statements while in a loop. I'd do something more direct -- use gca and put the subplot inside the loop. Quite often, if you want to programmatically address multiple images, it makes sense to put them in some sort of structure other than creating lots of differently named variables. Note also that while 1 is probably not really what you want -- it will hammer your graphics device drivers -- and that pause can take an argument to act as a wait function, for some fraction of a second if required.
testImages{1}=double(imread('coins.png'));
testImages{2}=double(imread('cameraman.tif'));
h=figure;
set(h,'color','w'); %This handle refers to the background window
for ix=1:2
subplot(1,2,ix);
imagesc(testImages{ix});
axis equal;
colormap gray;
%Change, for example, axis position
curPoss=get(gca,'Position'); %gca stands for 'get current axis'
set(gca,'Position',curPoss+1e-2*ix^2); %Move one image up a bit
end
Does that help?
If you want to jump between figures, make an array of them, and use it within a loop:
unitsPerInches = [0.1 0.1 0.15 0.15];
figs = [figure(1) figure(2)];
for f = 1:numel(figs)
figure(figs(f));
for counter = 1:2;
subplot(1,2,counter);
imagesc(rand(3));
drawnow
end
figs(f).Children(1).Position = unitsPerInches;
figs(f).Children(2).Position = unitsPerInches+0.3;
end
Your original values for unitsPerInches was wrong, since the 'Position' property of an axes takes values between 0 to 1 by default. You can change this using the 'Units' property, like:
figs(f).Children(1).Units = 'inches';
The output from this example is two figures that looks like this:
Where there is a small axes on the down-left and a big one on the top-right.
So, back to your original questions:
What is imagesc corresponding structure to plot(a1,rand(3))?
Instead of passing the axes to imagesc, set the focus on the relevant figure, and subplot with:
figure(h)
subplot(x,y,c)
imagesc(data)
where h is a handle to the relevant figure, c is the place of the subplot within h where you want to plot the image (a number between 1 to x*y), and after these two line you call imagesc.
How to change 'Position' of figure inside the loop?
In this question it is not clear if you want to change the 'Position' of the figure or the axes, they have different units and meaning, but both are accessible in the same way:
h.Position = [left bottom width height]; % for the position of the figure
h.Children(c).Position = [left bottom width height]; % for the position of the axes
where h is as before, but c may be numbered differently, so subplot(x,y,c) may not refer to the same axes as h.Children(c). However, you can always use gca to get the current axes handle:
ax = gca;
ax.Position = [left bottom width height];
Hope it's all clear now, and if there are further questions, let me know ;)

How to continuously update 2 plots and plotted Camera in same figure (MATLAB)

My goal is to continuously plot the position & orientation of camera relative to marker using MATLAB.
There are three thing to plot.(1)camera (2)all circle points (3)origin point '*'
Both the camera and points will be moving in each frame.I plotted all these three things in a static figure i.e. using hold on. as shown in the attached figure.
Now i want to plot them all continuously (real time) in the same figure as the values change.Till now i have only been able to dynamically update only one of these things i.e. the circular points for some random values. If I add another plot ,it conflicts.Can you please tell me how to update multiple plots in same figure and the plotCamera.
hF = figure;
hAx = gca;
im_pt_2world=rand(3,3);
x_o=im_pt_2world(1,1); y_o=im_pt_2world(1,2); %origin of the calibrated world points
x_ip=im_pt_2world(:,1); y_ip=im_pt_2world(:,2);
hpoints = plot3(x_ip, y_ip,zeros(size(im_pt_2world, 1),1),'ro');
% I added the "ishandle" so the program will end in case u closed the figure
while (1) & ishandle(hpoints)
%instead of using plot I directly change the data in the line
% this is faster the plot if only because you don't need to reedefine the limits and labels...
im_pt_2world=rand(3,3);
x_ip=im_pt_2world(:,1); y_ip=im_pt_2world(:,2);
set(hpoints,'ydata',y_ip);
set(hpoints,'xdata',x_ip);
drawnow %updates the display
end
The plotCamera function (Computer Vision System Toolbox) returns a handle to the graphical object, which you can manipulate programmatically. Changing the object's properties, such as Location and Orientation will move the camera in the plot. The help example for plotCamera shows how to make the camera fly in a circle:
% Plot a camera pointing along the Y-axis
R = [1 0 0;
0 0 -1;
0 1 0];
% Setting opacity of the camera to zero for faster animation.
cam = plotCamera('Location', [10 0 20], 'Orientation', R, 'Opacity', 0);
% Set view properties
grid on
axis equal
axis manual
% Make the space large enough for the animation.
xlim([-15, 20]);
ylim([-15, 20]);
zlim([15, 25]);
% Make the camera fly in a circle
for theta = 0:pi/64:10*pi
% Rotation about cameras y-axis
T = [cos(theta) 0 sin(theta);
0 1 0;
-sin(theta) 0 cos(theta)];
cam.Orientation = T * R;
cam.Location = [10 * cos(theta), 10 * sin(theta), 20];
drawnow();
end
If you really want to have fun with this, you can supply a function handle to be called when you click on the camera. For example, the function can display the image that the camera sees.

How to animate points on an image in MATLAB?

I have the pixel locations of P points on a -constant- image, for T iterations of an algorithm, so locations = [T x 2*P] double.
Now I want to create an animation where it plots the image, then plots the points, pauses for N seconds and updates their location to the next step. I don't know if there is a standard way to follow. I think I need something like:
figure;
imshow(img);
hold on;
for t=1:T
anim = updatePlot(locations(t,:), anim); % ?
end
How can I implement this updatePlot function?
Thanks for any help!
You can do this a couple of different ways. The first way would be to give the plotted points a handle so that you can delete them before the next iteration:
figure
imshow(img);
hold on;
for t = 1:T
% delete the previous points plotted (skip t = 1 since they won't exist)
if t > 1
delete(hPoints);
end
hPoints = plot(xLocations(t,:),yLocations(t,:),'.');
getframe;
pause(N);
end
(I am not exactly sure how you parse your locations along each row to separate the x and y components, so I've just used xLocations and yLocations to represent those values.)
The second way would be to re-draw the entire image at each iteration:
figure
for t = 1:T
clf;
imshow(img);
hold on;
plot(xLocations(t,:),yLocations(t,:),'.');
getframe;
pause(N);
end
Note that imshow might have its own getframe effect so that you'll see the image flicker before plotting the points -- if that happens just switch from imshow to image.

How to make a smooth rotation of a 3D plot in MATLAB?

If I try to rotate camera around my current figure with plot3 using
while true; camorbit(0.9,-0.1); drawnow; end
then the rotation periodically hangs for a while (example) even on 8-core MacPro.
Can I make it smooth?
EDIT1:
While there is no solution for my original question yet, I've managed to make a better movie with getframe function. It doesn't allow recording free-hand rotation, though, and is quite buggy in MATLAB2010b for Mac.
%# fix wrong figure position in MATLAB2010b for Mac - depends on your layout
correctedPosition = get(gcf,'Position') + [21 -125 0 0];
fps = 60; sec = 10;
vidObj = VideoWriter('newfile.avi');
vidObj.Quality = 100;
vidObj.FrameRate = fps;
open(vidObj);
for i=1:fps*sec
camorbit(0.9,-0.1);
writeVideo(vidObj,getframe(gcf, correctedPosition));
end
close(vidObj);
EDIT2:
I created a similar thread at MATLAB Central.
EDIT3:
You can try it yourself downloading one of my figures.
I would say it's the large number of points you are drawing that's causing the slowdown. One option is to downsample.. Also you could use lower-level functions to draw (check this related post for a comparison of plot3/scatter3/line performance).
Consider the animation below optimized for speed:
[X Y Z] = sphere(64);
X = X(:); Y = Y(:); Z = Z(:);
%# set-up figure
hFig = figure('Backingstore','off', 'renderer','zbuffer');
%# use lower-level function LINE
line(0.50*[X,X], 0.50*[Y,Y], 0.50*[Z,Z], 'LineStyle','none', 'Marker','.', 'MarkerSize',1, 'Color','r')
line(0.75*[X,X], 0.75*[Y,Y], 0.75*[Z,Z], 'LineStyle','none', 'Marker','.', 'MarkerSize',1, 'Color','g')
line(1.00*[X,X], 1.00*[Y,Y], 1.00*[Z,Z], 'LineStyle','none', 'Marker','.', 'MarkerSize',1, 'Color','b')
view(3)
%# freeze the aspect ratio to override stretch-to-fill behaviour
axis vis3d
%# fix the axes limits manually
%#set(gca, 'xlim',[-1 1], 'ylim',[-1 1], 'zlim',[-1 1])
axis manual
%# maybe even remove the tick labels
%set(gca, 'xticklabel',[], 'yticklabel',[], 'zticklabel',[])
%# animate (until figure is closed)
while ishandle(hFig); camorbit(0.9,-0.1); drawnow; end
Note how we are using the Z-buffer renderer, and turned off the Backingstore property.
EDIT:
If I understood correctly, what you are trying to do is to record a screencast (using a 3rd-party app), while you manually rotate the figure, but in your case these manual rotations are "jumpy". On the other animating your figure with CAMORBIT/VIEW in a while-loop is running smooth...
I propose an alternative solution: start by rotating the figure using the mouse and write these view configurations at each step (azimuth,elevation). Then you can replay them using the VIEW function while recording the video, something like:
v = [...]; %# matrix where each row specify Az/El of view
for i=1:size(v,1)
view( v(i,:) )
drawnow
end
The downside is that you will have to press/rotate/release using the mouse in small steps (the ROTATE3D object does not expose a mouse-motion event)
I wrote a simple function to help you in this process. It loads the saved figure, enable 3d-rotation, and keeps track of the intermediate position at each step. Once finished, press the "Done" button to return the list of views...
function v = rotationDemo(figFileName)
views = []; %# list of views (Az,El)
hFig = hgload(figFileName); %# load the saved figure
views(1,:) = get(gca,'View'); %# store initial view
%# add a button, used to terminate the process
hButton = uicontrol('Style','pushbutton', 'Position',[400 1 80 20], ...
'String','Done?', 'Callback',#buttonCallback);
set(hFig, 'Toolbar','figure') %# restore toolbar
%# start 3d rotation, and handle post-callback to record intermediate views
h = rotate3d(hFig); %# get rotation object
set(h, 'ActionPostCallback',#rotateCallback)
set(h, 'Enable','on') %# enable rotation
msgbox('Rotate the view step-by-step', 'rotate3d', 'warn', 'modal')
uiwait(hFig) %# wait for user to click button
delete(hButton) %# delete button on finish
set(h, 'Enable','off') %# disable rotation
v = round(views); %# return the list of views
%# callback functions
function rotateCallback(o,e)
views(end+1,:) = get(e.Axes,'View'); %# add current view to list
end
function buttonCallback(o,e)
uiresume(gcbf) %# uiresume(hFig)
end
end
You can call the above function, then replay the animation:
v = rotationDemo('smooth_rotation.fig');
for i=1:size(v,1)
view(v(i,:))
drawnow
end
We can smooth the transitions by simple interpolation:
v = rotationDemo('smooth_rotation.fig');
n = size(v,1);
nn = linspace(1,n,100)'; %'# use 100 steps
vv = round( [interp1(v(:,1),nn) interp1(v(:,2),nn)] );
for i=1:size(vv,1)
view(vv(i,:))
DRAWNOW %# or PAUSE(..) to slow it down
end
As a side note, I should mention that ROTATE3D and CAMORBIT have different effects. ROTATE3D changes the View property of the current axis, while CAMORBIT controls the camera properties CameraTarget/CameraPosition/CameraUpVector of the current axis.
I recognize the same jerking movements that you are talking about on a regular MATLAB Figure. But when I tried running the Amro's code, created a movie (*.AVI), it looks smooth on my Mac notebook also.
The movie making code that I used is the following:
% Added the 'Visible' property of the figure 'off' while making a movie (although I am not exactly certain if this will make the situation better) like so:
hFig = figure('Backingstore','off','visible','off','renderer','zbuffer');
% Then, I replaced Amro's while-loop with a simple AVI production loop, as follows:
aviobj=avifile('test.avi'); %creates AVI file
for I=1:360
camorbit(0.9,-0.1); drawnow;
aviobj=addframe(aviobj,hFig); %adds frames to the AVI file
end
aviobj=close(aviobj); %closes AVI file
close(hFig); %close hFig
Question:
Would it help to decimate some points or to create a density map before rendering the figure?
[Ref. on various Rendering Options: http://www.mathworks.com/support/tech-notes/1200/1201.html ]
I hope the comments above would be of any help.
I don't know if this will help your issue, but for some reason, I've had better success with pause(0.001) than drawnow to force an update of the graphics window
You might also see if rotate3d is faster.
The number of cores doesn't matter as much as you think, as many functions in matlab do not support multi-threading.
A workaround would be to proceed as you are now, but write the figure window to a movie file. Then you can play back the movie.