web-dev-qa-db-ja.com

Matlab:同じ図の異なるサーフェスに異なるカラーマップ/カラーバーを割り当てる方法

私はMatlabにかなり慣れていないので、いくつか質問があります。同じ図に2つのサーフェスと1つの平面があります。 bには別のカラーマップとカラーバーを使用し、cには別のカラーマップとカラーバーを使用したいと思います。 sは固定色なので問題ありません。

私が達成しようとしていることを説明しようと思います:

cmap1 = colormap(topobathy)-> cmap1は予想どおり64x3倍です

cmap2 = colormap(redwhitegreen)

cmap1を使用してcdata1を作成します(これは私が理解できない最初の部分であり、cmap1を使用してzデータをスケーリングする方法です。デフォルトではCDataにはz値が含まれています)

b = surf(x、y、z、cdata1)

z値を使用したbのcolorbar

c = pcolor(x、y、(z-z0))-これにはcmap2を使用したいと思います。

colorbarfor c for c using(z-z0)values

これが私がこれまでに抱えていることと私が遭遇する問題です

b=surf(x,y,z);
colormap(topobathy);
cbar1=colorbar;
set(get(cbar1,'ylabel'),'String', 'Elevation (m)', 'Rotation', 90)
hold on;
s=surf(x,y,z1,'FaceColor',[0.278 0.788 0.788])
hold on;
change=z-z0;     
c=pcolor(x,y,change)
set(c,'ZData',100 + 0*change); %plotting it above the other surfaces
colormap(redwhitegreen)`

この時点で、カラーマップはbの赤白緑に設定されています。bのカラーバー独自のクライムを備えた2番目のカラーバーを取得できません。

このリンクで説明されているfreezeColorsとcbfreezeを使用しました: http://blogs.mathworks.com/pick/2009/07/24/using-multiple-colormaps-in-a-single-figure/

しかし、あることが別のことを台無しにしながら機能します(おそらく私のせいです)。とにかく外部のmファイルを使用せずにオブジェクトを完全に制御する方法を学びたいです。

どんな助けでも大歓迎です。

12
theenemy

基本的な考え方は、カラーマップを連結してから、さまざまなプロットハンドルのカラーデータ(CData)をシフト/スケーリングして、カラーマップの目的の部分に揃えることです。したがって、カスタム関数や特定のデータが何であるかを知らなくても、colormap(topobathy(64); redwhitegreen(64))のようなことをしてから、CDatabを[1,64]の範囲にスケーリングできます。 CDatacを[65,128]の範囲に入れます。

MathWorks Webサイトにexcellentガイドがあり、これらすべてを説明しています(surf()およびpcolor()のように使用することもできますあなたの例):

http://www.mathworks.com/support/tech-notes/1200/1215.html#Example_1

カラーバーの場合、同様の方法で目盛りとラベルを偽造することができます。上記の例のカラーバーを作成する際のラフショットを次に示します。

h = colorbar;
ticks = [1 16:16:64 64:16:128];
ticks(5:6) = [62 66];
set(h, 'YTick', ticks);

labels = num2str(repmat(linspace(min(Z(:)), max(Z(:)), 5), 1, 2)', 2);
set(h, 'YTickLabel', labels)

enter image description here

16
John Colby

私はあなたと同じ問題を抱えていました、そして私が見つけた最良の(そして唯一の)解決策は次のものでした:

  1. 必要な両方のカラーマップを連結します。

    cmap1 = jet(64); cmap2 =銅(64); color_map = [cmap1; cmap2];

    したがって、最初のカラーマップ(cmap1)はAxes1と2番目のカラーマップ(cmap2)Axes2の場合。 Axes1とAxes2は同じ図にあると思います。

  2. データを正規化し、Axes1のデータの場合は0から1まで、Axes2のデータの場合は1から2までのスケールを指定します。したがって、[0、1]のAxes1と[12]のAxes2です。

    data1 = data1-lower_limit1; data1 = double(data1 ./(upper_limit1-lower_limit1));

    軸2のデータセットの場合:

    data2 = data2 - lower_limit;
    data2 = double(data2./(upper_limit2 - lower_limit2)) + 1;
    
  3. それらを表すとき:

    • 軸1:
    pcolor(handle_axes1, x_axis, y_axis, data1); shading(handle_axes1,'FLAT'); 
    caxis(handle_axes1, [0 2]);
    
    % Colorbar
    h_colorbar = colorbar('peer', handle_axes1);
    set(h_colorbar, 'YLim', [0 1]);
    
    labels = num2str(linspace(lower_limit1, upper_limit1, 6)', 2);
    set(h_colorbar, 'YTick', linspace(0, 1, 6));
    set(h_colorbar, 'YTickLabel', labels);
    
    • 軸2:
    pcolor(handle_axes2, x_axis, y_axis, data2); shading(handle_axes2,'FLAT'); 
    caxis(handle_axes2, [0 2]);
    
    % Colorbar
    h_colorbar2 = colorbar('peer', handle_axes2);
    set(h_colorbar2, 'YLim', [1 2]);
    
    labels = num2str(linspace(lower_limit2, upper_limit2, 6)', 2);
    set(h_colorbar2, 'YTick', linspace(1, 2, 6));
    set(h_colorbar2, 'YTickLabel', labels);
    

必要に応じて、pcolorまたはsurfを使用してください。それが役に立てば幸い!

1
YisasL

Matlabは、カラーマップを1つのカラーマップに連結することにより、この問題をクリーンに解決する関数newclimのコードを提供しています。このドキュメントは2012bヘルプでしか見つかりませんでしたが、オンラインでは見つかりませんでした。

最後のステップとしてCLimを更新するために使用される軸は、サーフプロットへの軸である可能性があることに注意してください。これが、このコードを適用した方法です。

色制限の計算

この例の鍵は、各サーフェスが適切な色を含むカラーマップのセクションを使用するようにするCLimの値を計算することです。

CLimの新しい値を計算するには、次のことを知る必要があります。

  • カラーマップの全長(CmLength)

  • 各軸に使用する開始カラーマップスロット(BeginSlot)

  • 各軸に使用する終了カラーマップスロット(EndSlot)

  • 軸に含まれるグラフィックオブジェクトの最小および最大CData値。つまり、CLimModeがauto(CDminおよびCDmax)の場合にMATLABによって決定されるaxesCLimプロパティの値です。

まず、サブプロット領域を定義し、サーフェスをプロットします。

im1 = load('cape.mat');
im2 = load('flujet.mat');
ax1 = subplot(1,2,1); 
imagesc(im1.X) 
axis(ax1,'image')
ax2 = subplot(1,2,2);
imagesc(im2.X) 
axis(ax2,'image')

2つのカラーマップを連結し、新しいカラーマップをインストールします。

colormap([im1.map;im2.map])

CLimの新しい値を計算するために必要なデータを取得します。

CmLength   = length(colormap);   % Colormap length
BeginSlot1 = 1;                  % Beginning slot
EndSlot1   = length(im1.map);    % Ending slot
BeginSlot2 = EndSlot1 + 1; 
EndSlot2   = CmLength;
CLim1      = get(ax1,'CLim');  % CLim values for each axis
CLim2      = get(ax2,'CLim');

CLim値を計算する関数の定義

CLimの新しい値を計算するには、カラーマップの合計サイズに対して各軸で使用するカラーマップの部分を決定し、それに応じてClim範囲をスケーリングする必要があります。これを行うためにMATLAB関数を定義できます。

function CLim = newclim(BeginSlot,EndSlot,CDmin,CDmax,CmLength)
   %                Convert slot number and range
   %                to percent of colormap
   PBeginSlot    = (BeginSlot - 1) / (CmLength - 1);
   PEndSlot      = (EndSlot - 1) / (CmLength - 1);
   PCmRange      = PEndSlot - PBeginSlot;
   %                Determine range and min and max 
   %                of new CLim values
   DataRange     = CDmax - CDmin;
   ClimRange     = DataRange / PCmRange;
   NewCmin       = CDmin - (PBeginSlot * ClimRange);
   NewCmax       = CDmax + (1 - PEndSlot) * ClimRange;
   CLim          = [NewCmin,NewCmax];
end

入力引数は、上記の箇条書きで識別されます。この関数は、最初に特定の軸に使用するカラーマップ全体のパーセンテージ(PCmRange)を計算し、次に軸のCData範囲を指定してカラーマップのその部分を使用するために必要なCLim範囲を計算します。最後に、計算されたCLim範囲に必要な最小値と最大値を決定し、これらの値を返します。これらの値は、特定の軸の色の制限です。

関数の使用

Newclim関数を使用して、各軸のCLim値を設定します。声明

set(ax1,'CLim',newclim(BeginSlot1,EndSlot1,CLim1(1),...
        CLim1(2),CmLength))

サーフェスがカラースロット65〜120を使用するように、最初の軸のCLim値を設定します。点灯しているサーフェスは下の64スロットを使用します。 CLim値もリセットする必要があります。

set(ax2,'CLim',newclim(BeginSlot2,EndSlot2,CLim2(1),...
        CLim2(2),CmLength))

関数のしくみ

MATLABでは、Axesに表示されるグラフィックスオブジェクトのCDataにこれらの値が対応していない場合でも、AxesCLimプロパティに任意の値を指定できます。これらの色に対応するCData値が実際にあるかどうかに関係なく、最小CLim値は常にカラーマップの最初の色にマップされ、最大CLim値は常にカラーマップの最後の色にマップされます。したがって、オブジェクトの実際のCDataの最小値または最大値を超えるCLimの値を指定すると、MATLABはカラーマップのサブセットのみでオブジェクトに色を付けます。

Newclim関数は、グラフィックスオブジェクトの実際のCData値を指定した開始および終了のカラーマップスロットにマップするCLimの値を計算します。これは、計算されたCLim値を持つ「仮想」グラフィックスオブジェクトを定義することによって行われます。

1
yellowjacket05