:py:mod:`cowpatch` ================== .. py:module:: cowpatch Package Contents ---------------- Classes ~~~~~~~ .. autoapisummary:: cowpatch.layout cowpatch.area cowpatch.patch Attributes ~~~~~~~~~~ .. autoapisummary:: cowpatch.rcParams .. py:class:: layout(ncol=None, nrow=None, byrow=None, rel_widths=None, rel_heights=None, design=None) layout class to store information about arangement of patches found in `cow.patch`. :param ncol: Integer for the number of columns to arrange the the patches in. The default is None (which avoids conflicts if a value for `design` is provided). If ``ncol`` is None but ``nrow`` is not, then ``ncol`` will default to the minimum number of columns to make sure that all patches can be visualized. :type ncol: integer :param nrow: Integer for the number of rows to arrange the the patches in. The default is None (which avoids conflicts if a value for ``design`` is provided). If ``nrow`` is None but ``ncol`` is not, then ``nrow`` will default to the minimum number of rows to make sure that all patches can be visualized. :type nrow: integer :param byrow: If ``ncol`` and/or ``nrow`` is included, then this boolean indicates if the patches should be ordered by row (default if ``byrow`` is None or when parameter is ``True``) or by column (if ``byrow`` was ``False``). :type byrow: boolean :param design: Specification of the location of each patch in the arrangement. Can either be a float numpy array with integers between 0 and the number of patches to arrange, or a text string that captures similar ideas to the array approach but uses capital alphabetical characters (A-Z) to indicate each figure. More information is in Notes. :type design: np.array (float based) or str :param rel_widths: Numerical vector of relative columns widths. This not required, the default would be ``np.ones(ncol)`` or ``np.ones(design.shape[0])``. Note that this is a relative sizing and the values are only required to be non-negative, non-zero values, for example ``[1,2]`` would would make the first column twice as wide as the second column. :type rel_widths: list, np vector or tuple :param rel_heights: Numerical vector of relative row heights. This not required, the default would be ``np.ones(nrow)`` or ``np.ones(design.shape[1])``. Note that this is a relative sizing and the values are only required to be non-negative, non-zero values, for example ``[1,2]`` would would make the first row twice as tall as the second row. :type rel_heights: list or tuple .. rubric:: Notes *Design* The ``design`` parameter expects specific input. 1. If the ``design`` is input as a numpy array, we expect it to have integers only (0 to # patches-1). It is allowed to have ``np.nan`` values if certain "squares" of the layout are not covered by others (the covering is defined by the value ordering). Note that we won't check for overlap and ``np.nan`` is not enforced if another patches' relative (min-x,min-y) and (max-x, max-y) define a box over that ``np.nan``'s area. An example of a design of the numpy array form could look like >>> my_np_design = np.array([[1,1,2], ... [3,3,2], ... [3,3,np.nan]]) 2. if the ``design`` parameter takes in a string, we expect it to have a structure such that each line (pre ``\\n``) contains the same number of characters, and these characters must come from the first (number of patches) capital alphabetical characters or the ``\#`` or ``.`` sign to indicate an empty square. Similar arguments w.r.t. overlap and the lack of real enforcement for empty squares applies (as in 1.). An example of a design of the string form could look like >>> my_str_design = """ ... AAB ... CCB ... CC\# ... """ or >>> my_str_design = """ ... AAB ... CCB ... CC. ... """ See the `Layout guide`_ for more detailed examples of functionality. .. _Layout guide: https://benjaminleroy.github.io/cowpatch/guides/Layout.html *Similarities to our `R` cousins:* This layout function is similar to `patchwork\:\:plot_layout `_ (with a special node to ``design`` parameter) and helps perform similar ideas to `gridExtra\:\:arrangeGrob `_'s ``layout_matrix`` parameter, and `cowplot\:\:plot_grid `_'s ``rel_widths`` and ``rel_heights`` parameters. .. rubric:: Examples >>> # Necessary libraries for example >>> import numpy as np >>> import cowpatch as cow >>> import plotnine as p9 >>> import plotnine.data as p9_data >>> g0 = p9.ggplot(p9_data.mpg) +\ ... p9.geom_bar(p9.aes(x="hwy")) +\ ... p9.labs(title = 'Plot 0') >>> g1 = p9.ggplot(p9_data.mpg) +\ ... p9.geom_point(p9.aes(x="hwy", y = "displ")) +\ ... p9.labs(title = 'Plot 1') >>> g2 = p9.ggplot(p9_data.mpg) +\ ... p9.geom_point(p9.aes(x="hwy", y = "displ", color="class")) +\ ... p9.labs(title = 'Plot 2') >>> g3 = p9.ggplot(p9_data.mpg[p9_data.mpg["class"].isin(["compact", ... "suv", ... "pickup"])]) +\ ... p9.geom_histogram(p9.aes(x="hwy"),bins=10) +\ ... p9.facet_wrap("class") >>> # design matrix >>> vis_obj = cow.patch(g1,g2,g3) >>> vis_obj += cow.layout(design = np.array([[0,1], ... [2,2]])) >>> vis_obj.show() >>> # design string >>> vis_obj2 = cow.patch(g1,g2,g3) >>> vis_obj2 += cow.layout(design = """ ... AB ... CC ... """) >>> vis_obj2.show() >>> # nrow, ncol, byrow >>> vis_obj3 = cow.patch(g0,g1,g2,g3) >>> vis_obj3 += cow.layout(nrow=2, byrow=False) >>> vis_obj3.show() >>> # rel_widths/heights >>> vis_obj = cow.patch(g1,g2,g3) >>> vis_obj += cow.layout(design = np.array([[0,1], ... [2,2]]), ... rel_widths = np.array([1,2])) >>> vis_obj.show() .. seealso:: :obj:`area` object class that helps ``layout`` define where plots will go in the arangement :obj:`patch` fundamental object class which is combined with ``layout`` to defin the overall arangement of plots .. py:attribute:: design defines underlying ``design`` attribute (potentially defined relative to a ``cow.patch`` object if certain structure are not extremely specific. .. py:class:: area(x_left, y_top, width, height, _type) object that stores information about what area a ``patch`` will fill :param x_left: scalar of where the left-most point of the patch is located (impacted by the ``_type`` parameter) :type x_left: float :param y_top: scalar of where the top-most point of the patch is located (impacted by the ``_type`` parameter) :type y_top: float :param width: scalar of the width of the patch (impacted by the ``_type`` parameter) :type width: float :param height: scalar of the height of the patch (impacted by the ``_type`` parameter) :type height: float :param _type: describes how the parameters are stored. See Notes for more information between the options. :type _type: str {"design", "relative", "pt"} .. rubric:: Notes These objects provide structural information about where in the overall arangement individual plots / sub arangments lie. The ``_type`` parameter informs how to understand the other parameters: 1. "design" means that the values are w.r.t. to a design matrix relative to the `layout` class, and values are relative to the rows and columns units. 2. "relative" means the values are defined relative to the full size of the canvas and taking values between 0-1 (inclusive). 3. "pt" means that values are defined relative to point values .. seealso:: :obj:`layout` object that incorporates multiple area definitions to define layouts. .. py:method:: pt(width_pt=None, height_pt=None, rel_widths=None, rel_heights=None) Translates area object to ``_type`` = "pt" :param width_pt: width in points (required if ``_type`` is not "pt") :type width_pt: float :param height_pt: height in points (required if ``_type`` is not "pt") :type height_pt: float :param rel_widths: list of relative widths of each column of the layout matrix (required if ``_type`` is "design") :type rel_widths: np.array (vector) :param rel_heights: list of relative heights of each row of the layout matrix (required if ``_type`` is "design") :type rel_heights: np.array (vector) :returns: area object of ``_type`` = "pt" :rtype: area object .. py:class:: patch(*args, grobs=None) fundamental object of `cowpatch`, encapsulates plot objects and can be told how to present them :param \*args: all non-named parameters are expected to be plot objects or lower-level ``cow.patch`` objects. :type \*args: plot objects and patches :param grobs: list of plot objects and patches. Either ``\*args`` is empty or ``grobs`` is ``None``. :type grobs: list .. rubric:: Notes *Guiding arangement:* In combination with ``cow.layout`` one can define arrangement of plots and lower-level arangements. For example, >>> vis_obj = cow.patch(g1,g2,g3) >>> vis_obj += cow.layout(design = np.array([[0,1], ... [2,2]])) >>> vis_obj.show() See the `Layout guide`_ for more detailed examples of functionality. .. _Layout guide: https://benjaminleroy.github.io/cowpatch/guides/Layout.html *Nesting:* One can nest `cow.patch` objects within other `cow.patch` objects. For example, >>> vis_obj2 = cow.patch(g4, vis_obj) >>> vis_obj2 += cow.layout(nrow = 1) >>> vis_obj2.show() .. rubric:: Examples >>> # Necessary libraries for example >>> import numpy as np >>> import cowpatch as cow >>> import plotnine as p9 >>> import plotnine.data as p9_data >>> g0 = p9.ggplot(p9_data.mpg) +\ ... p9.geom_bar(p9.aes(x="hwy")) +\ ... p9.labs(title = 'Plot 0') >>> g1 = p9.ggplot(p9_data.mpg) +\ ... p9.geom_point(p9.aes(x="hwy", y = "displ")) +\ ... p9.labs(title = 'Plot 1') >>> g2 = p9.ggplot(p9_data.mpg) +\ ... p9.geom_point(p9.aes(x="hwy", y = "displ", color="class")) +\ ... p9.labs(title = 'Plot 2') >>> g3 = p9.ggplot(p9_data.mpg[p9_data.mpg["class"].isin(["compact", ... "suv", ... "pickup"])]) +\ ... p9.geom_histogram(p9.aes(x="hwy"),bins=10) +\ ... p9.facet_wrap("class") >>> # Basic example: >>> vis_obj = cow.patch(g0,g1,g2) >>> vis_obj += cow.layout(design = np.array([[0,1], ... [2,2]])) >>> vis_obj.show() >>> # Nesting example: >>> vis_obj2 = cow.patch(g3, vis_obj) >>> vis_obj2 += cow.layout(nrow = 1) >>> vis_obj2.show() .. seealso:: :obj:`layout` class objects that can aid in defining the layout of plots in ``cow.patch`` objects .. py:method:: layout() :property: defines ``layout`` that either returns the last added ``cow.layout`` object or the default ``layout`` if no layout has been explicitly defined .. py:method:: save(filename, width=None, height=None, dpi=96, _format=None, verbose=None) save patch to file :param filename: local string to save the file to (this can also be at a ``io.BytesIO``) :type filename: str :param width: width of output image in inches (this should actually be associated with the svg...) :type width: float :param height: height of svg in inches (this should actually be associated with the svg...) :type height: float :param dpi: dots per square inch, default is 96 (standard) :type dpi: int or float :param _format: string of format (error tells options). If provided this is the format used, if None, then we'll try to use the ``filename`` extension. :type _format: str :param verbose: If ``True``, print the saving information. The package default is defined by cowpatch's own rcParams (the base default is ``True``), which is used if verbose is ``None``. See Notes. :type verbose: bool :returns: saves to a file :rtype: None .. rubric:: Notes If width and/or height is None, the approach will attempt to define acceptable width and height. The ``verbose`` parameter can be changed either directly with defining ``verbose`` input parameter or changing ``cow.rcParams["save_verbose"]``. .. seealso:: :obj:`io.BytesIO` object that acts like a reading in of bytes .. py:method:: show(width=None, height=None, dpi=96, verbose=None) display object from the command line or in a jupyter notebook :param width: width of output image in inches (this should actually be associated with the svg...) :type width: float :param height: height of svg in inches (this should actually be associated with the svg...) :type height: float :param dpi: dots per square inch, default is 96 (standard) :type dpi: int or float :param verbose: If ``True``, print the saving information. The package default is defined by cowpatch's own rcParams (the base default is ``True``), which is used if verbose is ``None``. See Notes. :type verbose: bool .. rubric:: Notes If width and/or height is None, the approach will attempt to define acceptable width and height. The ``verbose`` parameter can be changed either directly with defining ``verbose`` input parameter or changing ``cow.rcParams["show_verbose"]``. If run from the command line, this approach leverage matplotlib's plot render to show a static png version of the image. If run inside a jupyter notebook, this approache presents the actual svg representation. .. py:data:: rcParams underlying parameters of that control the generation of the actual images maxIter : int maximum number of iterations to be used to convert a plotnine ggplot object output into the correct size min_size_px : int early stopping rule for conversion a plotnine ggplot object output into the correct size, if size of image goes below this value the process stops with an error eps : float difference between desired and converged sizes to successfully stop the interation for the conversion a plotnine ggplot object output into the correct size save_verbose : boolean logic if saving a cow.patch arangement (with .save) is is done so verbosely as a default (can be overridden) show_verbose : boolean logic if showing a cow.patch arangement (with .show) is is done so verbosely as a default (can be overridden) num_attempts : int Number of attempts to correct the global size of the arangment to allow the plotnine ggplot objects to have the expected sizes with desired aspect ratio. Minimum value is 1, which means no correction is made. base_height : float inches for the minimum height of a plotnine ggplot object if no global height of the arrangement is provided in the `.show()` and `.save()` functions. base_aspect_ratio : float ratio that (along with base_height) defines underlying minimum width of a plotnine ggplot object if no global width of the arrangement is provided in the `.show()` and `.save()` functions. This ratio is the golden ratio.