简体   繁体   English

Bar3绘图具有单独的x,y,高度和宽度值

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

Solution posted below function to plot bar 3 with separate x, y values and separate width and height values 下面的解决方案是使用单独的x,y值和单独的宽度和高度值绘制条形图3

bar3(x,y,z,xWidth,yWidth) BAR3(X,Y,Z,xWidth,yWidth)

We are currently working on a project that allow one to visualize the area under a 3d function, f(x,y). 我们目前正在开发一个项目,允许人们在3d函数f(x,y)下可视化区域。 The purpose of this is to demonstrate how the bars cut a 3d surface. 这样做的目的是演示条形切割3d表面的方式。 Indirectly to visualize the desired integral. 间接地可视化所需的积分。

We wish to have the bars match up with the intervals of the surface grid. 我们希望条形图与表面网格的间隔匹配。 Below is a rough demonstration of the idea. 下面是这个想法的粗略演示。

想法的例子

bar3 only has input for the x-values bar3(x,z) , where as surf has a input for both the x and y surf(x,y,z) bar3只有x值bar3(x,z)的输入,其中surf有x和y surf(x,y,z)的输入

Unfortunately this is what we are getting. 不幸的是,这就是我们得到的。 - this is because bar3 cant be in terms of x and y - 这是因为bar3不能用x和y表示

GUI

CODE: 码:

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);

If you look closely, you will see that the XData and YData are different from the mesh to the 3D bar plot. 如果仔细观察,您会看到XDataYData与网格到3D条形图不同。 This is because your mesh uses "real" x and y values while the bar plot uses indexes for the x and y values. 这是因为您的网格使用“实际”x和y值,而条形图使用x和y值的索引。

To fix this, you will want to change one or the other. 要解决此问题,您需要更改其中一个。 For your case, the easiest one to change is going to be the surface. 对于您的情况,最容易改变的是表面。 You can actually just omit the x and y inputs and the indexed x and y values will be used instead by default when generating the surface. 实际上,您可以省略xy输入,并且在生成曲面时,默认情况下将使用索引的xy值。

surf(f);

From the documentation for surf : surf文件:

surf(Z) creates a three-dimensional shaded surface from the z components in matrix Z , using x = 1:n and y = 1:m , where [m,n] = size(Z) . surf(Z)使用x = 1:ny = 1:m从矩阵Z的z分量创建三维阴影表面,其中[m,n] = size(Z) The height, Z , is a single-valued function defined over a geometrically rectangular grid. 高度Z是在几何矩形网格上定义的单值函数。 Z specifies the color data, as well as surface height, so color is proportional to surface height. Z指定颜色数据以及表面高度,因此颜色与表面高度成比例。

Update 更新

If you want to keep the non-indexed values on the x and y axes, you will want to convert the bar3 plot instead. 如果要在x轴和y轴上保留非索引值,则需要转换bar3图。 Unfortunately, MATLAB provides a way to specify the x axis bot not the y axis. 不幸的是,MATLAB提供了一种指定x轴机器人而不是 y轴的方法。 You can take one of two approaches. 您可以采取两种方法之一。

Change the XData 更改XData

You can get the XData property of the resulting bar objects and change them to the data you want. 您可以获取生成的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);

And just to demonstrate what this does: 只是为了证明这一点:

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

在此输入图像描述

Change the XTickLabels 更改XTickLabels

Instead of changing the actual data, you could simply change the values that are displayed to be what you want them to be rather than the indexed values. 您可以简单地将显示的值更改为您希望它们的值而不是索引值,而不是更改实际数据。

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);

在此输入图像描述

We found a user contributed function scatterbar3, which does what we want, in a different way than what bar3 uses: http://www.mathworks.com/matlabcentral/fileexchange/1420-scatterbar3 我们找到了一个用户贡献的函数scatterbar3,它以我们想要的方式执行,与bar3使用的方式不同: http//www.mathworks.com/matlabcentral/fileexchange/1420-scatterbar3

There was however a slight hiccup that we had to correct: 然而,我们必须纠正一些轻微的打嗝:

hold on 坚持,稍等

scatterbar3(x,y,f,h); scatterbar3(X,Y,F,H);

scatterbar3 does not have separate inputs for the width and height of the bars, thus large gaps occur when the intervals do not equal one another. scatterbar3没有单独的条形宽度和高度输入,因此当间隔不相等时会出现大的间隙。 Demonstrated below. 演示如下。

GUI错误

We thus edited the scatterbar3 function in order to take both the width and height of the bars as inputs: 因此,我们编辑了scatterbar3函数,以便将条的宽度和高度都作为输入:

Edited scatterbar3 function: 编辑的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)

Finally the working solution in action: 最后工作解决方案在行动:

hold on 坚持,稍等

scatterbar3(x,y,f,h,k); scatterbar3(X,Y,F,H,K);

工作GUI 1

工作GUI 2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM