MATLAB で透明度付きプロット~円は rectangle で
MATLAB の Line は透明度が指定できない?
ツイッターで
「MATLAB の Line は透明度が指定できない」
という投稿を見かけました。
「そうなんだよな~」
と思って代替方法を。
patch 関数
th = 0:pi/20:2*pi;
y = sin(th);
patch([th,fliplr(th)],[y,fliplr(y)],'b','LineWidth',2,'EdgeColor','b',"EdgeAlpha",0.1);
patch([th,fliplr(th)],[y,fliplr(y)]+0.2,'b','LineWidth',2,'EdgeColor','b',"EdgeAlpha",0.5);
"patch" なら、α を指定できます。
ただ、本来は多角形の描画関数なので始点と終点を一致させる必要があり、上記スクリプトのように flip を使って折り返しています。
> 2022/06/11 追記
flip しなくても最後に NaN を追加すれば良いことが公式ドキュメントに書いてありました。
そういえば見た気がする・・。
th2 = [th NaN]; y2 = [y NaN];
patch(th2,y2,'b','LineWidth',2,'EdgeColor','b',"EdgeAlpha",0.1);
patch(th2,y2+0.2,'b','LineWidth',2,'EdgeColor','b',"EdgeAlpha",0.5);
最後の例も修正しました。
似たような関数で "polyshape" があります。こちらも透明度は指定可能ですが「囲まれた領域」が含まれている必要があり、上記のような指定はできません。
polyshapeの使用例はこちらをご覧ください。
隠された4次元目
でもその後、「あれ・・?」となんかモヤモヤ・・。
急に、
「確か、4次元目に直接指定すれば Line でも α が指定できた気がする!?」
というのを思い出しました!
for alpha = 0:0.1:1
plot(y+alpha, LineWidth=2, Color=[1 0.5 0 alpha])
if alpha == 0; hold on; end
end
hold off
できました!
なぜかマニュアルにも載ってないですし、
>> p=plot(y, LineWidth=2, Color=[1 0.5 0 0.1])
p =
Line のプロパティ:
Color: [1 0.5000 0]
プロパティにも表示されません。
しかし、
p.Color=[p.Color 0.5];
とプロパティを変更すれば透明度が更新されます。
rectangle 関数
同様に "rectangle" も、直接 α チャネルを指定すればokです。(u_u)
for r=0.1:0.1:1
pos = [0 0 r r];
rectangle(Position=pos, LineWidth=2, EdgeColor=[0 0 1 r^3], Curvature=[1 1])
pos = [-r/2 -r/2 r r];
rectangle(Position=pos, LineWidth=2, EdgeColor=[1 0 0 r^3], Curvature=[1 1])
end
確かだいぶ前にできることに気付いたんですが、
しばらく経って「できたっけ?」
と思ってマニュアル確認すると載ってないので、
「勘違いだったか・・」
と思ってしまっていたようです。(^_^;)
後から透明度変更
後から透明度を変更すれば、このようなこともできます。
一旦全て同じ透明度で描いてから、後から透明度だけを変更しています。
% clear
f = figure(1);
cla
line = true; % true : plot、false : patch
% 背景画面描画
th = 0:pi/20:2*pi;
y = sin(th);
for alpha = 0:0.1:1
plot(th, (y+alpha/2), LineWidth=2, Color=[1 0.5 0 alpha])
if alpha == 0; hold on; end
end
th = 0:pi/50:2*pi; % 各sin関数のステップ設定
th2 = 0:pi/50:2*pi; % 移動量設定
N = length(th2);
clear p
p = gobjects(1,N); % 各sin関数のグラフィックオブジェクト初期化
cols = zeros(N,3); % 各色保存用
alpha = 0.5; % 確認用透明度
cnt = 1;
for dth = th2
y = sin(th - dth);
col = squeeze(lab2rgb([75, cos(dth-pi)*100, sin(dth-pi)*100])); % L*a*b
col = min(col,1); col = max(col,0);
if line
p(cnt) = plot(th,y,LineWidth=3,Color=[col alpha]);
cols(cnt,:) = col;
else
xx = [th,NaN]; yy = [y,NaN];
p(cnt) = patch(xx,yy,'b',LineWidth=3,EdgeColor=col,EdgeAlpha=alpha);
end
if cnt==1; hold on; end
cnt = cnt + 1;
drawnow
end
hold off
% 透明化
for k=1:length(p)
if line
p(k).Color = [cols(k,:) 0];
else
p(k).EdgeAlpha = 0;
end
end
we = false; % trueでgifファイル保存
st = true; % 1st frame
filename = 'LineAlpha.gif';
N2 = 20; % 一度に可視化する数
for j=1:length(th2)
for k=0:N2
idx = mod(j+k, length(th2));
idx = max(idx,1);
alpha = (k/N2)^2;
if line
p(idx).Color = [cols(idx,:) alpha];
else
p(idx).EdgeAlpha = alpha;
end
xlim([0 max(th)])
end
drawnow
if we
frame = getframe(f); % capture with border frame
% frame = getframe(gca); % take image only
gr = frame2im(frame);
gr = imresize(gr,0.5);
[bA,map] = rgb2ind(gr,256);
if (st)
imwrite(bA,map,filename,'gif','LoopCount',Inf,'DelayTime',1/15);
st = false;
else
imwrite(bA,map,filename,'gif','WriteMode','append','DelayTime',1/15);
end
end
end
if we; disp('Finished'); end % ライブスクリプト動作では後半が表示されなかったりするので
もちろん色自体も変えられます。
なぜ、マニュアルに載っていないんでしょうね~?(;¬_¬)
そのうち、指定できなくなってしまうのでしょうか・・?
正式対応して欲しい!
MATLAB標準には「円を描く」命令はない!
ところで、「rectangle 関数」のスクリプト例にはもうひとネタ含まれています。
そう、"rectangle" なのに円が描かれています。
MATLAB標準には「円を描く」命令はない(!)のですが、
(Image Processing Toolbox には "viscircles" があります)
"rectangle" で "Curvature=[1 1]" と指定すれば(楕)円になります(=1でもok)
ただしあくまでも矩形描画関数ですので、外接矩形の左下座標を指定する必要があります。
透明度、大事ですよね。(-_☆)
この記事が気に入ったらサポートをしてみませんか?