簡體   English   中英

Bar3繪圖具有單獨的x,y,高度和寬度值

[英]Bar3 plot with seperate x,y,height and width values

下面的解決方案是使用單獨的x,y值和單獨的寬度和高度值繪制條形圖3

BAR3(X,Y,Z,xWidth,yWidth)

我們目前正在開發一個項目,允許人們在3d函數f(x,y)下可視化區域。 這樣做的目的是演示條形切割3d表面的方式。 間接地可視化所需的積分。

我們希望條形圖與表面網格的間隔匹配。 下面是這個想法的粗略演示。

想法的例子

bar3只有x值bar3(x,z)的輸入,其中surf有x和y surf(x,y,z)的輸入

不幸的是,這就是我們得到的。 - 這是因為bar3不能用x和y表示

GUI

碼:

clc;
cla;
d=eval(get(handles.edtOuterUpperB,'string'));
c=eval(get(handles.edtOuterLowerB,'string'));
b=eval(get(handles.edtInnerUpperB,'string'));
a=eval(get(handles.edtInnerLowerB,'string'));

n=eval(get(handles.edtInnerInterval,'string'));
m=eval(get(handles.edtOuterInterval,'string'));

h=(b-a)/n;
k=(d-c)/m;

[x,y] = meshgrid(a:h:b, c:k:d);
f=eval(get(handles.edtFunc,'string'));
surf(x,y,f);

hold on
bar3(f,1);

如果仔細觀察,您會看到XDataYData與網格到3D條形圖不同。 這是因為您的網格使用“實際”x和y值,而條形圖使用x和y值的索引。

要解決此問題,您需要更改其中一個。 對於您的情況,最容易改變的是表面。 實際上,您可以省略xy輸入,並且在生成曲面時,默認情況下將使用索引的xy值。

surf(f);

surf文件:

surf(Z)使用x = 1:ny = 1:m從矩陣Z的z分量創建三維陰影表面,其中[m,n] = size(Z) 高度Z是在幾何矩形網格上定義的單值函數。 Z指定顏色數據以及表面高度,因此顏色與表面高度成比例。

更新

如果要在x軸和y軸上保留非索引值,則需要轉換bar3圖。 不幸的是,MATLAB提供了一種指定x軸機器人而不是 y軸的方法。 您可以采取兩種方法之一。

更改XData

您可以獲取生成的bar對象的XData屬性,並將其更改為所需的數據。

x = a:h:b;
y = c:k:d;

%// Anonymous function to scale things for us
scaler = @(vals)x(1) + ((vals-1) * (x(end) - x(1)) / (numel(x) - 1));

%// Create the bar plot
bars = bar3(y, f);

%// Change the XData
xdata = get(bars, 'XData');
xdata = cellfun(scaler, xdata, 'uni', 0);
set(bars, {'XData'}, xdata);
set(gca, 'xtick', x)

%// Now plot the surface
surf(x,y,f);

只是為了證明這一點:

x = linspace(0.5, 1.5, 5);
y = linspace(2.5, 4.5, 4);

f = rand(4,5);

scaler = @(vals)x(1) + ((vals-1) * (x(end) - x(1)) / (numel(x) - 1));
bars = bar3(y, f);


set(bars, {'XData'}, cellfun(scaler, get(bars, 'XData'), 'uni', 0))
set(gca, 'xtick', x)
axis tight

在此輸入圖像描述

更改XTickLabels

您可以簡單地將顯示的值更改為您希望它們的值而不是索引值,而不是更改實際數據。

x = a:h:b;
y = c:k:d;
labels = arrayfun(@(x)sprintf('%.2f', x), x, 'uni', 0);
bar3(y, f);
set(gca, 'xtick', 1:numel(x), 'xticklabels', labels);
hold on

%// Make sure to use the INDEX values for the x variable
surf(1:numel(x), y, f);

在此輸入圖像描述

我們找到了一個用戶貢獻的函數scatterbar3,它以我們想要的方式執行,與bar3使用的方式不同: http//www.mathworks.com/matlabcentral/fileexchange/1420-scatterbar3

然而,我們必須糾正一些輕微的打嗝:

堅持,稍等

scatterbar3(X,Y,F,H);

scatterbar3沒有單獨的條形寬度和高度輸入,因此當間隔不相等時會出現大的間隙。 演示如下。

GUI錯誤

因此,我們編輯了scatterbar3函數,以便將條的寬度和高度都作為輸入:

編輯的scatterbar3函數:

function scatterbar3(X,Y,Z,widthx,widthy)

[r,c]=size(Z);
for j=1:r,
    for k=1:c,
        if ~isnan(Z(j,k))
            drawbar(X(j,k),Y(j,k),Z(j,k),widthx/2,widthy/2)
        end
    end
end

zlim=[min(Z(:)) max(Z(:))];
if zlim(1)>0,zlim(1)=0;end
if zlim(2)<0,zlim(2)=0;end
axis([min(X(:))-widthx max(X(:))+widthx min(Y(:))-widthy max(Y(:))+widthy zlim])
caxis([min(Z(:)) max(Z(:))])

function drawbar(x,y,z,widthx,widthy)

h(1)=patch([-widthx -widthx widthx widthx]+x,[-widthy widthy widthy -widthy]+y,[0 0 0 0],'b');
h(2)=patch(widthx.*[-1 -1 1 1]+x,widthy.*[-1 -1 -1 -1]+y,z.*[0 1 1 0],'b');
h(3)=patch(widthx.*[-1 -1 -1 -1]+x,widthy.*[-1 -1 1 1]+y,z.*[0 1 1 0],'b');
h(4)=patch([-widthx -widthx widthx widthx]+x,[-widthy widthy widthy -widthy]+y,[z z z z],'b');
h(5)=patch(widthx.*[-1 -1 1 1]+x,widthy.*[1 1 1 1]+y,z.*[0 1 1 0],'b');
h(6)=patch(widthx.*[1 1 1 1]+x,widthy.*[-1 -1 1 1]+y,z.*[0 1 1 0],'b');
set(h,'facecolor','flat','FaceVertexCData',z)

最后工作解決方案在行動:

堅持,稍等

scatterbar3(X,Y,F,H,K);

工作GUI 1

工作GUI 2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM