dandelion.polars.plotting.clone_circlepackplot

dandelion.polars.plotting.clone_circlepackplot(data, group_by, palette=None, figsize=(8, 8), title=None, min_clone_size=1, clone_key=None, show_group_labels=True, show_clone_labels=False, show_count_labels=False, alpha=0.6, show_legend=None, legend_kwargs={'bbox_to_anchor': (1, 0.5), 'frameon': False, 'loc': 'center left'}, as_subplots=False, n_col=None, n_row=None, scale_subplots=True, scale_factor=None, outer_ring_color=None, show_enclosure_label=True, max_clones_per_group=None, aggregate_by_size=False, packer='circlify')[source]

A bubble plot to visualise clone sizes within groups using circle packing.

Each group (e.g. sample, celltype) is represented as an enclosing circle, with clones within that group shown as packed inner circles sized proportionally to clone size.

When group_by is a list the hierarchy follows the list order: the first element is the outermost ring, subsequent elements are nested rings, and clone circles sit at the innermost level. Each level is coloured independently using its own colour map.

Parameters:
  • data (AnnData | DandelionPolars) – DandelionPolars or AnnData object.

  • group_by (str | list[str]) – Column name(s) in metadata to group clones by. A single string gives one level of nesting; a list gives multi-level nesting in list order (e.g. ['sample_id', 'celltype']).

  • palette (str | dict | None, optional) – Colour specification.

    • None (default): for DandelionPolars objects, uses "Set2" for every level; for AnnData objects, each column is looked up in adata.uns (e.g. uns["leiden_colors"]) and falls back to scanpy’s default palette cycle when the key is absent.

    • str: a seaborn palette name applied uniformly to every level.

    • dict: a nested mapping where each key is a column name from group_by and each value is either a {category: colour} dict or a list of colours assigned in category order (respecting .cat.categories for categoricals, numeric sort order, or alphabetical otherwise). Missing columns or values are auto-assigned. Examples for group_by=["A", "B"]:

      palette={"A": {"x": "red", "y": "blue"}, "B": {"x": "green"}}
      palette={"A": ["red", "blue"], "B": ["green", "orange"]}
      
  • figsize (tuple[float, float], optional) – Figure size. When as_subplots=True this is interpreted as the size of each individual subplot panel.

  • title (str | None, optional) – Title of plot.

  • min_clone_size (int, optional) – Minimum clone size to include. Set to 2 to exclude singletons.

  • clone_key (str | None, optional) – Column name for clones. None defaults to ‘clone_id’.

  • show_group_labels (bool, optional) – Whether to annotate each group enclosure with its label.

  • show_clone_labels (bool, optional) – Whether to annotate each clone circle with its clone ID.

  • show_count_labels (bool, optional) – Whether to annotate each circle with its cell count.

  • alpha (float, optional) – Transparency of clone circles.

  • show_legend (str | list[str] | None, optional) – Controls which group_by levels appear in the legend.

    • None (default): show all levels.

    • str: show only that level (e.g. "isotype").

    • list[str]: show only those levels.

    • False: hide the legend entirely.

  • legend_kwargs (dict, optional) – Keyword arguments forwarded to ax.legend.

  • as_subplots (bool, optional) – If True, split the figure into one subplot per top-level group (the first element of group_by). The subplots are tiled according to n_col and n_row.

  • n_col (int | None, optional) – Number of subplot columns when as_subplots=True. If None, defaults to 4 when there are more than 4 subplots, otherwise the number of subplots. Ignored when as_subplots=False.

  • n_row (int | None, optional) – Number of subplot rows when as_subplots=True. If None, computed automatically from n_col. Ignored when as_subplots=False.

  • scale_subplots (bool, optional) – When as_subplots=True, scale each subplot’s enclosing circle so that its area is proportional to its total cell count relative to the largest subplot. This keeps circle sizes visually comparable across panels: a clone of size n always occupies the same area regardless of which subplot it appears in. Uniform axis limits are applied to all subplots. Has no effect when as_subplots=False. Default True.

  • scale_factor (float | None, optional) – Direct multiplier on the enclosure radius. Larger values produce larger circles; smaller values produce smaller circles. Applies in both as_subplots=True and as_subplots=False modes.

    • None (default): in single-panel mode the enclosure fills the panel (radius = 1.0); in subplot mode the radius is determined by scale_subplots alone.

    • float: the enclosure radius is set to scale_factor in single-panel mode, or multiplied by scale_factor on top of the scale_subplots auto-computed radius in subplot mode. Axes are fixed to [-1.05, 1.05] so relative sizes remain visually meaningful. Values < 1 shrink circles; values > 1 enlarge them.

  • outer_ring_color (str | None, optional) – If set, all outermost group rings (depth-0 circles in single-panel mode and the enclosing ring in each subplot) are drawn in this single colour instead of their level-0 palette colour. Any valid matplotlib colour string is accepted (e.g. "black", "#333333"). None (default) preserves per-group colouring from palette.

  • show_enclosure_label (bool, optional) – Whether to display the total cell count below each enclosing group ring. Only has an effect when show_count_labels=True. Default True.

  • max_clones_per_group (int | None, optional) – If set, only the top-N largest clones within each leaf group are drawn. Clones are ranked by size (descending) and any beyond the N-th are silently dropped before packing. Useful for keeping very large groups readable. None (default) includes all clones that pass min_clone_size.

  • aggregate_by_size (bool, optional) – When True, instead of drawing one circle per clone, clones are grouped into buckets by their size. Each bucket becomes a single circle whose area is proportional to clone_size × number_of_clones (total cells in that bucket). The circle label is "n=<size>" and, when show_count_labels=True, the annotation reads "<size>\n(<total_cells>)". This greatly reduces the number of circles for samples with many small clones and gives a compact overview of the size distribution. Default False.

  • packer ({“circlify”, “packcircles”}, optional) – Circle-packing backend to use.

    • "circlify" (default): uses the circlify library, which produces deterministic, aesthetically balanced layouts.

    • "packcircles": uses the packcircles library, which applies an iterative overlap-removal algorithm. Leaf-level circles are packed with packcircles; enclosing group circles are still laid out by circlify. Requires pip install packcircles.

Return type:

tuple[Figure, Axes] | tuple[Figure, list[Axes]]

Returns:

  • tuple[Figure, Axes] – Circle-packing bubble plot (when as_subplots=False).

  • tuple[Figure, list[Axes]] – Figure and list of per-group axes (when as_subplots=True).

Raises:
  • ValueError – If no clones remain after filtering by min_clone_size.

  • ValueError – If packer is not "circlify" or "packcircles".