メインコンテンツ

グラフィックス プロパティを取得および設定するコードの最適化

自動計算されるプロパティ

MATLAB® では、一部のプロパティの値が他のプロパティの値に基づいて自動的に計算されます。たとえば、軸の範囲により、軸の目盛りに使用される値が変わります。さらに、この値により、軸の目盛りラベルが変わります。

プロパティの計算時はモード プロパティも影響することがあります。モード プロパティはオブジェクトの特定のプロパティとペアになっていて、名前の最後に "Mode" という語が付いています。たとえば、axes オブジェクトには XTick プロパティと XTickMode プロパティがあります。XTickMode プロパティの値が "auto" の場合、条件 (x 軸の範囲など) が変わると MATLAB によって XTick プロパティが更新されます。XTickMode プロパティの値が "manual" の場合は、他のプロパティの値に関係なく XTick プロパティが保持されます。

MATLAB では、特定のプロパティの値を他のオブジェクトに基づいて計算することもできます。たとえば、プロット関数は、プロットされるデータと Figure のサイズに適した軸の範囲、目盛りラベル、サイズを使用して、座標軸を自動的に作成します。

計算されたプロパティをクエリすると、MATLAB では drawnow が暗黙的に実行され、すべてのプロパティ値を最新状態にしてから、計算されたプロパティ値を返します。このクエリにより、依存するすべてのプロパティの完全更新と、画面の更新が行われます。

MATLAB は、計算されたプロパティの値を返す前に、その値が確実に最新状態となるよう、必要に応じてすべての更新を行います。

次の表に、よく計算されるプロパティの一部を示します。

オブジェクトプロパティこれらのプロパティの MATLAB による計算

axes

CameraPosition, CameraTarget, CameraUpVector, CameraViewAngle

対応するモード プロパティが "auto" に設定されている場合

 

Position, InnerPosition,

PositionConstraint プロパティが "outerposition" に設定されている場合

 OuterPosition

PositionConstraint プロパティが "innerposition" に設定されている場合

 TightInset

常時

 

XLim, YLim, ZLim

対応するモード プロパティが "auto" に設定されている場合

 

XTick, YTick, ZTick, XMinorTick, YMinorTick, ZMinorTick

対応するモード プロパティが "auto" に設定されている場合

 

XTickLabel, YTickLabel, ZTickLabel, TickDir

対応するモード プロパティが "auto" に設定されている場合

 

SortMethod

対応するモード プロパティが "auto" に設定されている場合

text

Extent

常時

 

Position

text オブジェクトが座標軸のタイトル、サブタイトル、軸ラベル、または副ラベルとして使用され、PositionMode プロパティが "auto" に設定されている場合

 

FontSize, FontWeight

text オブジェクトが座標軸のタイトル、サブタイトル、軸ラベル、または副ラベルとして使用され、対応するモード プロパティが "auto" に設定されている場合

set と get の非効率なサイクル

プロパティ値を設定するときには、グラフィックス モデルの状態を変更し、要更新としてマークします。計算されたプロパティをクエリする場合、グラフィックス モデルとグラフィックス ハードウェアが同期していないときには、MATLAB による更新の実行が必要です。

同じループ内でプロパティを取得および設定する場合、1 回ループするたびに更新を実行していることがあります。

  • get は更新を引き起こします。

  • set はグラフィックス モデルを要更新としてマークします。

1 回ループするたびにこのサイクルが繰り返されます。このようにするよりも、以下の例に示すように、1 回のループですべてのプロパティのクエリを実行してから、別のループですべてのプロパティの設定を行った方が効率的です。

この例では、text オブジェクトの Position プロパティと Extent プロパティの両方を取得してから、Position プロパティを設定しています。

パフォーマンスが悪いコードパフォーマンスが良いコード
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 プロパティは画面の解像度、Figure のサイズ、軸の範囲など他の値に依存しているため、このプロパティをクエリすると、すべての更新が起こる可能性がある。

  • Position プロパティを設定するごとに、次回の Extent プロパティの取得ですべての更新が必要となる。

このコードのパフォーマンスが良い理由は、以下のとおりです。

  • 1 つのループですべてのプロパティ値をクエリし、それらの値を配列に格納している。

  • 別のループですべてのプロパティ値を設定している。

  • 2 番目のループが終了した後で drawnow を呼び出している。

テキストの Extent を使用したラベルの回転

座標軸のラベルを回転させるためにテキストの Extent プロパティをクエリする場合、座標軸のプロパティ XTickLabelRotationYTickLabelRotationZTickLabelRotation を使用した方が効率的です。