Main Content

グラフィックス パフォーマンスの向上

MATLAB® グラフィックス関数を使用してデータの可視化を作成する場合、コードで特定の手法を使用してパフォーマンスを向上させることができます。このトピックでは、長時間かかるアニメーションの高速化、プロット データの迅速な更新、およびユーザー入力にスムーズに応答する可視化の作成などの手法について説明します。作成するグラフィックスのタイプに有効な手法を使用してください。

グラフィックスの更新速度の向上

既存のプロットまたは他のグラフィックス オブジェクトを更新する場合、すべてのデータを最初から再作成するのではなく、変更するデータのみ更新することで、コードのパフォーマンスを向上させることができます。

たとえば、次のコードは、表面プロットと単一のマーカーの両方を含む axes オブジェクトを更新します。更新の各段階で、マーカーのみ位置が変化します。表面プロットに関連付けられたすべてのデータ、およびマーカー プロパティの多くは、各ステップで変化しません。関数 surfplot3 を複数回呼び出してすべてのデータを更新するのではなく、マーカー オブジェクトの位置を制御するプロパティのみを更新します。

[sx,sy,sz] = peaks(500);
nframes = 490;

surf(sx,sy,sz,"EdgeColor","none")
hold on
m = plot3(sx(1,1),sy(1,1),sz(1,1),"o", ...
    "MarkerFaceColor","red", ...
    "MarkerSize",14);
hold off

for t = 1:nframes
    m.XData = sx(t+10,t);
    m.YData = sy(t,t+10);
    m.ZData = sz(t+10,t+10)+0.5;
    drawnow
end

イメージの読み込み速度の向上

R2022b 以降

イメージを処理する場合、MaxRenderedResolution プロパティを設定すれば、MATLAB でイメージの大きい次元を表示するときに使用する最大解像度を制御できます。小さい次元は、縦横比を保持するように調整されます。指定する値は画面上の表示に影響しますが、イメージの CData プロパティに格納されているイメージ データには影響しません。

イメージをフル解像度で表示するには、"none" を指定します。表示されるイメージのサイズを制限するには、数値を指定します。より大きい数値 (および "none") を指定すると画質は向上しますが、初期イメージのレンダリングに時間がかかる可能性があります。より小さい数値を指定するとイメージがダウンサンプリングされますが、より高速にレンダリングされます。

通常、元のイメージの最大イメージ次元より小さい値を指定すると、イメージのレンダリングが高速になります。ただし、1 ピクセルまたは数ピクセルのみ小さい値を指定すると、そのイメージの初期のレンダリングは、フル解像度でレンダリングされるよりも時間がかかる場合があります。

たとえば、384×512 の RGB イメージ peppers.png を読み取ります。次に、関数 imagesc を呼び出して、大きい次元で 128 ピクセルを使用してイメージを表示します。小さい次元では 96 ピクセルにスケール ダウンして、元の縦横比を維持します。

imdata = imread("peppers.png");
imagesc(imdata,"MaxRenderedResolution",128)

peppers.png displayed at a resolution of 96-by-128 pixels

コード内のボトルネックの特定

プロファイラーを使用して、最も多くの時間を消費している関数を特定します。これにより、それらの関数のパフォーマンス改善の可能性を評価できます。

たとえば、関数 myPlot を使用して 10 行 500 列の配列要素の散布図を作成します。

function myPlot
x = rand(10,500);
y = rand(10,500);
scatter(x,y,"blue");
end

プロファイラーを使用して関数 myPlot の実行時間を測定します。コードの実行には約 2.7 秒かかっています。

profile on
myPlot
profile viewer

Flame graph in the profile summary. The myPlot function accounts for 99.9% of the code execution time and takes 2.736 seconds to run.

x 配列と y 配列には 500 列のデータが含まれているため、関数 scatter は 500 個の Scatter オブジェクトを作成します。この場合、代替方法として、5,000 個のデータ点をもつ 1 つのオブジェクトを作成して同じデータをプロットできます。

function myPlot
   x = rand(10,500);
   y = rand(10,500);
   scatter(x(:),y(:),"blue");
end

このように更新されたコードをプロファイルします。関数の実行時間は 0.3 秒未満になりました。

profile on
myPlot
profile viewer

Flame graph in the profile summary. The myPlot function accounts for 98.5% of the code execution time and takes 0.262 second to run.

プロファイラーの使用に関する詳細については、パフォーマンス向上のためのコードのプロファイリングを参照してください。

長時間かかるアニメーションのパフォーマンスの向上

長時間かかるアニメーションのパフォーマンスを向上させるには、画面に更新を表示するために drawnow ではなく drawnow limitrate を使用することを検討してください。どちらのコマンドも Figure の表示を更新しますが、drawnow limitrate は更新の回数を 1 秒あたり 20 フレームに制限します。その結果、アニメーションの表示が高速化される可能性があります。

たとえば次のような状況では、drawnow limitrate を使用するとアニメーションのパフォーマンスが向上します。

  • リアルタイム シミュレーション データのプロットなど、最新のフレームを表示することが重要なアニメーション

  • 1 秒あたりのフレーム数が多く、かつ、すべてのフレームを表示する必要がないアニメーション

たとえば、次のコードでは、アニメーション化されたラインを作成し、50,000 個のデータ点をループ内のラインに追加します。ループで drawnow limitrate を使用すると、表示の更新回数が制限され、その結果、アニメーションは、1 回ループするたびに更新を実行するよりも高速になります。

h = animatedline;
axis([0 4*pi -1 1])
x = linspace(0,4*pi,50000);
 
for k = 1:length(x)
    y = sin(x(k));
    addpoints(h,x(k),y);
    drawnow limitrate
end

スムーズで応答性に優れた座標軸の操作

axes オブジェクトにデータを表示する場合は、ドラッグしてパン、スクロールしてズームなど、データの操作を構成できます。通常は、MATLAB で提供されている組み込み操作を使用し、構成します。組み込みの座標軸操作はユーザー入力にスムーズに応答するように最適化されており、WindowScrollWheelFcn などのカスタム対話機能コールバックを実装する場合よりも応答性に優れたエクスペリエンスを実現できます。

組み込み操作は座標軸の内容によって異なりますが、通常は、スクロールしてズーム、ドラッグしてパンまたは回転、ポイントまたはクリックしてデータ ヒントを表示、などがあります。これらの操作を有効にするには、関数 enableDefaultInteractivity を呼び出します。また、axes オブジェクトの Interactions プロパティを設定することで、特定のチャートの組み込み操作をカスタマイズできます。組み込み操作の有効化とカスタマイズの詳細については、チャートの対話機能の制御を参照してください。

コードにおいて座標軸の操作の有効化よりも起動時間の高速化の方が重要である場合、代わりに組み込みの座標軸操作を無効にすることを検討してください。無効にすることで、axes オブジェクトはより高速に表示されます。組み込み操作を無効にするには、関数 disableDefaultInteractivity を呼び出します。

関連するトピック