Octave「surf」で表現力アップ!3Dグラフ作成のプロ技公開
2025-04-26
基本的な使い方
「surf」関数は、通常、3つの行列またはベクトルを引数として受け取ります。
- Z
z座標(高さ)の行列。これは、xとyの各点におけるzの値を表します。 - Y
y座標の行列またはベクトル - X
x座標の行列またはベクトル
基本的な構文は次のとおりです。
surf(X, Y, Z);
詳細説明
-
- まず、描画したい表面のx、y、z座標のデータを準備します。通常、xとyはメッシュグリッドとして生成され、zはxとyの関数として計算されます。
- 例えば、次のコードは、xとyのメッシュグリッドを生成し、zを計算します。
[X, Y] = meshgrid(-2:0.2:2, -2:0.2:2); Z = X .* exp(-X.^2 - Y.^2);
-
「surf」関数の実行
- 次に、「surf」関数にX、Y、Zを引数として渡します。これにより、3次元の表面グラフが描画されます。
surf(X, Y, Z);
-
グラフのカスタマイズ
- 「surf」関数には、さまざまなオプションがあり、グラフの外観をカスタマイズできます。
- 例えば、カラーマップ、線のスタイル、照明などを変更できます。
colormap()
関数を使用し色を変更できます。shading interp
を使用することで、色を滑らかに補完することも可能です。
例
[X, Y] = meshgrid(-2:0.2:2, -2:0.2:2);
Z = X .* exp(-X.^2 - Y.^2);
surf(X, Y, Z);
title("3次元表面グラフ");
xlabel("X軸");
ylabel("Y軸");
zlabel("Z軸");
colormap("jet");#color mapの変更
shading interp; #shading の変更
この例では、ガウス関数のような3次元表面グラフを描画し、タイトル、軸ラベル、カラーマップを追加しています。
-
行列の次元の不一致
- エラー
error: surf: X, Y, and Z must be matrices of the same size
- 原因
X
,Y
,Z
の行列の次元が一致していない場合に発生します。 - 解決策
meshgrid
関数を使用してX
とY
を生成し、Z
をX
とY
の関数として計算することで、次元を一致させます。size(X)
,size(Y)
,size(Z)
を使用して行列の次元を確認し、必要に応じて修正します。
- エラー
-
Z が行列でない場合
- エラー
error: surf: Z must be a matrix
- 原因
Z
がベクトルまたはスカラーなど、行列でない場合に発生します。 - 解決策
Z
が行列であることを確認し、必要に応じてreshape
関数などを使用して行列に変換します。
- エラー
-
データ範囲のエラー
- 問題
グラフが期待どおりに表示されない、またはデータが極端に大きすぎる/小さすぎる。 - 原因
X
,Y
,Z
のデータ範囲が適切でない場合に発生します。 - 解決策
- データの範囲を確認し、必要に応じて調整します。
axis
関数を使用して軸の範囲を明示的に設定します。log10
などを使用して、データのスケールを調整します。
- 問題
-
カラーマップの問題
- 問題
グラフの色が期待どおりに表示されない。 - 原因
カラーマップの設定が適切でない場合に発生します。 - 解決策
colormap
関数を使用して、適切なカラーマップを選択します。colorbar
関数を使用して、カラーバーを表示し、色の範囲を確認します。caxis
関数を使用して、カラーマップの範囲を調整します。
- 問題
-
照明とシェーディングの問題
- 問題
グラフの照明やシェーディングが期待どおりに表示されない。 - 原因
照明やシェーディングの設定が適切でない場合に発生します。 - 解決策
shading
関数を使用して、適切なシェーディングモード(flat
,interp
など)を選択します。light
関数を使用して、光源を追加または調整します。material
関数を使用して、表面の材質特性を調整します。
- 問題
-
グラフの表示の問題
- 問題
グラフがウィンドウに表示されない、または表示が遅い。 - 原因
グラフィックドライバの問題、またはデータ量が大きすぎる場合に発生します。 - 解決策
- Octave を再起動します。
- グラフィックドライバを更新します。
drawnow
関数を使用して、グラフを強制的に更新します。- データ量を減らすか、表示するデータの間隔を大きくします。
- 問題
-
meshgridの理解不足
- 問題
XとYのグリッドが期待したものではない。 - 原因
meshgridの理解が足りない。 - 解決策
meshgridの挙動を理解する。- meshgridは2つのベクトルから2次元のグリッドを作る関数である。
- meshgrid(x,y)の場合、Xはxのベクトルを縦方向にコピーした行列、Yはyのベクトルを横方向にコピーした行列である。
- meshgrid(x)とした場合meshgrid(x,x)と同じ結果になる。
- 問題
% データの準備
[X, Y] = meshgrid(-2:0.2:2, -2:0.2:2); % xとyのメッシュグリッドを生成
Z = X .* exp(-X.^2 - Y.^2); % z座標を計算
% 表面グラフの描画
surf(X, Y, Z);
% グラフの装飾
title("基本的な3次元表面グラフ");
xlabel("X軸");
ylabel("Y軸");
zlabel("Z軸");
説明
title
,xlabel
,ylabel
,zlabel
: グラフのタイトルと軸ラベルを設定します。surf(X, Y, Z)
:X
,Y
,Z
のデータを使用して3次元表面グラフを描画します。Z = X .* exp(-X.^2 - Y.^2)
:x
とy
の関数としてz
座標を計算します。meshgrid(-2:0.2:2, -2:0.2:2)
:-2
から2
まで0.2
刻みのx
とy
のメッシュグリッドを生成します。
% データの準備
[X, Y] = meshgrid(-pi:0.1:pi, -pi:0.1:pi);
Z = sin(X) .* cos(Y);
% 表面グラフの描画とカスタマイズ
surf(X, Y, Z);
title("カラーマップとシェーディングの変更");
xlabel("X軸");
ylabel("Y軸");
zlabel("Z軸");
colormap("jet"); % カラーマップを"jet"に変更
shading interp; % シェーディングを補間モードに変更
colorbar; % カラーバーを表示
説明
colorbar
: カラーバーを表示し、色の範囲を示します。shading interp
: シェーディングを補間モードに変更し、表面を滑らかに表示します。colormap("jet")
: カラーマップを「jet」に変更します。他のカラーマップ(hot
,cool
,gray
など)も使用できます。
% データの準備
[X, Y] = meshgrid(-2:0.2:2, -2:0.2:2);
Z = X.^2 + Y.^2;
% 表面グラフの描画と照明の追加
surf(X, Y, Z);
title("照明の追加");
xlabel("X軸");
ylabel("Y軸");
zlabel("Z軸");
light; % デフォルトの光源を追加
lighting gouraud; % 照明モデルを"gouraud"に変更
説明
lighting gouraud
: 照明モデルを「gouraud」に変更し、滑らかな照明効果を実現します。他の照明モデル(flat
,phong
など)も使用できます。light
: デフォルトの光源を追加します。光源の位置や色をカスタマイズすることもできます。
% データの準備
[X, Y] = meshgrid(-2:0.2:2, -2:0.2:2);
Z = X.^2 - Y.^2;
% 表面グラフの描画と軸の範囲設定
surf(X, Y, Z);
title("軸の範囲の修正");
xlabel("X軸");
ylabel("Y軸");
zlabel("Z軸");
axis([-3 3 -3 3 -5 5]); % 軸の範囲を[-3 3 -3 3 -5 5]に設定
axis([-3 3 -3 3 -5 5])
: 軸の範囲を[xmin xmax ymin ymax zmin zmax]
に設定します。これにより、グラフの表示範囲を調整できます。
「mesh」関数
- 構文は「surf」とほぼ同じです。
- データの形状を把握するのに役立ちます。
- 「mesh」関数は、「surf」関数と似ていますが、表面を塗りつぶさずに、ワイヤーフレームとして描画します。
[X, Y] = meshgrid(-2:0.2:2, -2:0.2:2);
Z = X .* exp(-X.^2 - Y.^2);
mesh(X, Y, Z);
title("mesh関数によるワイヤーフレーム");
「plot3」関数
- しかし、複雑な表面を描画するには、多くの処理が必要になります。
- 表面を描画する場合、複数の「plot3」を組み合わせて、表面のワイヤーフレームのようなものを生成できます。
- 表面ではなく、3次元空間内の点の軌跡を表示するのに適しています。
- 「plot3」関数は、3次元の線グラフを描画します。
t = 0:0.1:10*pi;
x = sin(t);
y = cos(t);
z = t;
plot3(x, y, z);
title("plot3関数による3次元線グラフ");
「contour3」関数
- 表面の形状と高さの変化を視覚化するのに役立ちます。
- 表面の等高線を3次元空間に表示します。
- 「contour3」関数は、3次元の等高線グラフを描画します。
[X, Y] = meshgrid(-2:0.2:2, -2:0.2:2);
Z = X .* exp(-X.^2 - Y.^2);
contour3(X, Y, Z);
title("contour3関数による3次元等高線グラフ");
「imagesc」と「view」関数
- 完全な3次元表面グラフではありませんが、特定の視点からの表面の様子を表現できます。
- 「imagesc」で高さデータをカラーマップとして表示し、「view」で視点を調整します。
- 「imagesc」関数は、2次元のイメージデータを表示しますが、「view」関数と組み合わせることで、擬似的な3次元表面グラフを作成できます。
[X, Y] = meshgrid(-2:0.2:2, -2:0.2:2);
Z = X .* exp(-X.^2 - Y.^2);
imagesc(Z);
view(30, 45); % 視点を調整
title("imagescとview関数による擬似3次元グラフ");
- 点の密度や色で表面の形状を表現できますが、表面自体を描画するわけではありません。
- 表面ではなく、3次元空間内の点の分布を表示するのに適しています。
- 「scatter3」関数は、3次元の散布図を描画します。
x = randn(100, 1);
y = randn(100, 1);
z = randn(100, 1);
scatter3(x, y, z);
title("scatter3関数による3次元散布図");
- 「scatter3」は3次元散布図。
- 「imagesc」と「view」は擬似的な3次元表示。
- 「contour3」は3次元等高線グラフ。
- 「plot3」は3次元線グラフ。
- 「mesh」はワイヤーフレーム表示。