#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]]~