はじめに
annotation コマンドによる矢印は、美しく気品に満ちていて好きです。しかし、座標の指示方法が、axes内で設定したaxisの単位によるものではなく、figure画面の全体を[幅1.0×高さ1.0]として、normalized単位で指定しなければなりません。
これが面倒で、使うのをためらいがちになってしまいます。しかし、比較的簡単に解決できる方法があります。座標変換用のローカル関数を作って利用するものです。ただ、過去に使っていた関数では引数の数が多かったのがネックで、今一歩の感がありました。
本題
ところが、ここで紹介する関数は引数が少なく、たった3つだけです。この応用例を図1に示します。往復電線路周りの磁界のquiver図です。詳しくは、プログラムリストの中のコメントを参照ください。
おわりに
実は、この記事の内容は、過去の記事の一部を抜き出して、再編集しただけのものです。「いいね」があまり付かなかった記事でも、一部を抜き出して紹介したところ、予想外の「いいね」を頂けたという経験がありました。そこで2匹目のドジョウを狙ってみました。あざとくて、すみません。
プログラム
座標変換用ローカル関数
実際には、磁界のquiver図のプログラムのうしろに付けるべきものです。しかし、この記事の主役なので、分離して先に示しました。axesのハンドルを引数の一つとして渡しているところがミソです。
% ===============================================================
% axes の座標値を figure の normalized 単位に変換するローカル関数
% ===============================================================
function [A,B]=axe2fig(haxe,X,Y)
% 【入力】
% haxe: 現在アクティブになっている axes のハンドル。
% 呼び出し側での引数は「gca」とすること。
% X: axes 上の点の x座標群
% (点の数に相当する要素数の配列やベクトル)
% Y: 〃 y 〃
% 【出力】
% A: X を normalized 単位に変換後の配列やベクトル
% B: Y 〃
ap = haxe.Position;
al = ap(1); ab = ap(2); aw = ap(3); ah = ap(4);
area = axis(haxe);
xmin = area(1); xmax = area(2); ymin = area(3); ymax = area(4);
A = aw*(X-xmin)/(xmax-xmin) + al;
B = ah*(Y-ymin)/(ymax-ymin) + ab;
end
磁界のquiver図
% arrow_test03.m
% annotationコマンドの矢印の利用例(往復電線路周りの磁界quiver図)
clear
close all
% ==========================================================
% 往復電線路周りの磁界の計算(比例スケールだが、単位は適当)
% ==========================================================
x=[-10:2:10];
y=[-8:2:8];
[X,Y]=meshgrid(x,y);
d=8; % 電線間の距離
U1=Y.*(1./((X-d/2).^2+Y.^2)); % 右側の電流による磁界のx方向成分
V1=-(X-d/2)./((X-d/2).^2+Y.^2); % 右側の電流による磁界のy方向成分
U2=-Y.*(1./((X+d/2).^2+Y.^2)); % 左側の電流による磁界のx方向成分
V2=(X+d/2)./((X+d/2).^2+Y.^2); % 左側の電流による磁界のy方向成分
U=U1+U2; V=V1+V2; % 合成磁界のベクトル(x,y方向成分)
L=sqrt(U.^2+V.^2); % 磁界の強さ
U0=U./L; V0=V./L; % 磁界の単位ベクトル(x,y方向成分)
% 矢印の基準点を、矢印軸の根元から矢印軸の中央に変更
r=0.8; % 矢印の長さの半分
A=atan2(V,U); % 磁界ベクトルの傾き角度
X1=X+r*cos(A+pi); % 磁界ベクトル矢印の
Y1=Y+r*sin(A+pi); % 始点のx,y座標
X2=X+r*cos(A); % 磁界ベクトル矢印の
Y2=Y+r*sin(A); % 終点のx,y座標
% ============================================================
% 磁界ベクトルのquiver図を描画(比例スケールだが、単位は適当)
% ============================================================
figure(1)
ha=axes;
hapos=ha.Position;
ha.Position=hapos+[-0.04 -0.02 0 0];
% カラーバーやタイトルのスペースを
% 空けるために、サイズを変えずに、
% axesをやや左下に移動。
hapos=ha.Position; % その結果の位置を再取得
axis equal
axis([[-9 9]*1.2679 [-9 9]]); % 1.2679: 既定のアスペクト比
hold on
cmap=jet; % カラーマップjetのデータを借用
% 磁界の強さの階調分け(cmapアクセス用のインデックス nc)
Lmax=max(L(:));
Lmin=min(L(:));
nc=floor(63.99*(L-Lmin)/(Lmax-Lmin))+1;
% axis系 → normalized系 座標変換(ローカル関数の呼び出し)
[A1,B1]=axe2fig(gca,X1,Y1); % 矢印の始点群行列のx/y座標(A1/B1)
[A2,B2]=axe2fig(gca,X2,Y2); % 〃 終点群 〃 (A2/B2)
% 矢印の描画
for l=1:size(X,1)
for c=1:size(X,2)
a1=A1(l,c); a2=A2(l,c); b1=B1(l,c); b2=B2(l,c);
% 電線の位置では、磁界の大きさがNaNになるので矢印は描かない。
if ~(isnan(a1) | isnan(a2) | isnan(b1) | isnan(b2))
annotation('arrow',[a1 a2],[b1 b2],'LineWidth',1, ...
'Color',cmap(nc(l,c),:));
end
end
end
grid on
% 電流の方向を図示
text(4,0,'$$\otimes$$','FontSize',20,'Interpreter','latex', ...
'HorizontalAlign','center','VerticalAlign','middle');
text(-4,0,'$$\odot$$','FontSize',20,'Interpreter','latex', ...
'HorizontalAlign','center','VerticalAlign','middle');
title('annotation矢印による 往復電線路周りの磁界表示','FontSize',13);
colormap(jet); % カラーマップとして jet を使用
% 位置を指定してカラーバーを表示
colorbar('Position',[hapos(1)+hapos(3)+0.01 hapos(2) 0.03 hapos(4)])