保存和加载图类的实例
从 ChartContainer
基类继承的图遵循与其他 MATLAB® 对象相同的保存和加载规则。但是,在某些情况下,您可能希望您的对象保存和加载其他信息。例如,为了支持保存和加载交互式更改(如旋转或缩放)的结果,必须将坐标区的修改视图存储在类的属性中。通过定义存储和检索这些类型的更改的属性和方法,用户可以保存和重新加载图的实例,同时保留其更改。
保存和加载坐标区更改的编码模式
内置坐标区交互会更改坐标区上的某些属性。例如,拖动以旋转三维图会更改 View
属性。同样,在图中滚动缩放会更改坐标区上的 XLim
、YLim
以及可能包含的 ZLim
属性。要在用户保存和重新加载图时保留更改,请将这些组件添加到您的类中:
定义用于存储图状态的受保护属性 - 该属性提供当 MATLAB 保存图对象时用来存储坐标区更改的位置。例如,您可以将该属性命名为
ChartState
。定义用于检索图状态的
get
方法 - 根据 MATLAB 是保存还是加载图对象,该方法执行以下两项操作之一。当 MATLAB 保存图对象时,该方法会返回相关坐标区更改,以便保存它们。当 MATLAB 加载图对象时,该方法返回存储在ChartState
属性中的坐标区更改。定义用于更新坐标区的受保护方法 - 当图对象加载到 MATLAB 中时,此方法对
ChartState
属性调用get
方法,然后更新图的相关坐标区属性。
定义用于存储图状态的受保护属性
定义一个受保护属性来存储相关坐标区信息。此属性为空,除非 MATLAB 在保存过程中设置其值,或 MATLAB 加载图的已保存实例。用易于识别的有意义名称定义属性。例如,定义一个名为 ChartState
的属性。
properties (Access = protected) ChartState = [] end
定义检索图状态的 get
方法
为 ChartState
属性定义公共 get
方法。像所有 set
和 get
方法一样,此方法自动继承 ChartState
属性的访问权限。MATLAB 在保存图实例时调用此方法。
在此方法中,创建一个名为 isLoadedStateAvailable
的变量,该变量存储一个 logical
值。当 ChartState
属性不为空时,该值为 true
。
接下来,编写一个条件语句来检查 isLoadedStateAvailable
的值。将语句分成下列子句:
if...then
子句 -isLoadedStateAvailable
值为true
。返回ChartState
属性的内容。else
子句 -isLoadedStateAvailable
值为false
。创建一个结构体并获取坐标区对象。仅当坐标区上的XLim
、YLim
和ZLim
属性发生变化时,才能将XLim
、YLim
和ZLim
字段添加到结构体中。要测试坐标区属性是否发生了更改,请检查对应的模式属性是否设置为'manual'
。由于没有与坐标区View
属性相关联的模式属性,因此无需检查任何内容即可将View
字段添加到结构体中。
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
定义更新坐标区的受保护方法
定义名为 loadstate
的受保护方法。在此方法中,执行以下步骤:
查询
ChartState
属性,并将返回值存储为data
。在更新坐标区上的对应属性之前,请检查是否存在
XLim
、YLim
、ZLim
和View
字段。清除
ChartState
属性的内容。
创建此方法后,在 setup
方法的末尾(创建构成图的图形对象后)调用它。当 MATLAB 创建图的新实例或加载图实例时,将执行 setup
方法。
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
示例:用于存储轴范围和视图的三维绘图
定义一个 MeshGradientChart
类,该类显示网格点处有 x 和 y 梯度向量的网格图。将此类设计为当用户保存和重新加载图实例时,坐标区的 XLim
、YLim
、ZLim
和 View
属性会被保留。
要定义此类,请在位于 MATLAB 路径上的文件夹中创建名为 MeshGradientChart.m
的程序文件。然后按照表中的步骤实现该类。
步骤 | 实现 |
---|---|
从 |
classdef MeshGradientChart < matlab.graphics.chartcontainer.ChartContainer |
定义公共属性。 |
properties
XData (:,:) double = []
YData (:,:) double = []
ZData (:,:) double = []
end |
定义私有属性。一个属性存储 |
properties (Access = private,Transient,NonCopyable)
SurfaceObject (1,1) matlab.graphics.chart.primitive.Surface
QuiverObject (1,1) matlab.graphics.chart.primitive.Quiver
end |
定义一个受保护 | properties (Access = protected)
ChartState = []
end |
实现 |
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 |
实现 |
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 |
实现 |
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 |
实现 |
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 |
接下来,创建图的一个实例。然后旋转或放大图并保存。当您将图加载回 MATLAB 时,该对象会保留交互式更改。
创建图的实例
[X,Y] = meshgrid(-5:5); Z = X.^2 + Y.^2; c = MeshGradientChart('XData',X,'YData',Y,'ZData',Z);
创建图时:
setup
方法会调用loadstate
方法。loadstate
方法会执行以下任务,这些任务最终对图对象或底层坐标区对象没有影响。调用
get.ChartState
方法,该方法返回包含坐标区View
属性当前值的结构体。将坐标区上的
View
属性重置为存储在结构体中的值。清除
ChartState
属性的内容。
旋转或放大图并保存。
savefig(gcf,'mychart.fig')
保存图时,MATLAB 调用 get.ChartState
方法,该方法返回包含以下内容的结构体:
坐标区上的
XLim
、YLim
或ZLim
属性的值(仅当这些值发生了更改时)坐标区上的
View
属性的值
在 MATLAB 检索结构体后,会将该结构体存储在要保存的图对象的 ChartState
属性中。
加载保存的图。
openfig('mychart.fig')
加载图时:
setup
方法会调用loadstate
方法。loadstate
方法执行以下任务:调用
get.ChartState
方法,该方法从ChartState
属性返回结构体。重置坐标区上的
XLim
、YLim
、ZLim
和View
属性(仅当结构体包含对应的字段时)。清除
ChartState
属性的内容。