| Products & Services | Solutions | Academia | Support | User Community | Company |
| Download Product Updates | | | Get Pricing | | | Trial Software |
| Documentation → MATLAB |
| Contents | Index |
| Learn more about MATLAB |
| On this page… |
|---|
About the 3-D Animation Example |
This example GUI has 3-D axes in which the Earth spins on its axis. It accepts no inputs, but it reads a matrix of topographic elevations for the whole Earth. To the user, it looks like this.

The GUI provides controls to:
Start and stop the rotation.
Change lighting direction.
Display a latitude-longitude grid (or graticule).
Save the animation as a movie in a MAT-file.
Exit the application.
GUI-building techniques illustrated in this example include:
Changing the label (string) of a button every time it is clicked.
Storing data in the handles structure and using it to control callback execution.
Enabling a callback to interrupt its own execution.
Controlling scene lighting with two sliders that communicate.
In addition, two of the callbacks illustrate how to construct and manipulate the appearance of 3-D views.
If you are reading this document in the MATLAB Help browser, you can access the example FIG-file and M-file by using either of two sets of links listed below. If you are reading this on the Web or in PDF form, go to the corresponding section in the MATLAB Help Browser to use the links.
If you intend to modify the layout or code of this GUI example, first save copies of its M-files and FIG-files to your current folder. (You need write access to your current folder to do this.) Follow these steps to copy the example files to your current folder, and then open them:
Type guide globegui or click here to open the FIG-file in GUIDE.
Type edit globegui or click here to open the M-file in the Editor.
You can view the properties of any component by double-clicking it in the Layout Editor to open the Property Inspector for it. You can modify either the figure, the M-file, or both. Then you can save the GUI in your current folder using File > Save as from GUIDE. This saves both files, allowing you to rename them, if you choose.
To just inspect the GUI in GUIDE and run it, follow these steps instead:
Click here to add the example files to the MATLAB path (only for the current session).
Click here to display the GUI in the GUIDE Layout Editor (read only).
Click here to display the GUI M-file in the MATLAB Editor (read only).
Note Do not save GUI files to the examples folder where you found them or you will overwrite the original files. If you want to save GUI files, use File > Save as from GUIDE, which saves both the GUI FIG-file and the GUI M-file. |
The GUI contains:
Three uipanels
An axes
Two push buttons
Two sliders
Two check boxes
Static text
The Property Inspector was used to customize the uicontrols and text by:
Setting the figure Color to black, as well as the BackgroundColor, ForegroundColor, and ShadowColor of the three uipanels. (They are used as containers only, so they do not need to be visible.)
Coloring all static text yellow and uicontrol backgrounds either black or yellow-gray.
Giving all uicontrols mnemonic names in their Tag string.
Setting the FontSize for uicontrols to 9 points.
Specifying nondefault Min and Max values for the sliders.
Adding tooltip strings for some controls.
In the GUIDE Layout Editor, the GUI looks like this.

The GUI includes three uipanels that you can barely see in this figure because they are entirely black. Using uipanels helps the graphic functions work more efficiently.
The axes CreateFcn (axes1_CreateFcn) initializes the graphic objects. It executes just once no matter how many times the GUI is opened.
The Spin button's callback (spinstopbutton_Callback), which contains a while loop for rotating the spherical surface, conducts the animation.
The two sliders allow the user to change light direction during animation and function independently, but they query one another's value because both parameters are needed to specify a view.
The Show grid check box toggles the Visible property of the graticule surface object. The axes1_CreateFcn initializes the graticule and then hides it until the user selects this option.
The Spin button's callback reads the Make movie check box value to accumulate movie frames and saves the movie to a MAT-file when rotation is stopped or after one full revolution, whichever comes first. (The user must select Make movie before spinning the globe.)
The following sections describe the interactive techniques used in the GUI.
GUIDE generates the following create functions and callbacks in the globegui GUI. Most of these functions are customized for this application. If you are reading this page in the MATLAB Help Browser, click any function name to scroll to it in the Editor.
| Function | Function Behavior |
|---|---|
| globegui | Initializes the GUI's framework (not customized) |
| globegui_OpeningFcn | Initializes the GUI's handles structure (not customized) |
| globegui_OutputFcn | Specifies what is written to the Command Window (not customized) |
| spinstopbutton_Callback | Executes and halts animation, creates movie file |
| quitbutton_Callback | Exits the GUI by closing the figure |
| spinstopbutton_CreateFcn | Assigns button label strings and saves to handles structure |
| axes1_CreateFcn | Initializes axes and colormap, creates surface and light objects, displays globe |
| sunazslider_Callback | Changes azimuth of light source as user moves slider |
| sunazslider_CreateFcn | Initializes light source azimuth slider (not customized) |
| sunelslider_Callback | Changes elevation of light source as user moves slider |
| sunelslider_CreateFcn | Initializes light source elevation slider (not customized) |
| showgridbutton_Callback | Toggles the graticule grid visibility |
| movie_checkbox_Callback | Toggles capturing and saving a movie of the animation |
| movie_checkbox_CreateFcn | Initializes the movie button and saves its value |
The top right button, initially labeled Spin, changes to Stop when clicked, and back to Spinclicked a second time. It does this by comparing its String property to a pair of strings stored in the handles structure as a cell array. Insert this data into the handles structure in spinstopbutton_CreateFcn, as follows:
function spinstopbutton_CreateFcn(hObject, eventdata, handles)
handles.Strings = {'Spin';'Stop'};
guidata(hObject, handles); The call to guidata saves the updated handles structure for the figure containing hObject, which is the spinstopbutton push button object. GUIDE named this object pushbutton1. It was renamed by changing its Tag property in the Property Inspector. As a result, GUIDE changed all references to the component in the GUI's M-file when the GUI was saved. For more information on setting tags, see Identifying the Axes in the previous example.
The handles.Strings data is used in the spinstopbutton_Callback function, which includes the following code for changing the label of the button:
str = get(hObject,'String');
state = find(strcmp(str,handles.Strings));
set(hObject,'String',handles.Strings{3-state}); The find function returns the index of the string that matches the button's current label. The call to set switches the label to the alternative string. If state is 1, 3-state sets it to 2. If state is 2, it sets it to 1.
If the user clicks the Spin/Stop button when its label is Stop, its callback is looping through code that updates the display by advancing the rotation of the surface objects. The spinstopbutton_Callback contains code that listens to such events, but it does not use the events structure to accomplish this. Instead, it uses this piece of code to exit the display loop:
if find(strcmp(get(hObject,'String'),handles.Strings)) == 1
handles.azimuth = az;
guidata(hObject,handles);
break
end
Entering this block of code while spinning the view exits the while loop to stop the animation. First, however, it saves the current azimuth of rotation for initializing the next spin. (The handles structure can store any variable, not just handles.) If the user clicks the (now) Spin button, the animation resumes at the place where it halted, using the cached azimuth value.
When the user clicks Quit, the GUI destroys the figure, exiting immediately. To avoid errors due to quitting while the animation is running, the while loop must know whether the axes object still exists:
while ishandle(handles.axes1)
% plotting code
...
endYou can write the spinstopbutton_Callback function without a while loop, which avoids you having to test that the figure still exists. You can, for example, create a timer object that handles updating the graphics. This example does not explore the technique, but you can find information about programming timers in Using a MATLAB Timer Object in the MATLAB Programming Fundamentals documentation.
Selecting the Make movie check box before clicking Spin causes the application to record each frame displayed in the while loop of the spinstopbutton_Callback routine. When the user selects this check box, the animation runs more slowly because the following block of code executes:
filming = handles.movie;
...
if ishandle(handles.axes1) && filming > 0 && filming < 361
globeframes(filming) = getframe; % Capture axes in movie
filming = filming + 1;
endBecause it is the value of a check box, handles.movie is either 0 or 1. When it is 1, a copy (filming) of it keeps a count of the number of frames saved in the globeframes matrix (which contains the axes CData and colormap for each frame). Users cannot toggle saving the movie on or off while the globe is spinning, because the while loop code does not monitor the state of the Make movie check box.
The ishandle test prevents the getframe from generating an error if the axes is destroyed before the while loop finishes.
When the while loop is terminated by the user, the callback prints the results of capturing movie frames to the Command Window and writes the movie to a MAT-file:
if (filming)
filename = sprintf('globe%i.mat',filming-1);
disp(['Writing movie to file ' filename]);
save (filename, 'globeframes')
end Note Before creating a movie file with the GUI, make sure that you have write permission for the current folder. |
The file name of the movie ends with the number of frames it contains. Supposing the movie's file name is globe360.mat, you play it with:
load globe360 axis equal off movie(globeframes)
The playback looks like this.

To see the spinstopbutton_Callback code in globegui.m in the MATLAB Editor, click here.
To learn more about how this GUI uses Handle Graphics to create and view 3-D objects, read the following sections:
The axes1_CreateFcn function initializes the axes, the two objects displayed in it, and two hgtransform objects that affect the rotation of the globe:
The globe, a surfaceplot object, generated by a call to surface.
The geographic graticule (lines of latitude and longitude), also a surfaceplot object, generated by a call to mesh.
Data for these two objects are rectangular x-y-z grids generated by the sphere function. The globe's grid is 50-by-50 and the graticule grid is 8-by-15. (Every other row of the 15-by-15 grid returned by sphere is removed to equalize its North-South and East-West spans when viewed on the globe.)
The axes x-, y-, and z-limits are set to [-1.02 1.02]. Because the graphic objects are unit spheres, this leaves a little space around them while constraining all three axes to remain the same relative and absolute size. The graticule grid is also enlarged by 2%, which is barely enough to prevent the opaque texture-mapped surface of the globe from obscuring the graticule. If you watch carefully, you can sometimes see missing pieces of graticule edges as the globe spins.
Tip uipanels enclose the axes and the uicontrols. This makes the axes a child of the uipanel that contains it. Containing axes in uipanels speeds up graphic rendering by localizing the portion of the figure where MATLAB graphics functions redraw graphics. |
Code in the axes1_CreateFcn sets the CData for the globe to the 180-by-360 (one degree) topo terrain grid by setting its FaceColor property to 'texturemap'. You can use any image or grid to texture a surface. Specify surface properties as a struct containing one element per property that you must set, as follows:
props.FaceColor= 'texture'; props.EdgeColor = 'none'; props.FaceLighting = 'gouraud'; props.Cdata = topo; props.Parent = hgrotate; hsurf = surface(x,y,z,props); colormap(cmap)
Tip You can create MATLAB structs that contain values for sets of parameters and provide them to functions instead of parameter-value pairs, and save the structs to MAT-files for later use. |
The surface function plots the surface into the axes. Setting the Parent of the surface to hgrotate puts the surface object under the control of the hgtransform that spins the globe (see the illustration in Orienting the Globe and Graticule). By setting EdgeColor to 'none', the globe displays face colors only, with no grid lines (which, by default, display in black). The colormap function sets the colormap for the surface to the 64-by-3 colormap cmap defined in the code, which is appropriate for terrain display. While you can use more colors, 64 is sufficient, given the relative coarseness of the texture map (1-by-1 degree resolution).
Unlike the globe grid, the graticule grid displays with no face colors and gray edge color. (You turn the graticule grid on and off by clicking the Show grid button.) Like the terrain map, it is a surfaceplot object; however, the mesh function creates it, rather than the surface function, as follows:
hmesh = mesh(gx,gy,gz,'parent',hgrotate,...
'FaceColor','none','EdgeColor',[.5 .5 .5]);
set(hmesh,'Visible','off')The state of the Show grid button is initially off, causing the graticule not to display. Show grid toggles the mesh object's Visible property.
As mentioned earlier, enlarging the graticule by 2 percent before plotting prevents the terrain surface from obscuring it.
The globe and graticule rotate as if they were one object, under the control of a pair of hgtransform objects. Within the figure, the HG objects are set up in this hierarchy.

The tilt transform applies a rotation about the x-axis of 0.5091 radians (equal to 23.44 degrees, the inclination of the Earth's axis of rotation). The rotate transform initially has a default identity matrix. The spinstopbutton_Callback subsequently updates the matrix to rotate about the z-axis by 0.01745329252 radians (1 degree) per iteration, using the following code:
az = az + 0.01745329252;
set(hgrotate,'Matrix',makehgtform('zrotate',az));
drawnow % Refresh the screen
A light object illuminates the globe, initially from the left. Two sliders control the light's position, which you can manipulate whether the globe is standing still or rotating. The light is a child of the axes, so is not affected by either of the hgtransforms. The call to light uses no parameters other than its altitude and an azimuth:
hlight = camlight(0,0);
After creating the light, the axes1_CreateFcn adds some handles and data that other callbacks need to the handles structure:
handles.light = hlight; handles.tform = hgrotate; handles.hmesh = hmesh; handles.azimuth = 0.; handles.cmap = cmap; guidata(gcf,handles);
The call to guidata caches the data added to handles.
Moving either of the sliders sets both the elevation and the azimuth of the light source, although each slider changes only one. The code in the callback for varying the elevation of the light is
function sunelslider_Callback(hObject, eventdata, handles) hlight = handles.light; % Get handle to light object sunaz = get(handles.sunazslider,'value'); % Get current light azimuth sunel = get(hObject,'value'); % Varies from -72.8 -> 72.8 deg lightangle(hlight,sunaz,sunel) % Set the new light angle
The callback for the light azimuth slider works similarly, querying the elevation slider's setting to keep that value from being changed in the call to lightangle.
You can enhance the presentation of globegui in various ways, including:
Adding a colorbar to show how colors correspond to terrain elevation above and below sea level
You cannot use GUIDE to set up a colorbar, but you can do so in axes1_CreateFcn. For more information about using colorbars, see the reference page for colorbar and Adding a Colorbar to a Graph in the MATLAB Graphics documentation.
Displaying a readout of longitude of the closest point on the globe to the observer.
Use an edit or text style uicontrol that the function can update inside its while loop with the current azimuth (after expressing its value as degrees East or West of the Prime Meridian). Store this value in handles.azimuth. If you do this with an edit box that has an appropriate callback to update the rotate hgtransform, the user can update the globe's longitude interactively.
Giving the graticule smooth, curving edges rather than straight edges.
The sphere function returns a graticule grid that is, by design, very coarse and does not have values in between grid lines that are needed to generate smooth grid lines. To overcome this, you can generate your own lines of latitude and longitude separately as vectors of x, y, and z coordinates, scaling their values to be slightly larger than a unit sphere.
Modeling reflectance of light from the globe's surface.
You can make the globe look shiny or dull with the material function. For more information, see Reflectance Characteristics of Graphics Objects in the MATLAB 3-D Visualization documentation.
Adding 3-D topographic relief to the globe
This involves scaling the topo grid to a fraction of unity and assigning the ZData in the globe surface object to it, as well as using topo as its CData. Use the surfl function to plot output from sphere.
Tip Uuse a spherical grid that is the same size as topo to add terrain relief to the globe. Then scale the values of topo to well under 1.0 and factor them into the x, y, and z matrices. |
The result might look something like this figure, in which terrain relief is scaled to add 10% to the globe's radius, greatly exaggerating terrain relief.

![]() | GUI with Multiple Axes | GUI to Interactively Explore Data in a Table | ![]() |

Includes the most popular MATLAB recorded presentations with Q&A sessions led by MATLAB experts.
| © 1984-2009- The MathWorks, Inc. - Site Help - Patents - Trademarks - Privacy Policy - Preventing Piracy - RSS |