bluemira.display.plotter ======================== .. py:module:: bluemira.display.plotter .. autoapi-nested-parse:: api for plotting using matplotlib Attributes ---------- .. autoapisummary:: bluemira.display.plotter.UNIT_LABEL bluemira.display.plotter.X_LABEL bluemira.display.plotter.Y_LABEL bluemira.display.plotter.Z_LABEL Classes ------- .. autoapisummary:: bluemira.display.plotter.Zorder bluemira.display.plotter.ViewDescriptor bluemira.display.plotter.DictOptionsDescriptor bluemira.display.plotter.DefaultPlotOptions bluemira.display.plotter.PlotOptions bluemira.display.plotter.BasePlotter bluemira.display.plotter.PointsPlotter bluemira.display.plotter.WirePlotter bluemira.display.plotter.FacePlotter bluemira.display.plotter.ComponentPlotter bluemira.display.plotter.Plottable Functions --------- .. autoapisummary:: bluemira.display.plotter.get_default_options bluemira.display.plotter._validate_plot_inputs bluemira.display.plotter._get_plotter_class bluemira.display.plotter.plot_2d bluemira.display.plotter.plot_3d bluemira.display.plotter._get_ndim bluemira.display.plotter._get_plan_dims bluemira.display.plotter.plot_coordinates bluemira.display.plotter._plot_3d bluemira.display.plotter._plot_2d bluemira.display.plotter.plot_2d_mesh_plt bluemira.display.plotter.plot_dolfinx_2d_mesh_plt Module Contents --------------- .. py:data:: UNIT_LABEL :value: '[m]' .. py:data:: X_LABEL :value: 'x [m]' .. py:data:: Y_LABEL :value: 'y [m]' .. py:data:: Z_LABEL :value: 'z [m]' .. py:class:: Zorder(*args, **kwds) Bases: :py:obj:`enum.Enum` .. autoapi-inheritance-diagram:: bluemira.display.plotter.Zorder :parts: 1 :private-bases: Layer ordering of common plots .. py:attribute:: GRID :value: 0.5 .. py:attribute:: POSITION_1D :value: 1 .. py:attribute:: POSITION_2D :value: 2 .. py:attribute:: PLASMACURRENT :value: 7 .. py:attribute:: PSI :value: 8 .. py:attribute:: FLUXSURFACE :value: 9 .. py:attribute:: SEPARATRIX :value: 10 .. py:attribute:: OXPOINT :value: 11 .. py:attribute:: FACE :value: 20 .. py:attribute:: WIRE :value: 30 .. py:attribute:: POINTS :value: 35 .. py:attribute:: RADIATION :value: 40 .. py:attribute:: CONSTRAINT :value: 45 .. py:attribute:: TEXT :value: 100 .. py:class:: ViewDescriptor Descriptor for placements in dataclass .. py:attribute:: _default .. py:method:: __set_name__(_, name: str) Set the attribute name from a dataclass .. py:method:: __get__(obj: Any, _) -> tuple[numpy.ndarray, numpy.ndarray, float, str] Get the view tuple :returns: the view attributes from the instance or defaults. .. py:method:: __set__(obj: Any, value: str | tuple | bluemira.geometry.placement.BluemiraPlacement) Set the view :raises DisplayError: View not known .. py:class:: DictOptionsDescriptor(default_factory: collections.abc.Callable[[], dict[str, Any]] | None = None) Keep defaults for options unless explicitly overwritten .. rubric:: Notes The default will be reinforced if value set to new dictionary. Otherwise as a dictionary is mutable will act in the normal way. .. code-block:: python po = PlotOptions() po.wire_options["linewidth"] = 0.1 # overrides default po.wire_options["zorder"] = 2 # adds new zorder option # setting a new dictionary resets the defaults with zorder overridden po.wire_options = {'zorder': 1} del po.wire_options["linewidth"] # linewidth unset No checks are done on the contents of the dictionary. .. py:attribute:: default .. py:method:: __set_name__(_, name: str) Set the attribute name from a dataclass .. py:method:: __get__(obj: Any, _) -> collections.abc.Callable[[], dict[str, Any]] | dict[str, Any] :returns: the options dictionary .. py:method:: __set__(obj: Any, value: collections.abc.Callable[[], dict[str, Any]] | dict[str, Any]) Set the options dictionary .. py:class:: DefaultPlotOptions The options that are available for plotting objects in 2D. :param show_points: If True, points are plotted. By default False. :param show_wires: If True, wires are plotted. By default True. :param show_faces: If True, faces are plotted. By default True. :param point_options: Dictionary with matplotlib options for points. By default {"s": 10, "facecolors": "blue", "edgecolors": "black"} :param wire_options: Dictionary with matplotlib options for wires. By default {"color": "black", "linewidth": "0.5"} :param face_options: Dictionary with matplotlib options for faces. By default {"color": "red"} :param view: The reference view for plotting. As string, possible options are "xy", "xz", "yz". By default 'xz'. :param ndiscr: The number of points to use when discretising a wire or face. :param byedges: If True then wires or faces will be discretised respecting their edges. .. py:attribute:: show_points :type: bool :value: False .. py:attribute:: show_wires :type: bool :value: True .. py:attribute:: show_faces :type: bool :value: True .. py:attribute:: number_points :type: bool :value: False .. py:attribute:: point_options :type: DictOptionsDescriptor .. py:attribute:: wire_options :type: DictOptionsDescriptor .. py:attribute:: face_options :type: DictOptionsDescriptor .. py:attribute:: ndiscr :type: int :value: 100 .. py:attribute:: byedges :type: bool :value: True .. py:attribute:: view :type: ViewDescriptor .. py:attribute:: _external_options :type: bool :value: True .. py:property:: view_placement :type: bluemira.geometry.placement.BluemiraPlacement returns: the view as BluemiraPlacement .. py:class:: PlotOptions(**kwargs) Bases: :py:obj:`bluemira.display.tools.Options` .. autoapi-inheritance-diagram:: bluemira.display.plotter.PlotOptions :parts: 1 :private-bases: The options that are available for plotting objects .. py:attribute:: __slots__ :value: () .. py:attribute:: _options .. py:function:: get_default_options() -> PlotOptions :returns: the default plot options. .. py:class:: BasePlotter(options: PlotOptions | None = None, *, data: numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates | bluemira.geometry.base.BluemiraGeoT | bluemira.base.components.Component | None = None, **kwargs) Bases: :py:obj:`abc.ABC` .. autoapi-inheritance-diagram:: bluemira.display.plotter.BasePlotter :parts: 1 :private-bases: Base utility plotting class .. py:attribute:: _CLASS_PLOT_OPTIONS :type: ClassVar .. py:attribute:: options .. py:method:: set_view(view: str | bluemira.geometry.placement.BluemiraPlacement) Set the plotting view .. py:property:: ax :type: matplotlib.axes.Axes returns: the axes object .. py:method:: _check_obj(obj) :abstractmethod: Internal function that check if obj is an instance of the correct class .. py:method:: _check_options() :abstractmethod: Internal function that check if it is needed to plot something .. py:method:: initialise_plot_2d(ax=None) Initialise the plot environment .. py:method:: show() :staticmethod: Function to show a plot .. py:method:: _populate_data(obj: numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates | bluemira.geometry.base.BluemiraGeoT | bluemira.base.components.Component) :abstractmethod: Internal function that makes the plot. It fills self._data and self._projected_data .. py:method:: _make_plot_2d() :abstractmethod: Internal function that makes the plot. It should use self._data and self._projected_data, so _populate_data should be called before. .. py:method:: _set_aspect_2d() .. py:method:: _set_label_2d() .. py:method:: _set_aspect_3d() .. py:method:: _set_label_3d() .. py:method:: plot_2d(obj: numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates | bluemira.geometry.base.BluemiraGeoT | bluemira.base.components.Component, ax: matplotlib.axes.Axes | None = None, *, show: bool = True) -> matplotlib.axes.Axes 2D plotting method :returns: The axes with the plotted data. .. py:method:: initialise_plot_3d(ax=None) Initialise the plot environment .. py:method:: _make_plot_3d() :abstractmethod: Internal function that makes the plot. It should use self._data and self._projected_data, so _populate_data should be called before. .. py:method:: plot_3d(obj: numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates | bluemira.geometry.base.BluemiraGeoT | bluemira.base.components.Component, ax: matplotlib.axes.Axes | None = None, *, show: bool = True) -> matplotlib.axes.Axes 3D plotting method :returns: The axes with the plotted data. .. py:class:: PointsPlotter(options: PlotOptions | None = None, *, data: numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates | bluemira.geometry.base.BluemiraGeoT | bluemira.base.components.Component | None = None, **kwargs) Bases: :py:obj:`BasePlotter` .. autoapi-inheritance-diagram:: bluemira.display.plotter.PointsPlotter :parts: 1 :private-bases: Base utility plotting class for points .. py:attribute:: _CLASS_PLOT_OPTIONS :type: ClassVar .. py:method:: _check_obj(obj) :staticmethod: :returns: Always returns True. .. rubric:: Notes This method currently always returns True. .. py:method:: _check_options() Check if nothing has to be plotted :returns: True if the `show_points` option is set to True, otherwise False. .. py:method:: _populate_data(obj: numpy.typing.ArrayLike) Internal function that makes the plot. It fills self._data and self._projected_data .. py:method:: _make_plot_2d() Internal function that makes the plot. It should use self._data and self._projected_data, so _populate_data should be called before. .. py:method:: _make_plot_3d(*args, **kwargs) Internal function that makes the plot. It should use self._data and self._projected_data, so _populate_data should be called before. .. py:class:: WirePlotter(options: PlotOptions | None = None, *, data: numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates | bluemira.geometry.base.BluemiraGeoT | bluemira.base.components.Component | None = None, **kwargs) Bases: :py:obj:`BasePlotter` .. autoapi-inheritance-diagram:: bluemira.display.plotter.WirePlotter :parts: 1 :private-bases: Base utility plotting class for bluemira wires .. py:attribute:: _CLASS_PLOT_OPTIONS :type: ClassVar .. py:method:: _check_obj(obj) :staticmethod: :returns: Always returns True if the object is a `BluemiraWire`. :raises TypeError: If the object is not an instance of `BluemiraWire`. .. py:method:: _check_options() Check if nothing has to be plotted :returns: True if nothing has to be plotted, otherwise False. .. py:method:: _populate_data(obj: bluemira.geometry.wire.BluemiraWire) Internal function that makes the plot. It fills self._data and self._projected_data .. py:method:: _make_plot_2d() Internal function that makes the plot. It should use self._data and self._projected_data, so _populate_data should be called before. .. py:method:: _make_plot_3d() Internal function that makes the plot. It should use self._data and self._projected_data, so _populate_data should be called before. .. py:class:: FacePlotter(options: PlotOptions | None = None, *, data: numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates | bluemira.geometry.base.BluemiraGeoT | bluemira.base.components.Component | None = None, **kwargs) Bases: :py:obj:`BasePlotter` .. autoapi-inheritance-diagram:: bluemira.display.plotter.FacePlotter :parts: 1 :private-bases: Base utility plotting class for bluemira faces .. py:attribute:: _CLASS_PLOT_OPTIONS :type: ClassVar .. py:method:: _check_obj(obj: bluemira.geometry.face.BluemiraFace) :staticmethod: :returns: Always returns True if the object is a `BluemiraFace`. :raises TypeError: If the object is not an instance of `BluemiraFace`. .. py:method:: _check_options() Check if nothing has to be plotted :returns: True if nothing has to be plotted, otherwise False. .. py:method:: _populate_data(obj: bluemira.geometry.face.BluemiraFace) Internal function that makes the plot. It fills self._data and self._projected_data .. py:method:: _make_plot_2d() Internal function that makes the plot. It should use self._data and self._projected_data, so _populate_data should be called before. .. py:method:: _make_plot_3d() Internal function that makes the plot. It should use self._data and self._projected_data, so _populate_data should be called before. .. py:class:: ComponentPlotter(options: PlotOptions | None = None, *, data: numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates | bluemira.geometry.base.BluemiraGeoT | bluemira.base.components.Component | None = None, **kwargs) Bases: :py:obj:`BasePlotter` .. autoapi-inheritance-diagram:: bluemira.display.plotter.ComponentPlotter :parts: 1 :private-bases: Base utility plotting class for bluemira faces .. py:attribute:: _CLASS_PLOT_OPTIONS :type: ClassVar .. py:method:: _check_obj(obj: bluemira.base.components.Component) :staticmethod: :returns: Always returns True if the object is a `BluemiraComponent`. :raises TypeError: If the object is not an instance of `BluemiraComponent`. .. py:method:: _check_options() Check if nothing has to be plotted :returns: True if nothing has to be plotted, otherwise False. .. py:method:: _create_plotters(comp: bluemira.base.components.Component) -> collections.abc.Iterator[BasePlotter] .. py:method:: _populate_data(comp: bluemira.base.components.Component) Internal function that makes the plot. It fills self._data and self._projected_data .. py:method:: _make_plot_2d() Internal function that makes the plot. It should use self._data and self._projected_data, so _populate_data should be called before. .. py:method:: _make_plot_3d() Internal function that makes the plot. It should use self._data and self._projected_data, so _populate_data should be called before. .. py:method:: _set_aspect_3d() .. py:function:: _validate_plot_inputs(parts: bluemira.geometry.base.BluemiraGeoT | list[bluemira.geometry.base.BluemiraGeoT], options: PlotOptions | list[None] | list[PlotOptions] | None) -> tuple[list[bluemira.geometry.base.BluemiraGeoT], list[PlotOptions] | list[None]] Validate the lists of parts and options, applying some default options. :returns: validated lists of parts and options :raises DisplayError: Number of options not equal to number of parts .. py:function:: _get_plotter_class(part: numpy.typing.ArrayLike | bluemira.geometry.coordinates.Coordinates | bluemira.geometry.base.BluemiraGeoT | bluemira.base.components.Component) :returns: the plotting class for a BluemiraGeo object. :raises DisplayError: No plotter available for type of part .. py:function:: plot_2d(parts: bluemira.geometry.base.BluemiraGeoT | collections.abc.Iterable[bluemira.geometry.base.BluemiraGeoT], options: PlotOptions | collections.abc.Iterable[PlotOptions] | collections.abc.Iterable[None] | None = None, ax: matplotlib.axes.Axes | None = None, *, show: bool = True, **kwargs) -> matplotlib.axes.Axes The implementation of the display API for BluemiraGeo parts. :param parts: The parts to display. :param options: The options to use to display the parts. :param ax: The axes onto which to plot :param show: Whether or not to show the plot immediately (default=True). Note that if using iPython or Jupyter, this has no effect; the plot is shown automatically. :returns: The axes with the plotted data. .. py:function:: plot_3d(parts: bluemira.geometry.base.BluemiraGeoT | collections.abc.Iterable[bluemira.geometry.base.BluemiraGeoT], options: PlotOptions | collections.abc.Iterable[PlotOptions] | collections.abc.Iterable[None] | None = None, ax: matplotlib.axes.Axes | None = None, *, show: bool = True, **kwargs) -> matplotlib.axes.Axes The implementation of the display API for BluemiraGeo parts. :param parts: The parts to display. :type parts: Union[Part.Shape, List[Part.Shape]] :param options: The options to use to display the parts. :type options: Optional[Union[Plot3DOptions, List[Plot3Options]]] :param ax: The axes onto which to plot :type ax: Optional[Axes] :param show: Whether or not to show the plot immediately in the console. (default=True). Note that if using iPython or Jupyter, this has no effect; the plot is shown automatically. :type show: bool :returns: The axes with the plotted data. .. py:class:: Plottable Mixin class to make a class plottable in 2D by imparting a plot2d method and options. .. rubric:: Notes The implementing class must set the _plotter2D attribute to an instance of the appropriate Plotter2D class. .. py:attribute:: _plot_options :type: PlotOptions .. py:property:: plot_options :type: PlotOptions The options that will be used to display the object. .. py:property:: _plotter :type: BasePlotter The options that will be used to display the object. .. py:method:: plot_2d(ax: matplotlib.axes.Axes | None = None, *, show: bool = True) -> matplotlib.axes.Axes Default method to call display the object by calling into the Displayer's display method. :returns: The axes with the plotted data. .. py:method:: plot_3d(ax: matplotlib.axes.Axes | None = None, *, show: bool = True) -> matplotlib.axes.Axes Function to 3D plot a component. :returns: The axes with the plotted data. .. py:function:: _get_ndim(coords: bluemira.geometry.coordinates.Coordinates) -> int :returns: The number of dimensions in the coordinate data. Returns at least 2. .. py:function:: _get_plan_dims(array: numpy.typing.ArrayLike) -> list[str] :returns: A sorted list of axis labels ("x", "y", "z") indicating which dimensions have variability. .. py:function:: plot_coordinates(coords: bluemira.geometry.coordinates.Coordinates, ax: matplotlib.axes.Axes | None = None, *, points: bool = False, **kwargs) Plot Coordinates. :param coords: Coordinates to plot :type coords: Coordinates :param ax: Matplotlib axis on which to plot :type ax: Axes :param edgecolor: The edgecolor to plot the Coordinates with :type edgecolor: str :param facecolor: The facecolor to plot the Coordinates fill with :type facecolor: str :param alpha: The transparency to plot the Coordinates fill with :type alpha: float .. py:function:: _plot_3d(coords: bluemira.geometry.coordinates.Coordinates, ax: matplotlib.axes.Axes | None = None, **kwargs) .. py:function:: _plot_2d(coords: bluemira.geometry.coordinates.Coordinates, ax: matplotlib.axes.Axes | None = None, *, points: bool, **kwargs) .. py:function:: plot_2d_mesh_plt(nodes: numpy.ndarray, faces: numpy.ndarray, face_groups: numpy.ndarray | None = None, group_colors: dict[int, str] | None = None, cmap: str = 'tab20', figsize: tuple = (6, 6), title: str = '2D Triangular Mesh', ax=None, *, show: bool = False) -> matplotlib.pyplot.Axes Plots a 2D triangular mesh with optional face group coloring. If no face_groups and no group_colors are provided, only the triangle edges will be plotted without face coloring. :param nodes: Array of node coordinates, shape (N, 2) :type nodes: np.ndarray :param faces: Array of triangle indices, shape (M, 3) :type faces: np.ndarray :param face_groups: Face group IDs for coloring, shape (M,) :type face_groups: np.ndarray, optional :param group_colors: Custom mapping from group ID to color :type group_colors: dict[int, str], optional :param cmap: Colormap used for automatic color assignment :type cmap: str :param figsize: Figure size (only used if ax is None) :type figsize: tuple :param title: Title of the plot :type title: str :param ax: An existing Axes to plot on :type ax: matplotlib.axes.Axes, optional :param show: Whether to display the plot with plt.show() :type show: bool :returns: The axes object the mesh is plotted on. :rtype: matplotlib.axes.Axes .. py:function:: plot_dolfinx_2d_mesh_plt(mesh: dolfinx.mesh.Mesh, face_groups: numpy.ndarray | None = None, group_colors: dict[int, str] | None = None, cmap: str = 'tab20', figsize: tuple = (6, 6), title: str = '2D Triangular Mesh (DOLFINx)', ax=None, *, show: bool = False) -> matplotlib.pyplot.Axes Plot a 2D triangular mesh from a DOLFINx mesh using matplotlib by leveraging `plot_2d_mesh_plt`. :param mesh: A 2D DOLFINx triangular mesh. :type mesh: dolfinx.mesh.Mesh :param face_groups: Group IDs for each face (element), same length as number of cells. :type face_groups: np.ndarray, optional :param group_colors: Mapping from group ID to color. :type group_colors: dict[int, str], optional :param cmap: Colormap for automatic coloring of groups. :type cmap: str :param figsize: Size of the figure if ax is None. :type figsize: tuple :param title: Title of the plot. :type title: str :param ax: Axes object to draw on. :type ax: matplotlib.axes.Axes, optional :param show: Whether to show the plot immediately. :type show: bool :returns: The axes object used for plotting. :rtype: matplotlib.axes.Axes :raises ValueError: If the mesh is not a triangular mesh.