【问题标题】:Bar3 plot with seperate x,y,height and width values具有单独 x、y、高度和宽度值的 Bar3 绘图
【发布时间】:2016-04-07 20:56:11
【问题描述】:

下面发布的解决方案函数用单独的 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 表示

代码:

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

【问题讨论】:

    标签: matlab plot matlab-figure


    【解决方案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

    您可以获取结果栏对象的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);
    

    【讨论】:

    • 感谢您的贡献,不幸的是,因为我们正在绘制双积分图,我们需要具有不同边界和间距的 x 和 y 区间。您可以在我们的 GUI 上看到这一点。因此,我们将要求 bar3 函数使用“真实”x 和 y 值。这可能吗?
    • @Msegling 我已经用两种方法更新了答案,以满足您的需求。
    • 非常感谢您的贡献,它绝对有助于最终解决方案。看看我们想出了什么,如果有什么可以调整的,请告诉我们。
    【解决方案2】:

    我们发现了一个用户贡献的函数 scatterbar3,它可以做我们想做的事,与 bar3 使用的方式不同: http://www.mathworks.com/matlabcentral/fileexchange/1420-scatterbar3

    然而,我们不得不纠正一个小问题:

    等一下

    scatterbar3(x,y,f,h);

    scatterbar3 没有单独的条形宽度和高度输入,因此当间隔不相等时会出现较大的间隙。如下所示。

    我们因此编辑了 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);

    【讨论】:

      猜你喜欢
      • 2020-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-25
      • 2017-08-11
      • 2016-11-20
      • 2010-11-19
      相关资源
      最近更新 更多