Main Content

优化代码以获取和设置图形属性

自动计算属性

某些属性依赖于其他属性的值。MATLAB® 会根据当前图形模型自动计算这些属性值并更新值。例如,坐标轴范围影响用于轴刻度的值,轴刻度值会影响轴刻度标签。

当您查询计算属性时,MATLAB 会执行隐式 drawnow 以确保返回属性值之前所有属性值都是最新的。查询会引起所有从属属性的更新和屏幕的更新。

MATLAB 计算某些属性值时需要根据该属性所依赖的值。例如,绘图函数会自动创建具有坐标轴范围、刻度标签及尺寸适合绘制数据及图窗尺寸的坐标区。

MATLAB 图形执行完全更新,如果需要,再从计算属性返回值以确保返回值是最新的。

下表列出了一些更常见的计算属性。

对象属性MATLAB 何时计算这些属性

坐标区

CameraPosition, CameraTarget, CameraUpVector, CameraViewAngle

始终

 

Position, OuterPosition, TightInset

始终

 

XLim, YLim, ZLim

始终

 

XTick, YTick, ZTick, XMinorTick, YMinorTick, ZMinorTick

始终

 

XTickLabel, YTickLabel, ZTickLabel, TickDir

始终

 

SortMethod

始终

文本

Extent

始终

 

Position

仅当文本对象用作坐标区标题或轴标签时

 

FontSize, FontWeight

仅当文本对象用作坐标区标题或轴标签时

效率不高的设置和获取周期

当您设置属性值时,会更改图形模型的状态,并将其标记为需要更新。当您查询自动计算属性时,如果图形模型和图形硬件未同步,MATLAB 需要执行更新。

当您在同一个循环中获取和设置属性时,会造成每次遍历循环都要执行更新的情况。

  • get 会引起更新。

  • set 将图形模型标记为需要更新。

每次遍历循环都会重复这个周期。最好在一个循环中执行所有属性查询,在另一个循环中执行所有属性设置,如以下示例。

此示例获取和设置文本 Extent 属性。

性能不佳的代码性能更高的代码
h = gobjects(1,500);
p = zeros(500,3);
for ix = 1:500
   h(ix) = text(ix/500,ix/500,num2str(ix));
end
drawnow

% Gets and sets in the same loop,
% prompting a full update at each pass
for ix = 1:500
   pos = get(h(ix),'Position');
   ext = get(h(ix),'Extent');
   p(ix,:) = [pos(1)+(ext(3)+ext(1)), ...
              pos(2)+ext(2)+ext(4),0];
   set(h(ix),'Position',p(ix,:))
end
drawnow
h = gobjects(1,500);
p = zeros(500,3);
for ix = 1:500
   h(ix) = text(ix/500,ix/500,num2str(ix));
end
drawnow

% Get and save property values
for ix=1:500
   pos = get(h(ix),'Position');
   ext = get(h(ix),'Extent');
   p(ix,:) = [pos(1)+(ext(3)+ext(1)), ...
              pos(2)+ext(2)+ext(4),0];
end

% Set the property values and 
% call a drawnow after the loop
for ix=1:500
   set(h(ix),'Position',p(ix,:));
end
drawnow

这段代码性能不佳是因为:

  • Extent 属性依赖于其他值,如屏幕分辨率、图窗尺寸和坐标轴范围,因此查询此属性会引起全部更新。

  • 当下一次获取 Extent 属性发生时,就需要设置 Position 属性。

这样的性能更佳,因为此代码:

  • 在一个循环中查询所有属性值并将这些值存储到一个数组中。

  • 在单独的循环中设置所有属性值。

  • 第二个循环完成后调用 drawnow

更改文本 Extent 以旋转标签

如果您更改文本 Extent 属性以旋转标签,那么使用坐标区属性 XTickLabelRotationYTickLabelRotationZTickLabelRotation 更高效。