Example #1
0
 def set_3d_properties(self):
     # Force the collection to initialize the face and edgecolors
     # just in case it is a scalarmappable with a colormap.
     self.update_scalarmappable()
     self._sort_zpos = None
     self.set_zsort('average')
     self._facecolor3d = PolyCollection.get_facecolor(self)
     self._edgecolor3d = PolyCollection.get_edgecolor(self)
     self._alpha3d = PolyCollection.get_alpha(self)
     self.stale = True
Example #2
0
 def set_3d_properties(self):
     # Force the collection to initialize the face and edgecolors
     # just in case it is a scalarmappable with a colormap.
     self.update_scalarmappable()
     self._sort_zpos = None
     self.set_zsort(True)
     self._facecolors3d = PolyCollection.get_facecolor(self)
     self._edgecolors3d = PolyCollection.get_edgecolor(self)
     self._alpha3d = PolyCollection.get_alpha(self)
     self.stale = True
Example #3
0
 def set_edgecolor(self, colors):
     PolyCollection.set_edgecolor(self, colors)
     self._edgecolors3d = PolyCollection.get_edgecolor(self)
Example #4
0
 def set_edgecolor(self, colors):
     PolyCollection.set_edgecolor(self, colors)
     self._edgecolors3d = PolyCollection.get_edgecolor(self)
Example #5
0
 def set_edgecolor(self, colors):
     # docstring inherited
     super().set_edgecolor(colors)
     self._edgecolor3d = PolyCollection.get_edgecolor(self)
Example #6
0
 def set_edgecolor(self, colors):
     super().set_edgecolor(colors)
     self._edgecolors3d = PolyCollection.get_edgecolor(self)
Example #7
0
def triplot(mesh, axes=None, interior_kw={}, boundary_kw={}):
    r"""Plot a mesh with a different color for each boundary segment

    The interior and boundary keyword arguments can be any keyword argument for
    :class:`LineCollection <matplotlib.collections.LinecCollection>` and
    related types.

    :arg mesh: mesh to be plotted
    :arg axes: matplotlib :class:`Axes <matplotlib.axes.Axes>` object on which to plot mesh
    :arg interior_kw: keyword arguments to apply when plotting the mesh interior
    :arg boundary_kw: keyword arguments to apply when plotting the mesh boundary
    :return: list of matplotlib :class:`Collection <matplotlib.collections.Collection>` objects
    """
    gdim = mesh.geometric_dimension()
    tdim = mesh.topological_dimension()
    BoundaryCollection, InteriorCollection = _get_collection_types(gdim, tdim)
    quad = mesh.ufl_cell().cellname() == "quadrilateral"

    if axes is None:
        figure = plt.figure()
        if gdim == 3:
            axes = figure.add_subplot(111, projection='3d')
        else:
            axes = figure.add_subplot(111)

    coordinates = mesh.coordinates
    element = coordinates.function_space().ufl_element()
    if element.degree() != 1:
        # Interpolate to piecewise linear.
        V = VectorFunctionSpace(mesh, element.family(), 1)
        coordinates = interpolate(coordinates, V)

    coords = toreal(coordinates.dat.data_ro, "real")
    result = []
    interior_kw = dict(interior_kw)
    # If the domain isn't a 3D volume, draw the interior.
    if tdim <= 2:
        cell_node_map = coordinates.cell_node_map().values
        idx = (tuple(range(tdim + 1)) if not quad else (0, 1, 3, 2)) + (0, )
        vertices = coords[cell_node_map[:, idx]]

        interior_kw["edgecolors"] = interior_kw.get("edgecolors", "k")
        interior_kw["linewidths"] = interior_kw.get("linewidths", 1.0)
        if gdim == 2:
            interior_kw["facecolors"] = interior_kw.get("facecolors", "none")

        interior_collection = InteriorCollection(vertices, **interior_kw)
        axes.add_collection(interior_collection)
        result.append(interior_collection)

    # Add colored lines/polygons for the boundary facets
    facets = mesh.exterior_facets
    local_facet_ids = facets.local_facet_dat.data_ro
    exterior_facet_node_map = coordinates.exterior_facet_node_map().values
    topology = coordinates.function_space().finat_element.cell.get_topology()

    mask = np.zeros(exterior_facet_node_map.shape, dtype=bool)
    for facet_index, local_facet_index in enumerate(local_facet_ids):
        mask[facet_index, topology[tdim - 1][local_facet_index]] = True
    faces = exterior_facet_node_map[mask].reshape(-1, tdim)

    markers = facets.unique_markers
    color_key = "colors" if tdim <= 2 else "facecolors"
    boundary_colors = boundary_kw.pop(color_key, None)
    if boundary_colors is None:
        cmap = matplotlib.cm.get_cmap("Dark2")
        num_markers = len(markers)
        colors = cmap([k / num_markers for k in range(num_markers)])
    else:
        colors = matplotlib.colors.to_rgba_array(boundary_colors)

    boundary_kw = dict(boundary_kw)
    if tdim == 3:
        boundary_kw["edgecolors"] = boundary_kw.get("edgecolors", "k")
        boundary_kw["linewidths"] = boundary_kw.get("linewidths", 1.0)
    for marker, color in zip(markers, colors):
        face_indices = facets.subset(int(marker)).indices
        marker_faces = faces[face_indices, :]
        vertices = coords[marker_faces]
        _boundary_kw = dict(**{
            color_key: color,
            "label": marker
        }, **boundary_kw)
        marker_collection = BoundaryCollection(vertices, **_boundary_kw)
        axes.add_collection(marker_collection)
        result.append(marker_collection)

    # Dirty hack to enable legends for 3D volume plots. See the function
    # `Poly3DCollection.set_3d_properties`.
    for collection in result:
        if isinstance(collection, Poly3DCollection):
            collection._facecolors2d = PolyCollection.get_facecolor(collection)
            collection._edgecolors2d = PolyCollection.get_edgecolor(collection)

    _autoscale_view(axes, coords)
    return result