Setting and fixing axes and figure handle in plot3

18 views (last 30 days)
Hi there, I'm new to computing in MATLAB and I've been trying to get my head around the axes handle and figure handle. I'm doing a simple animation by updating the plot3 using hold on and hold off in a for loop for each iteration.
  1. I would like to fix the axes and figure properties of the plot3 outside the for loop and only update the data in the for loop.
This is part of the structure of my code:
.....
h.figure1=figure('Name','Shimmer 1');
h.axes=axes('Linewidth',[4],'DataAspectRatio',[1 1 1],'XGrid','on','YGrid','on','ZGrid','on','XLim',[-2 2],'YLim',[-2 2],'ZLim',[-2 2]);
for i=1:10000
%data processing and calculation
%updating data for plot3
set(h.figure1,'CurrentAxes',h.axes);
subplot(2,2,1)
plot3(...);
hold on
subplot(2,2,2)
plot(...)
fill3(..)
pause(0.0001)
hold off
end
2- What have I done wrong in the code above?
3- I would also like to label the axis as 'x','y','z' outside the for loop, and fixed it throughout the 'animation' but it turns out the xlabel,ylabel, and zlabel are not axes properties. How would i do that?
Any help would be much appreciated. Thanks!

Answers (2)

dpb
dpb on 6 Jul 2013
Mat
h.figure1=figure('Name','Shimmer 1');
h.axes=axes('Linewidth',[4],'DataAspectRatio',[1 1 1], ...
'XGrid','on','YGrid','on','ZGrid','on', ...
'XLim',[-2 2],'YLim',[-2 2],'ZLim',[-2 2]);
%
for i=1:10000
%data processing and calculation
%updating data for plot3
set(h.figure1,'CurrentAxes',h.axes);
plot3(...);
hold on
pause(0.0001)
hold off
end
Above hold on does nothing as you immediately turn it back off so can just eliminate both.
Since there's no other figure in sight, the current axes will remain so so there's no need for the set(), either...
So, you're left basically with
M
%data processing and calculation for plot3
for i=1:10000
plot3(...);
pause(0.0001)
end
For other ways of doing animations, look in the documentation for the Animation section under Graphics/2D and 3D Graphics.
As for the labels, another useful tool when you're not sure what you're looking for...
Mat
>> lookfor label
imtext - Place possibly multi-line text as xlabel.
labeldtips - Display an observation's Y-data and label for a data tip
texlabel - Produces the TeX format from a character string.
xlabel - X-axis label.
ylabel - Y-axis label.
zlabel - Z-axis label.
clabel - Contour plot elevation labels.
menulabel - Obsolete function.
datetick - Date formatted tick labels.
>>
Also, type
get(gca)
at the comand line to see the properties and current values of the axes object when you need a refresher there on...
  2 Comments
Ken
Ken on 6 Jul 2013
Edited: Ken on 6 Jul 2013
Thanks for the reply. Sorry, I should be clearer with my code. I can't remove the 'hold on' and 'hold off' as I used a fill3 function in between them. In the for loop, the axes limit will change for each iteration depending on the size of the data in plot3 function, but I would like to fix them outside the for loop, is that possible with the hold off function in place? I'm aware that I can use the labeling in the for loop such that:
if true
% code
for i=1:1000
%update data
plot3(data);
xlabel('x'); ylabel('y'); hold off;
end
I don't want to invoke the xlabel,ylabel, everytime in the for loop, is there a way of fixing them outside the for loop while keeping the 'hold off' function in place in the for loop? Thanks!
dpb
dpb on 6 Jul 2013
One rule in posting...we can only comment on what we see... :)
If it ain't there in the post, it doesn't exist as far as we know here (albeit on the rare occasion the crystal ball does work, but it's rare and I've been known to complain mine spends an inordinate amount of time in the shop).
I don't quite follow the question/request. HOLD ON will cause the axis limits to remain as were when a new plot request comes along; with HOLD OFF the limits will be automagically scaled to the range of the new data. Now, are the limit changes between each iteration desired or an artifact you're trying to remove? If the former then you will want HOLD OFF before the PLOT3 call each pass to rescale based on that set of data and ON for the FILL3 as you had...that makes sense w/ that additional call per loop.
If you instead want the later iterations to be on the same scale as the first then set HOLD ON after the first call (and can put in an IF...END clause to not execute every pass and don't turn it back ON. It just depends on which effect you're after.
The [X|Y|Z]LABEL call can be anywhere after the axis is created; there's no need for them in the loop at all. For single plots it's probably the most common pattern for folks to just add them after the plotting commands but since you're running an animation and presumably want them showing while it's running that doesn't really help if it's after the loop completes.
Two ways to solve it -- first way,
Mat
for i=1:N
...
plot3(data);
hold on
fill3(data); % no idea on arg list; just the call in place
if i==1 % only write the labels first time
xlabel('x'); ylabel('y');
end % to lower overhead/superfluous stuff
A variation on a theme of the above is to calculate and plot3/fill3 the first case then write the labels before you build the loop. Then start the loop construct. That eliminates the if test each pass at the cost of a little code upfront that duplicates that in the loop.
Second and different way would be to first create the axes, label them, then begin the loop and plot onto those axes.
I suppose the IF TRUE...END block above is simply for debugging purposes of commenting out a section if you're not wanting to look at it for a time?

Sign in to comment.


dpb
dpb on 6 Jul 2013
In the for loop, the axes limit will change for each iteration depending on the size of the data in plot3 function, but I would like to fix them outside the for loop, is that possible with the hold off function in place?
Ah....it just dawned on me what you were asking...the answer is 'No'.
To set limits manually, use [X|Y|Z]LIM(). You can do this any time after the axes object is created, whether or not the data have yet been plotted. This will set the ?LimMode property to 'Manual'
BUT, if you then plot() that HOLD OFF is in effect means that the high-level routines will reinitialize to known state and that includes resetting the LimMode to 'Auto'
You can do this yourself by setting the NextPlot property of the current figure and axes to "add" but might as well just use HOLD as simpler.
So, for your problem, if you know a priori the limits you want, then when that is known use XLIM and friends to set and set HOLD ON until you're ready to change to a new set. But HOLD ON also has the effect of retaining existing data instead of replacing it so now you're in a quandary if want to keep the axis from rescaling but make a new plot w/o the old data hanging around.
Here's where the alternate animation ideas come into play -- replace the data itself directly instead of calling the high level routine(s)

Categories

Find more on Graphics Performance in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!