bluemira.balance_of_plant.plotting ================================== .. py:module:: bluemira.balance_of_plant.plotting .. autoapi-nested-parse:: Plotting for balance of plant Attributes ---------- .. autoapisummary:: bluemira.balance_of_plant.plotting.BALANCE_PLOT_DEFAULTS Classes ------- .. autoapisummary:: bluemira.balance_of_plant.plotting.SuperSankey bluemira.balance_of_plant.plotting.BalanceOfPlantPlotter Module Contents --------------- .. py:class:: SuperSankey(ax=None, scale=1.0, unit='', format='%G', gap=0.25, radius=0.1, shoulder=0.03, offset=0.15, head_angle=100, margin=0.4, tolerance=1e-06, **kwargs) Bases: :py:obj:`matplotlib.sankey.Sankey` .. autoapi-inheritance-diagram:: bluemira.balance_of_plant.plotting.SuperSankey :parts: 1 :private-bases: A sub-class of the Sankey diagram class from matplotlib, which is capable of connecting two blocks, instead of just one. This is done using a cute sledgehammer approach, using optimisation. Basically, the Sankey object is quite complex, and it makes it very hard to calculate the exact lengths required to connect two sub-diagrams. .. py:method:: add(patchlabel: str = '', flows: collections.abc.Iterable[float] | None = None, orientations: collections.abc.Iterable[float] | None = None, labels: str | list[str | None] | None = '', trunklength: float = 1.0, pathlengths: float | list[float] = 0.25, prior: int | None = None, future: int | None = None, connect: tuple[int, int] | list[tuple[int, int]] = (0, 0), rotation: float = 0, **kwargs) Add a simple Sankey diagram with flows at the same hierarchical level. :param patchlabel: Label to be placed at the center of the diagram. Note that *label* (not *patchlabel*) can be passed as keyword argument to create an entry in the legend. :type patchlabel: str :param flows: Array of flow values. By convention, inputs are positive and outputs are negative. Flows are placed along the top of the diagram from the inside out in order of their index within *flows*. They are placed along the sides of the diagram from the top down and along the bottom from the outside in. If the sum of the inputs and outputs is nonzero, the discrepancy will appear as a cubic Bézier curve along the top and bottom edges of the trunk. :type flows: list of float :param orientations: List of orientations of the flows (or a single orientation to be used for all flows). Valid values are 0 (inputs from the left, outputs to the right), 1 (from and to the top) or -1 (from and to the bottom). :type orientations: list of {-1, 0, 1} :param labels: List of labels for the flows (or a single label to be used for all flows). Each label may be *None* (no label), or a labeling string. If an entry is a (possibly empty) string, then the quantity for the corresponding flow will be shown below the string. However, if the *unit* of the main diagram is None, then quantities are never shown, regardless of the value of this argument. :type labels: list of (str or None) :param trunklength: Length between the bases of the input and output groups (in data-space units). :type trunklength: float :param pathlengths: List of lengths of the vertical arrows before break-in or after break-away. If a single value is given, then it will be applied to the first (inside) paths on the top and bottom, and the length of all other arrows will be justified accordingly. The *pathlengths* are not applied to the horizontal inputs and outputs. :type pathlengths: list of float :param prior: Index of the prior diagram to which this diagram should be connected. :type prior: int :param connect: A (prior, this) tuple indexing the flow of the prior diagram and the flow of this diagram which should be connected. If this is the first diagram or *prior* is *None*, *connect* will be ignored. :type connect: (int, int) :param rotation: Angle of rotation of the diagram in degrees. The interpretation of the *orientations* argument will be rotated accordingly (e.g., if *rotation* == 90, an *orientations* entry of 1 means to/from the left). *rotation* is ignored if this diagram is connected to an existing one (using *prior* and *connect*). :type rotation: float :returns: The current `.Sankey` instance. :rtype: Sankey :param \*\*kwargs: Additional keyword arguments set `matplotlib.patches.PathPatch` properties, listed below. For example, one may want to use ``fill=False`` or ``label="A legend entry"``. :param %(Patch: :type %(Patch: kwdoc)s .. seealso:: :obj:`Sankey.finish` .. py:method:: _double_connect(patchlabel: str, flows: collections.abc.Iterable[float] | None, orientations: collections.abc.Iterable[float] | None, labels: str | list[str | None] | None, trunklength: float, pathlengths: list[float], prior: int | None, future: int | None, connect: list[tuple[int, int]], rotation: float, **kwargs) Handles two connections in a Sankey diagram. :param future: The index of the diagram to connect to :param connect: The list of (int, int) connections. - connect[0] is a (prior, this) tuple indexing the flow of the prior diagram and the flow of this diagram to connect. - connect[1] is a (future, this) tuple indexing of the flow of the future diagram and the flow of this diagram to connect. .. seealso:: :obj:`Sankey.add` .. py:method:: _opt_connect(flows: collections.abc.Iterable[float] | None, orient: collections.abc.Iterable[float] | None, prior: int | None, future: int | None, connect: list[tuple[int, int]], trunklength: float) -> tuple[float, float] Optimises the second connection between Sankey diagrams. :returns: * *dx* -- The x pathlength to use to match the tips * *dy* -- The y pathlength to use to match the tips .. rubric:: Notes This is because Sankey is very complicated, and makes it hard to work out the positions of things prior to adding them to the diagrams. Because we are bizarrely using a plotting function as a minimisation objective, we need to make sure we clean the plot on every call. .. py:data:: BALANCE_PLOT_DEFAULTS .. py:class:: BalanceOfPlantPlotter(**kwargs) The plotting object for the BalanceOfPlant system. Builds a relatively complicated Sankey diagram, connecting the various flows of energy in the reactor. .. py:attribute:: plot_options .. py:method:: _scale_flows(flow_dict: dict[str, list[float]]) -> dict[str, list[float]] .. py:method:: plot(flow_dict: dict[str, list[float]], title: str = '') -> matplotlib.axes.Axes Plots the BalanceOfPlant system, based on the inputs and flows. :param flow_dict: The dictionary of flows for each of the Sankey diagrams. :type flow_dict: dict :returns: the plot axis .. py:method:: _build_diagram(flow_dict: dict[str, list[float]], sankey: SuperSankey) -> SuperSankey Builds the Sankey diagram. This is much more verbose than looping over some structs, but that's how it used to be and it was hard to modify. This is easier to read and modify. :returns: The Sankey diagram object .. py:method:: _polish(fig: matplotlib.figure.Figure, sankey: SuperSankey) Finish up and polish figure, and format text