How can I remove the back faces of a 3D matlab plot

前端 未结 1 1668
情话喂你
情话喂你 2021-01-23 19:07

When plotting a 3d graph in matlab, the back faces of the bounding box are filled in white:

These can easily all be removed with

ax = gca;
ax.Co         


        
相关标签:
1条回答
  • 2021-01-23 19:44

    Using the undocumented Axes.Backdrop property, you can sort of get this behaviour. Axes.Backdrop.Face.VertexData contains a list of the vertices of the backdrop. We can find and keep the floor with:

    ax = gca;
    face = ax.Backdrop.Face;
    
    % can be replaced with conditions on other axes and limits
    point_on_face = face.VertexData(3,:) == ax.ZLim(1);
    is_target_face = all(reshape(point_on_face, 4, []));
    target_face_verts = logical(kron(is_target_face, ones(1, 4)));
    
    % discard all but the first quad (the floor)
    face.VertexData = face.VertexData(:,target_face_verts);
    

    However, when the axes are rotated, these quads are redrawn, making this not an effective solution.

    We can go further by adding an event listener:

    function h = set_walls(ax, varargin)
      function update()
        face = ax.Backdrop.Face;
        data = face.VertexData;
        if empty(data); return; end
        keep_verts = false(1, size(data, 2));
        for side = varargin'
          side = side{:};
          switch side
            case 'xmin'; point_on_face = data(1,:) == ax.XLim(1);
            case 'xmax'; point_on_face = data(1,:) == ax.XLim(2);
            case 'ymin'; point_on_face = data(2,:) == ax.YLim(1);
            case 'ymax'; point_on_face = data(2,:) == ax.YLim(2);
            case 'zmin'; point_on_face = data(3,:) == ax.ZLim(1);
            case 'zmax'; point_on_face = data(3,:) == ax.ZLim(2);
            otherwise; error('Unknown face');
          end
          is_target_face = all(reshape(point_on_face, 4, []));
          keep_verts = keep_verts | logical(kron(is_target_face, ones(1, 4)));
        end
        face.VertexData = data(:,keep_verts);
      end
      h = addlistener(ax, 'MarkedClean', @(x, y) update);
    end
    

    This flickers, but it works. The function can be used as set_walls(gca, 'zmin')

    0 讨论(0)
提交回复
热议问题