OpenNH

日常のひとこま(自分用のメモとかあれこれ)

MATLABのbar3でxy座標値を任意に変更する

はじめに

MATLABで3次元の棒グラフを使用したい機会があり、使用したのですがなかなか使いづらい関数でした…。
デフォルトのままではxyの座標値がなぜか設定できない。

例えば、このようなコードではxyの値がデータ数になってしまいます。

[X, Y] = meshgrid(10:20, -10:10);
Z = sqrt(X.^2+Y.^2);
figure;
bar3(Z);
xlabel('X');
ylabel('Y');
zlabel('Z');

↓↓こんな感じになってしまいます。
f:id:FounderLeis:20181119002140p:plain

”bar3()”に関する公式解説
jp.mathworks.com
 
このxy座標をデータ数ではなく数値にしたいのですが、ググってみてもなかなかいい方法がないようでした。

なので、bar3のxy座標値を任意に設定できる関数を作成してみました。

ソースコード

function [] = bar3XYtick(ax, X, Y, T)
%BAR3XYTICK bar3のX,Y座標の値を設定
%  BAR3XYTICK(B,X,Y)
%  Input
%  ax : Handle of figure's Axis 
%       変更したい図の座標軸
%  X  : X coordinate values (vector)
%       X座標値(ベクトル)
%  Y  : Y coordinate values (vector)
%       Y座標値(ベクトル)
%  T  : (tx, ty) Number of thin out
%       座標メモリ表示における間引く数 
%        tx : X座標の刻み
%        ty : Y座標の刻み
%
%  @ Fumihachi - 2018/11/19
%

minX = min(min(X));
minY = min(min(Y));
maxX = max(max(X));
maxY = max(max(Y));
if isvector(X)
    Nx   = length(X);
    Ny   = length(Y);
else
    Nx   = length(X(1,:));
    Ny   = length(Y(:,1));
end
dx = (maxX-minX)/(Nx-1);
dy = (maxY-minY)/(Ny-1);

set(ax, 'XTick', 1:T(1)/dx:Nx);
set(ax, 'YTick', 1:T(2)/dy:Ny);
set(ax, 'XTickLabel', minX:T(1):maxX);
set(ax, 'YTickLabel', minY:T(2):maxY);
axis([0 Nx+1 0 Ny+1]);
view([-37.5 30]);
end


サンプルコード(使い方)

clear; close all; clc;

% Exsample 1
[X, Y] = meshgrid(-10:10, -10:10);
Z = sqrt(X.^2+Y.^2);
figure;
bar3(Z);
bar3XYtick(gca, X, Y, [2 5]);
xlabel('X');
ylabel('Y');
zlabel('Z');

% Exsample 2
X = -pi:0.1:pi;
Y = -pi:0.1:pi;
Z = sin(X')*sin(Y);
figure;
bar3(Z);
bar3XYtick(gca,X, Y, [2 2]);
xlabel('X');
ylabel('Y');
zlabel('Z');


実行するとこんな感じの図が表示されます。
Exsample1:
f:id:FounderLeis:20181119003439p:plain
Exsample2:
f:id:FounderLeis:20181119002929p:plain

ちゃんとデータ数ではなく数値が入っていることが確認できます。

―――――――――――――――――――――――――――――――
もっときれいにやる方法がある気がするが思い浮かばないですね…
どなたかもっと簡潔にできる方法を知っている方がいたら教えていただきたです。