Example #1
0
def hfss_plot_convergences_report(convergence_t: pd.core.frame.DataFrame,
                                  convergence_f: pd.core.frame.DataFrame,
                                  fig: mpl.figure.Figure = None,
                                  _display=True):
    """Plot convergence frequency vs. pass number if fig is None.
    Plot delta frequency and solved elements vs. pass number.
    Plot delta frequency vs. solved elements.

    Args:
        convergence_t (pandas.core.frame.DataFrame): Convergence vs pass number of the eigenemode freqs.
        convergence_f (pandas.core.frame.DataFrame): Convergence vs pass number of the eigenemode freqs.
        fig (matplotlib.figure.Figure, optional): A mpl figure. Defaults to None.
        _display (bool, optional): Display the plot? Defaults to True.
    """

    if fig is None:
        fig = plt.figure(figsize=(11, 3.))

        # Grid spec and axes;    height_ratios=[4, 1], wspace=0.5
        gs = mpl.gridspec.GridSpec(1, 3, width_ratios=[1.2, 1.5, 1])
        axs = [fig.add_subplot(gs[i]) for i in range(3)]

        ax0t = axs[1].twinx()
        plot_convergence_f_vspass(axs[0], convergence_f)
        plot_convergence_max_df(axs[1], convergence_t.iloc[:, 1])
        plot_convergence_solved_elem(ax0t, convergence_t.iloc[:, 0])
        plot_convergence_maxdf_vs_sol(axs[2], convergence_t.iloc[:, 1],
                                      convergence_t.iloc[:, 0])

        fig.tight_layout(w_pad=0.1)  # pad=0.0, w_pad=0.1, h_pad=1.0)
Example #2
0
def style_figure(fig: matplotlib.figure.Figure, title: str, bottom: float = 0.2) -> None:
    """Stylize the supplied matplotlib Figure instance."""
    fig.tight_layout()
    if bottom is not None:
        fig.subplots_adjust(bottom=bottom)
    fig.suptitle(title)
    fig.legend(ncol=10, handlelength=0.75, handletextpad=0.25, columnspacing=0.5, loc='lower left')
def fig_square(fig: mpl.figure.Figure) -> None:
    """Adjust figure width so that it is square, and tight layout.

    Parameters
    ----------
    fig : mpl.figure.Figure
        `Figure` instance.
    """
    fig.set_size_inches(mpl.figure.figaspect(1))
    fig.tight_layout()
Example #4
0
    def apply(self, fig: matplotlib.figure.Figure) -> None:
        # It shouldn't hurt to align the labels if there's only one.
        fig.align_ylabels()

        # Adjust the layout.
        fig.tight_layout()
        adjust_default_args = dict(
            # Reduce spacing between subplots
            hspace=0,
            wspace=0,
            # Reduce external spacing
            left=0.10,
            bottom=0.105,
            right=0.98,
            top=0.98,
        )
        adjust_default_args.update(self.edge_padding)
        fig.subplots_adjust(**adjust_default_args)
Example #5
0
    def plot_convergences(self,
                          convergence_t: pd.DataFrame = None,
                          convergence_f: pd.DataFrame = None,
                          fig: mpl.figure.Figure = None,
                          _display: bool = True):
        """Creates 3 plots, useful to determin the convergence achieved by the renderer:
        * convergence frequency vs. pass number if fig is None.
        * delta frequency and solved elements vs. pass number.
        * delta frequency vs. solved elements.

        Args:
            convergence_t (pd.DataFrame): Convergence vs pass number of the eigenemode freqs.
            convergence_f (pd.DataFrame): Convergence vs pass number of the eigenemode freqs.
            fig (matplotlib.figure.Figure, optional): A mpl figure. Defaults to None.
            _display (bool, optional): Display the plot? Defaults to True.
        """

        if convergence_t is None:
            convergence_t = self.convergence_t
        if convergence_f is None:
            convergence_f = self.convergence_f

        if fig is None:
            fig = plt.figure(figsize=(11, 3.))

            # Grid spec and axes;    height_ratios=[4, 1], wspace=0.5
            gspec = mpl.gridspec.GridSpec(1, 3, width_ratios=[1.2, 1.5, 1])
            axs = [fig.add_subplot(gspec[i]) for i in range(3)]

            ax0t = axs[1].twinx()
            plot_convergence_f_vspass(axs[0], convergence_f)
            plot_convergence_max_df(axs[1], convergence_t.iloc[:, 1])
            plot_convergence_solved_elem(ax0t, convergence_t.iloc[:, 0])
            plot_convergence_maxdf_vs_sol(axs[2], convergence_t.iloc[:, 1],
                                          convergence_t.iloc[:, 0])

            fig.tight_layout(w_pad=0.1)  # pad=0.0, w_pad=0.1, h_pad=1.0)
Example #6
0
def _trends_helper(
    adata: AnnData,
    models: Dict[str, Dict[str, Any]],
    gene: str,
    ln_key: str,
    lineage_names: Optional[Sequence[str]] = None,
    same_plot: bool = False,
    sharey: Union[str, bool] = False,
    show_ylabel: bool = True,
    show_lineage: bool = True,
    show_xticks_and_label: bool = True,
    lineage_cmap=None,
    abs_prob_cmap=cm.viridis,
    gene_as_title: bool = False,
    legend_loc: Optional[str] = "best",
    fig: mpl.figure.Figure = None,
    axes: Union[mpl.axes.Axes, Sequence[mpl.axes.Axes]] = None,
    **kwargs,
) -> None:
    """
    Plot an expression gene for some lineages.

    Parameters
    ----------
    %(adata)s
    %(model)s
    gene
        Name of the gene in `adata.var_names``.
    ln_key
        Key in ``adata.obsm`` where to find the lineages.
    lineage_names
        Names of lineages to plot.
    same_plot
        Whether to plot all lineages in the same plot or separately.
    sharey
        Whether the y-axis is being shared.
    show_ylabel
        Whether to show y-label on the y-axis. Usually, only the first column will contain the y-label.
    show_lineage
        Whether to show the lineage as the title. Usually, only first row will contain the lineage names.
    show_xticks_and_label
        Whether to show x-ticks and x-label. Usually, only the last row will show this.
    lineage_cmap
        Colormap to use when coloring the the lineage. If `None`, use colors from ``adata.uns``.
    abs_prob_cmap:
        Colormap to use when coloring in the absorption probabilities, if they are being plotted.
    gene_as_title
        Whether to use the gene names as titles (with lineage names as well) or on the y-axis.
    legend_loc
        Location of the legend. If `None`, don't show any legend.
    fig
        Figure to use.
    ax
        Ax to use.
    **kwargs
        Keyword arguments for :meth:`cellrank.ul.models.BaseModel.plot`.

    Returns
    -------
    %(just_plots)s
    """

    n_lineages = len(lineage_names)
    if same_plot:
        axes = [axes] * len(lineage_names)

    fig.tight_layout()
    axes = np.ravel(axes)

    percs = kwargs.pop("perc", None)
    if percs is None or not isinstance(percs[0], (tuple, list)):
        percs = [percs]

    same_perc = False  # we need to show colorbar always if percs differ
    if len(percs) != n_lineages or n_lineages == 1:
        if len(percs) != 1:
            raise ValueError(
                f"Percentile must be a collection of size `1` or `{n_lineages}`, got `{len(percs)}`."
            )
        same_perc = True
        percs = percs * n_lineages

    hide_cells = kwargs.pop("hide_cells", False)
    show_cbar = kwargs.pop("show_cbar", True)

    if same_plot:
        lineage_colors = (
            lineage_cmap.colors
            if lineage_cmap is not None and hasattr(lineage_cmap, "colors")
            else adata.uns.get(f"{_colors(ln_key)}", cm.Set1.colors)
        )
    else:
        lineage_colors = (
            "black" if not mcolors.is_color_like(lineage_cmap) else lineage_cmap
        )

    for i, (name, ax, perc) in enumerate(zip(lineage_names, axes, percs)):
        if same_plot:
            if gene_as_title:
                title = gene
                ylabel = "expression" if show_ylabel else None
            else:
                title = ""
                ylabel = gene
        else:
            if gene_as_title:
                title = None
                ylabel = "expression" if i == 0 else None
            else:
                title = (
                    (name if name is not None else "no lineage") if show_lineage else ""
                )
                ylabel = gene if i == 0 else None

        models[gene][name].plot(
            ax=ax,
            fig=fig,
            perc=perc,
            show_cbar=False,
            title=title,
            hide_cells=hide_cells or (same_plot and i == n_lineages - 1),
            same_plot=same_plot,
            lineage_color=lineage_colors[i]
            if same_plot and name is not None
            else lineage_colors,
            abs_prob_cmap=abs_prob_cmap,
            ylabel=ylabel,
            **kwargs,
        )
        if sharey in ("row", "all", True) and i == 0:
            plt.setp(ax.get_yticklabels(), visible=True)

        if show_xticks_and_label:
            plt.setp(ax.get_xticklabels(), visible=True)
        else:
            ax.set_xlabel(None)

    if not same_plot and same_perc and show_cbar and not hide_cells:
        vmin = np.min([models[gene][ln].w_all for ln in lineage_names])
        vmax = np.max([models[gene][ln].w_all for ln in lineage_names])
        norm = mcolors.Normalize(vmin=vmin, vmax=vmax)

        for ax in axes:
            [
                c
                for c in ax.get_children()
                if isinstance(c, mpl.collections.PathCollection)
            ][0].set_norm(norm)

        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="2.5%", pad=0.1)
        _ = mpl.colorbar.ColorbarBase(
            cax, norm=norm, cmap=abs_prob_cmap, label="absorption probability"
        )

    if same_plot and lineage_names != [None] and legend_loc is not None:
        ax.legend(lineage_names, loc=legend_loc)
Example #7
0
def _trends_helper(
    models: Dict[str, Dict[str, Any]],
    gene: str,
    transpose: bool = False,
    lineage_names: Optional[Sequence[str]] = None,
    same_plot: bool = False,
    sharey: Union[str, bool] = False,
    show_ylabel: bool = True,
    show_lineage: Union[bool, np.ndarray] = True,
    show_xticks_and_label: Union[bool, np.ndarray] = True,
    lineage_cmap: Optional[Union[mpl.colors.ListedColormap, Sequence]] = None,
    lineage_probability_color: Optional[str] = None,
    abs_prob_cmap=cm.viridis,
    gene_as_title: bool = False,
    legend_loc: Optional[str] = "best",
    fig: mpl.figure.Figure = None,
    axes: Union[mpl.axes.Axes, Sequence[mpl.axes.Axes]] = None,
    **kwargs,
) -> None:
    """
    Plot an expression gene for some lineages.

    Parameters
    ----------
    %(adata)s
    %(model)s
    gene
        Name of the gene in `adata.var_names``.
    ln_key
        Key in ``adata.obsm`` where to find the lineages.
    lineage_names
        Names of lineages to plot.
    same_plot
        Whether to plot all lineages in the same plot or separately.
    sharey
        Whether the y-axis is being shared.
    show_ylabel
        Whether to show y-label on the y-axis. Usually, only the first column will contain the y-label.
    show_lineage
        Whether to show the lineage as the title. Usually, only first row will contain the lineage names.
    show_xticks_and_label
        Whether to show x-ticks and x-label. Usually, only the last row will show this.
    lineage_cmap
        Colormap to use when coloring the the lineage. When ``transpose``, this corresponds to the color of genes.
    lineage_probability_color
        Actual color of 1 ``lineage``. Only used when ``same_plot=True`` and ``transpose=True`` and
        ``lineage_probability=True``.
    abs_prob_cmap:
        Colormap to use when coloring in the absorption probabilities, if they are being plotted.
    gene_as_title
        Whether to use the gene names as titles (with lineage names as well) or on the y-axis.
    legend_loc
        Location of the legend. If `None`, don't show any legend.
    fig
        Figure to use.
    ax
        Ax to use.
    **kwargs
        Keyword arguments for :meth:`cellrank.ul.models.BaseModel.plot`.

    Returns
    -------
    %(just_plots)s
    """

    n_lineages = len(lineage_names)
    if same_plot:
        axes = [axes] * len(lineage_names)

    fig.tight_layout()
    axes = np.ravel(axes)

    percs = kwargs.pop("perc", None)
    if percs is None or not isinstance(percs[0], (tuple, list)):
        percs = [percs]

    same_perc = False  # we need to show colorbar always if percs differ
    if len(percs) != n_lineages or n_lineages == 1:
        if len(percs) != 1:
            raise ValueError(
                f"Percentile must be a collection of size `1` or `{n_lineages}`, got `{len(percs)}`."
            )
        same_perc = True
        percs = percs * n_lineages

    hide_cells = kwargs.pop("hide_cells", False)
    show_cbar = kwargs.pop("cbar", True)
    show_prob = kwargs.pop("lineage_probability", False)

    if same_plot:
        if not transpose:
            lineage_colors = (lineage_cmap.colors if lineage_cmap is not None
                              and hasattr(lineage_cmap, "colors") else
                              lineage_cmap)
        else:
            # this should be fine w.r.t. to the missing genes, since they are in the same order AND
            # we're also passing the failed models (this is important)
            # these are actually gene colors, bu w/e
            if lineage_cmap is not None:
                lineage_colors = (
                    lineage_cmap.colors if hasattr(lineage_cmap, "colors") else
                    [c for _, c in zip(lineage_names, lineage_cmap)])
            else:
                lineage_colors = _create_categorical_colors(n_lineages)
    else:
        lineage_colors = (("black" if not mcolors.is_color_like(lineage_cmap)
                           else lineage_cmap), ) * n_lineages

    if n_lineages > len(lineage_colors):
        raise ValueError(
            f"Expected at least `{n_lineages}` colors, found `{len(lineage_colors)}`."
        )

    lineage_color_mapper = {
        ln: lineage_colors[i]
        for i, ln in enumerate(lineage_names)
    }

    successful_models = {
        ln: models[gene][ln]
        for ln in lineage_names if models[gene][ln]
    }

    if show_prob and same_plot:
        minns, maxxs = zip(*[
            models[gene][n]._return_min_max(show_conf_int=kwargs.get(
                "conf_int", False), ) for n in lineage_names
        ])
        minn, maxx = min(minns), max(maxxs)
        kwargs["loc"] = legend_loc
        kwargs["scaler"] = lambda x: (x - minn) / (maxx - minn)
    else:
        kwargs["loc"] = None

    if isinstance(show_xticks_and_label, bool):
        show_xticks_and_label = [show_xticks_and_label] * len(lineage_names)
    elif len(show_xticks_and_label) != len(lineage_names):
        raise ValueError(
            f"Expected `show_xticks_label` to be the same length as `lineage_names`, "
            f"found `{len(show_xticks_and_label)}` != `{len(lineage_names)}`.")

    if isinstance(show_lineage, bool):
        show_lineage = [show_lineage] * len(lineage_names)
    elif len(show_lineage) != len(lineage_names):
        raise ValueError(
            f"Expected `show_lineage` to be the same length as `lineage_names`, "
            f"found `{len(show_lineage)}` != `{len(lineage_names)}`.")

    last_ax = None
    ylabel_shown = False
    cells_shown = False

    for i, (name, ax, perc) in enumerate(zip(lineage_names, axes, percs)):
        model = models[gene][name]
        if isinstance(model, FailedModel):
            if not same_plot:
                ax.remove()
            continue

        if same_plot:
            if gene_as_title:
                title = gene
                ylabel = "expression" if show_ylabel else None
            else:
                title = ""
                ylabel = gene
        else:
            if gene_as_title:
                title = None
                ylabel = "expression" if not ylabel_shown else None
            else:
                title = ((name if name is not None else "no lineage")
                         if show_lineage[i] else "")
                ylabel = gene if not ylabel_shown else None

        model.plot(
            ax=ax,
            fig=fig,
            perc=perc,
            cbar=False,
            title=title,
            hide_cells=cells_shown if not hide_cells else True,
            same_plot=same_plot,
            lineage_color=lineage_color_mapper[name],
            lineage_probability_color=lineage_probability_color,
            abs_prob_cmap=abs_prob_cmap,
            lineage_probability=show_prob,
            ylabel=ylabel,
            **kwargs,
        )
        if sharey in ("row", "all", True) and not ylabel_shown:
            plt.setp(ax.get_yticklabels(), visible=True)

        if show_xticks_and_label[i]:
            plt.setp(ax.get_xticklabels(), visible=True)
        else:
            ax.set_xlabel(None)

        last_ax = ax
        ylabel_shown = True
        cells_shown = True

    if not same_plot and same_perc and show_cbar and not hide_cells:
        vmin = np.min([model.w_all for model in successful_models.values()])
        vmax = np.max([model.w_all for model in successful_models.values()])
        norm = mcolors.Normalize(vmin=vmin, vmax=vmax)

        for ax in axes:
            children = [
                c for c in ax.get_children()
                if isinstance(c, mpl.collections.PathCollection)
            ]
            if len(children):
                children[0].set_norm(norm)

        divider = make_axes_locatable(last_ax)
        cax = divider.append_axes("right", size="2%", pad=0.1)
        _ = mpl.colorbar.ColorbarBase(
            cax,
            norm=norm,
            cmap=abs_prob_cmap,
            label="absorption probability",
            ticks=np.linspace(norm.vmin, norm.vmax, 5),
        )

    if same_plot and lineage_names != [None] and legend_loc is not None:
        handles = [
            mpl.lines.Line2D([], [], color=lineage_color_mapper[ln], label=ln)
            for ln in successful_models.keys()
        ]
        last_ax.legend(handles=handles, loc=legend_loc)