'ax.voxels([x, y, z,] /, filled, **kwargs)
Plot a set of filled voxels
All voxels are plotted as 1x1x1 cubes on the axis, with filled[0,0,0]
placed with its lower corner at the origin. Occluded faces are not
plotted.
Call signatures::
voxels(filled, facecolors=fc, edgecolors=ec, **kwargs)
voxels(x, y, z, filled, facecolors=fc, edgecolors=ec, **kwargs)
.. versionadded:: 2.1
Parameters
filled : 3D np.array of bool
A 3d array of values, with truthy values indicating which voxels
to fill
x, y, z : 3D np.array, optional
The coordinates of the corners of the voxels. This should broadcast
to a shape one larger in every dimension than the shape of `filled`.
These can be used to plot non-cubic voxels.
If not specified, defaults to increasing integers along each axis,
like those returned by :func:`~numpy.indices`.
As indicated by the ``/`` in the function signature, these arguments
can only be passed positionally.
facecolors, edgecolors : array_like, optional
The color to draw the faces and edges of the voxels. Can only be
passed as keyword arguments.
This parameter can be:
- A single color value, to color all voxels the same color. This
can be either a string, or a 1D rgb/rgba array
- ``None``, the default, to use a single color for the faces, and
the style default for the edges.
- A 3D ndarray of color names, with each item the color for the
corresponding voxel. The size must match the voxels.
- A 4D ndarray of rgb/rgba data, with the components along the
last axis.
**kwargs
Additional keyword arguments to pass onto
:func:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`
Returns
faces : dict
A dictionary indexed by coordinate, where ``faces[i,j,k]`` is a
`Poly3DCollection` of the faces drawn for the voxel
``filled[i,j,k]``. If no faces were drawn for a given voxel, either
because it was not asked to be drawn, or it is fully occluded, then
``(i,j,k) not in faces``.
Examples
.. plot:: gallery/mplot3d/voxels.py
.. plot:: gallery/mplot3d/voxels_rgb.py
.. plot:: gallery/mplot3d/voxels_torus.py
.. plot:: gallery/mplot3d/voxels_numpy_logo.py'

def voxels(self, *args, **kwargs):

    if (len(args) >= 3):
        def voxels(__x, __y, __z, filled, **kwargs):
            return ((__x, __y, __z), filled, kwargs)
    else:
        def voxels(filled, **kwargs):
            return (None, filled, kwargs)
    (xyz, filled, kwargs) = voxels(*args, **kwargs)
    if (filled.ndim != 3):
        raise ValueError(u'Argument    filled    must    be    3-dimensional')
    size = np.array(filled.shape, dtype=np.intp)
    coord_shape = tuple((size + 1))
    if (xyz is None):
        (x, y, z) = np.indices(coord_shape)
    else:
        (x, y, z) = (broadcast_to(c, coord_shape) for c in xyz)
    def _broadcast_color_arg(color, name):
        if (np.ndim(color) in (0, 1)):
            return broadcast_to(color, (filled.shape + np.shape(color)))
        elif (np.ndim(color) in (3, 4)):
            if (np.shape(color)[:3] != filled.shape):
                raise ValueError(u'When    multidimensional,    {}    must    match    the    shape    of    filled'.format(name))
            return color
        else:
            raise ValueError(u'Invalid    {}    argument'.format(name))
    facecolors = kwargs.pop(u'facecolors', None)
    if (facecolors is None):
        facecolors = self._get_patches_for_fill.get_next_color()
    facecolors = _broadcast_color_arg(facecolors, u'facecolors')
    edgecolors = kwargs.pop(u'edgecolors', None)
    edgecolors = _broadcast_color_arg(edgecolors, u'edgecolors')
    self.auto_scale_xyz(x, y, z)
    square = np.array([[0, 0, 0], [0, 1, 0], [1, 1, 0], [1, 0, 0]], dtype=np.intp)
    voxel_faces = defaultdict(list)
    def permutation_matrices(n):
        u'    Generator    of    cyclic    permutation    matices    '
        mat = np.eye(n, dtype=np.intp)
        for i in range(n):
            (yield mat)
            mat = np.roll(mat, 1, axis=0)
    for permute in permutation_matrices(3):
        (pc, qc, rc) = permute.T.dot(size)
        pinds = np.arange(pc)
        qinds = np.arange(qc)
        rinds = np.arange(rc)
        square_rot = square.dot(permute.T)
        for p in pinds:
            for q in qinds:
                p0 = permute.dot([p, q, 0])
                i0 = tuple(p0)
                if filled[i0]:
                    voxel_faces[i0].append((p0 + square_rot))
                for (r1, r2) in zip(rinds[:(-1)], rinds[1:]):
                    p1 = permute.dot([p, q, r1])
                    p2 = permute.dot([p, q, r2])
                    i1 = tuple(p1)
                    i2 = tuple(p2)
                    if (filled[i1] and (not filled[i2])):
                        voxel_faces[i1].append((p2 + square_rot))
                    elif ((not filled[i1]) and filled[i2]):
                        voxel_faces[i2].append((p2 + square_rot))
                pk = permute.dot([p, q, (rc - 1)])
                pk2 = permute.dot([p, q, rc])
                ik = tuple(pk)
                if filled[ik]:
                    voxel_faces[ik].append((pk2 + square_rot))
    polygons = {}
    for (coord, faces_inds) in voxel_faces.items():
        if (xyz is None):
            faces = faces_inds
        else:
            faces = []
            for face_inds in faces_inds:
                ind = (face_inds[:, 0], face_inds[:, 1], face_inds[:, 2])
                face = np.empty(face_inds.shape)
                face[:, 0] = x[ind]
                face[:, 1] = y[ind]
                face[:, 2] = z[ind]
                faces.append(face)
        poly = art3d.Poly3DCollection(faces, facecolors=facecolors[coord], edgecolors=edgecolors[coord], **kwargs)
        self.add_collection3d(poly)
        polygons[coord] = poly
    return polygons
