Saving and Loading Instances of Chart Classes
Charts that inherit from the ChartContainer
base class follow the
same rules for saving and loading as other MATLAB® objects. However in some cases, you might want your objects to save and
load additional information. For example, to provide support for saving and loading the
result of interactive changes, such as rotating or zooming, you must store the modified
view of the axes in a property on your class. By defining properties and methods for
storing and retrieving these kinds of changes, you enable users to save and reload
instances of your chart with their changes preserved.
Coding Pattern for Saving and Loading Axes Changes
The built-in axes interactions change certain properties on the axes. For example,
dragging to rotate a 3-D chart changes the View
property.
Similarly, scrolling to zoom within a chart changes the XLim
,
YLim
, (and possibly ZLim
) properties
on the axes. To preserve the changes when the user saves and reloads the chart, add
these components to your class:
Define a protected property for storing the chart state — This property provides a place to store the axes changes when MATLAB saves the chart object. For example, you might name this property
ChartState
.Define a
get
method for retrieving the chart state — This method does either of two things depending on whether MATLAB is saving or loading the chart object. When MATLAB saves the chart object, the method returns the relevant axes changes so they can be saved. When MATLAB loads the chart object, the method returns the axes changes that are stored in theChartState
property.Define a protected method that updates the axes — When the chart object loads into MATLAB, this method calls the
get
method for theChartState
property and then updates the relevant axes properties for the chart.
Define a Protected Property for Storing the Chart State
Define a protected property to store the relevant axes information. This property
is empty except when MATLAB sets its value during the save process, or when MATLAB loads a saved instance of the chart. Define the property with a name
that is useful and easy to recognize. For example, define a property called
ChartState
.
properties (Access = protected) ChartState = [] end
Define a get
Method for Retrieving the Chart State
Define a public get
method for the
ChartState
property. Like all set
and
get
methods, this method automatically inherits the access
permissions of the ChartState
property. MATLAB calls this method when it saves an instance of the chart.
Within this method, create a variable called
isLoadedStateAvailable
that stores a
logical
value. This value is true
when the
ChartState
property is not empty.
Next, write a conditional statement that checks the value of
isLoadedStateAvailable
. Divide the statement into clauses:
if...then
clause — TheisLoadedStateAvailable
value istrue
. Return the contents of theChartState
property.else
clause — TheisLoadedStateAvailable
value isfalse
. Create a structure and get the axes object. Add theXLim
,YLim
, andZLim
fields to the structure only if theXLim
,YLim
, andZLim
properties on the axes changed. To test whether the axes properties changed, check to see if the corresponding mode properties are set to'manual'
. Since there is no mode property associated with the axesView
property, add theView
field to the structure without checking anything.
methods function data = get.ChartState(obj) isLoadedStateAvailable = ~isempty(obj.ChartState); if isLoadedStateAvailable data = obj.ChartState; else data = struct; ax = getAxes(obj); % Get axis limits only if mode is manual. if strcmp(ax.XLimMode,'manual') data.XLim = ax.XLim; end if strcmp(ax.YLimMode,'manual') data.YLim = ax.YLim; end if strcmp(ax.ZLimMode,'manual') data.ZLim = ax.ZLim; end % No ViewMode to check. Store the view anyway. data.View = ax.View; end end end
Define a Protected Method That Updates the Axes
Define a protected method called loadstate
. In this method,
perform these steps:
Query the
ChartState
property and store the returned value asdata
.Check for the existence of the
XLim
,YLim
,ZLim
, andView
fields before updating the corresponding properties on the axes.Clear the contents of the
ChartState
property.
After you create this method, call it near the end of the
setup
method (after creating the graphics objects that make
up your chart). The setup
method executes when MATLAB creates a new instance of the chart or when it loads an instance of a
chart.
function loadstate(obj) data=obj.ChartState; ax = getAxes(obj); % Look for states that changed if isfield(data, 'XLim') ax.XLim=data.XLim; end if isfield(data, 'YLim') ax.YLim=data.YLim; end if isfield(data, 'ZLim') ax.ZLim=data.ZLim; end if isfield(data, 'View') ax.View=data.View; end % Reset ChartState to empty obj.ChartState=[]; end
Example: 3-D Plot That Stores Axis Limits and View
Define a MeshGradientChart
class for displaying a mesh plot
with x and y gradient vectors at the grid
points. Design this class so that the XLim
,
YLim
, ZLim
, and
View
properties of the axes are preserved when the user
saves and reloads an instance of the chart.
To define this class, create a program file named
MeshGradientChart.m
in a folder that is on the MATLAB path. Then implement the class by following the steps in the
table.
Step | Implementation |
---|---|
Derive from the |
classdef MeshGradientChart < matlab.graphics.chartcontainer.ChartContainer |
Define the public properties. |
properties
XData (:,:) double = []
YData (:,:) double = []
ZData (:,:) double = []
end |
Define the private properties. One property stores a
|
properties (Access = private,Transient,NonCopyable)
SurfaceObject (1,1) matlab.graphics.chart.primitive.Surface
QuiverObject (1,1) matlab.graphics.chart.primitive.Quiver
end |
Define a protected |
properties (Access = protected)
ChartState = []
end |
Implement the |
methods(Access = protected) function setup(obj) ax = getAxes(obj); % Create Mesh and Quiver objects. obj.SurfaceObject=mesh(ax,[],[],[],'FaceColor','none'); hold(ax,'on') obj.QuiverObject=quiver3(ax,[],[],[],[],'Color','r','LineWidth',2); hold(ax,'off') % Load state of the axes. loadstate(obj); end |
Implement the |
function update(obj) % Update Mesh data. obj.SurfaceObject.XData = obj.XData; obj.SurfaceObject.YData = obj.YData; obj.SurfaceObject.ZData = obj.ZData; % Update locations of vector tails. obj.QuiverObject.XData = obj.XData; obj.QuiverObject.YData = obj.YData; obj.QuiverObject.ZData = obj.ZData; % Update lengths and directions of vectors. [gradx,grady] = gradient(obj.ZData); obj.QuiverObject.UData = gradx; obj.QuiverObject.VData = grady; obj.QuiverObject.WData = zeros(size(obj.ZData)); end |
Implement the |
function loadstate(obj) data=obj.ChartState; ax = getAxes(obj); % Look for states that changed. if isfield(data, 'XLim') ax.XLim=data.XLim; end if isfield(data, 'YLim') ax.YLim=data.YLim; end if isfield(data, 'ZLim') ax.ZLim=data.ZLim; end if isfield(data, 'View') ax.View=data.View; end % Reset ChartState to empty. obj.ChartState=[]; end end |
Implement the |
methods function data = get.ChartState(obj) isLoadedStateAvailable = ~isempty(obj.ChartState); % Return ChartState content if loaded state is available. % Otherwise, return current axes state. if isLoadedStateAvailable data = obj.ChartState; else data = struct; ax = getAxes(obj); % Get axis limits only if mode is manual. if strcmp(ax.XLimMode,'manual') data.XLim = ax.XLim; end if strcmp(ax.YLimMode,'manual') data.YLim = ax.YLim; end if strcmp(ax.ZLimMode,'manual') data.ZLim = ax.ZLim; end % No ViewMode to check. Store the view anyway. data.View = ax.View; end end end end |
Next, create an instance of the chart. Then rotate or zoom into the chart and save it. The object preserves the interactive changes when you load the chart back into MATLAB.
Create an instance of the chart
[X,Y] = meshgrid(-5:5); Z = X.^2 + Y.^2; c = MeshGradientChart('XData',X,'YData',Y,'ZData',Z);
When you create the chart:
The
setup
method calls theloadstate
method.The
loadstate
method performs these tasks, which ultimately have no effect on the chart object or the underlying axes object.Call the
get.ChartState
method, which returns a structure containing the current value of the axesView
property.Reset the
View
property on the axes to the value stored in the structure.Clear the contents of the
ChartState
property.
Rotate or zoom into the chart and save it
savefig(gcf,'mychart.fig')
When you save the chart, MATLAB calls the get.ChartState
method, which returns
a structure containing:
The values of the
XLim
,YLim
, orZLim
properties on the axes, but only if they changedThe value of the
View
property on the axes
After MATLAB retrieves the structure, it stores the structure in the
ChartState
property of the chart object that is being
saved.
Load the chart that you saved
openfig('mychart.fig')
When you load the chart:
The
setup
method calls theloadstate
method.The
loadstate
method performs these tasks:Call the
get.ChartState
method, which returns the structure from theChartState
property.Reset the
XLim
,YLim
,ZLim
, andView
properties on the axes, but only if the structure contains the corresponding fields.Clear the contents of the
ChartState
property.