2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【MATLAB】annotationコマンドの矢印を気軽に使う

Last updated at Posted at 2024-11-04

はじめに

 annotation コマンドによる矢印は、美しく気品に満ちていて好きです。しかし、座標の指示方法が、axes内で設定したaxisの単位によるものではなく、figure画面の全体を[幅1.0×高さ1.0]として、normalized単位で指定しなければなりません。

 これが面倒で、使うのをためらいがちになってしまいます。しかし、比較的簡単に解決できる方法があります。座標変換用のローカル関数を作って利用するものです。ただ、過去に使っていた関数では引数の数が多かったのがネックで、今一歩の感がありました。

本題

 ところが、ここで紹介する関数は引数が少なく、たった3つだけです。この応用例を図1に示します。往復電線路周りの磁界のquiver図です。詳しくは、プログラムリストの中のコメントを参照ください。

図1
annotation矢印による往復電線路周りの磁界表示.png

おわりに

 実は、この記事の内容は、過去の記事の一部を抜き出して、再編集しただけのものです。「いいね」があまり付かなかった記事でも、一部を抜き出して紹介したところ、予想外の「いいね」を頂けたという経験がありました。そこで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)])
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?