#author("2018-07-25T15:18:27+09:00","default:Miyashita","Miyashita")
#author("2019-12-25T11:07:47+09:00","default:Miyashita","Miyashita")
*平面図の特定部分のマスキング [#c4675724]
**はじめに [#yd774ea1]
pcolorやcontourfは,複数のcolormapを使って重ねた表示をするのが難しい.~
特定の部分だけ別の基準で塗りつぶし(ハッチング?)をしたい時に.~
適当にデータを用意しておく.
#codeprettify(lang-matlab){{
% sample data
n = 501;
[x,y,z] = peaks(n);
}}
今回は,peaksで作成された配列zの中から一部をくりぬき, colormap(parula) のとは別の色をつけることを考える.~
2手法でやってみた.下記の手法は,配列の要素数が少ないと図が不細工になるため,要素数が十分大きい(解像度が細かい)場合に限る.
#htmlinsert(MATLAB/test_masking.html)

***方法① patchで各メッシュを塗りつぶす [#cd87cf95]
例えば z<-4 または 6<z の範囲を異なる色で着色するとして,まず該当範囲をNaNにして描いてみる.
#codeprettify(lang-matlab){{
% thresholds
z(z<-4|6<z) = NaN;
% figure
figure
contourf(x,y,z,-4:6);hold on
axis equal tight
}}
#ref(https://main-t-miyashita.ssl-lolipop.jp/hydrocoast/image/MATLAB/mask0.jpg,583x438)

この白抜き部分を塗りつぶすために,patchのデータを作成する.~
下記の操作は,NaNになっている格子を頂点と面のデータにそれぞれ変換している.

#codeprettify(lang-matlab){{
xvec = x(1,:);
yvec = y(:,1);
dx = xvec(2)-xvec(1);
dy = yvec(2)-yvec(1);

% count the number of NaN
ind = find(isnan(z));

% preallocate
np = length(ind);
faces = zeros(np,4);
vertices = zeros(4*np,2);

% data for patch
for k = 1:np
   [i,j] = ind2sub(size(z),ind(k));
   faces(k,:) = 4*(k-1)+1:4*k;
   vertices(4*(k-1)+1:4*k,:) = [xvec(j)-0.5*dx         ,yvec(i)-0.5*dy; ...
                                xvec(min(j+1,n))-0.5*dx,yvec(i)-0.5*dy; ...
                                xvec(min(j+1,n))-0.5*dx,yvec(min(i+1,n))-0.5*dy; ...
                                xvec(j)-0.5*dx         ,yvec(min(i+1,n))-0.5*dy];  
end

% overlay
patch('Faces',faces,'Vertices',vertices,'FaceColor',[.7,.7,.7],'FaceAlpha',0.5,'EdgeColor','None');
}}
#ref(https://main-t-miyashita.ssl-lolipop.jp/hydrocoast/image/MATLAB/mask1.jpg,,583x438)

変数verticesには着色するメッシュの4つの頂点,facesには4つの頂点からなる面の指定をしている.~
patchによる着色は,pcolorなどの後にあれば,hold on,hold offをしなくても上塗りされる(少なくとも2015b時点では).~
quiverなどの矢印もpatchの裏に埋もれてしまうので,同時に表示する場合は透過度(FaceAlpha,0〜1)を小さくする.
 
***方法② colormapの上端か下端に色を追加する [#nfad3b25]
RGBが指定されたn行3列の配列の上端か下端に,つけたい色のRGBを挿入するという力技がある.~
例えば組み込みのcolormapであるparulaを使う場合,

#codeprettify(lang-matlab){{
[x,y,z] = peaks(n);
z(z<-4|6<z) = -4-1e-5;

figure
% edit colormap
cmap = colormap(parula(10));
cmap = vertcat([.9,.9,.9],cmap);

% contourf 
contourf(x,y,z,-5:6);hold on
caxis([-5 6])
colormap(cmap);

% format colorbar
cb = colorbar;
cbl = cb.TickLabels;
cbl{1} = '';
cb.TickLabels = cbl;
}}
#ref(https://main-t-miyashita.ssl-lolipop.jp/hydrocoast/image/MATLAB/mask2.jpg,583x438)
contourfとpatchを使った①と似たような図が作成できた.
この方法であれば,quiverをオーバーラップさせることも可能.~
ただし,colorbarの表示に追加した色が含まれてしまったり,特にcontourfではcaxisのrangeの指定が面倒になったりする.~

***参考 MathWorks公式 [#u0e438cb]
-[[contourf>https://jp.mathworks.com/help/matlab/ref/contourf.html]]~
-[[patch>https://jp.mathworks.com/help/matlab/ref/patch.html]]~

Front page   Edit Diff Attach Copy Rename Reload   New List of pages Search Recent changes   Help   RSS of recent changes