Skip to content

Conversation

rwbaber
Copy link

@rwbaber rwbaber commented Aug 16, 2025

  • Closes #
  • Tests included: New tests were added for the core functionality, swap_axes compatibility, and error conditions.

Description

This PR introduces a new feature to sc.pl.dotplot: the group_cmaps parameter. This allows users to assign a unique colormap to each category in a dot plot, which is particularly useful for creating publication-ready figures that align with a paper's established color scheme for different cell types.

Key Changes

  • group_cmaps parameter: Added a new parameter to sc.pl.dotplot and the DotPlot class that accepts a dictionary mapping group names to colormap names.
  • Stacked Colorbar Legend: Implemented a new stacked horizontal colorbar legend (via _plot_stacked_colorbars function) that appears when group_cmaps is used. This legend clearly displays the colormap and for each group with corresponding label.
  • Robust Error Handling: Added a ValueError that is raised if group_cmaps is used but a group in the plot data is not defined in the dictionary.
  • Pre-existing Layout Bug Fix: Set the width of the dot plot legend area within the dotplot wrapper function to 2.0 (instead of DEFAULT_LEGENDS_WIDTH=1.5) to fix a pre-existing issue where the circles of the size legend could overlap (especially with dendrogram=True).
    • As a result, the reference images (expected.png) for several existing dotplot tests were updated to reflect the new, corrected layout.
  • Code Refactoring: The DotPlot.__init__ method was refactored into a smaller helper function (_prepare_dot_data) to improve readability and pass the automated code complexity checks by pre-commit.
  • Comprehensive Tests: Added new tests to verify the core functionality, ensure compatibility with swap_axes, and confirm that the correct errors and warnings are raised.

Example Plot

from testing.scanpy._helpers.data import (pbmc3k_processed)
import scanpy as sc

adata = pbmc3k_processed()

markers = ["SERPINB1", "IGFBP7", "GNLY", "IFITM1", "IMP3", "UBALD2", "LTB", "CLPP"]

group_cmaps = {
    "CD4 T cells":              "pink_r",
    "CD14+ Monocytes":          "Reds",
    "B cells":                  "Greys",
    "CD8 T cells":              "Greens",
    "NK cells":                 "Oranges",
    "FCGR3A+ Monocytes":        "Purples",
    "Dendritic cells":          "Blues",
    "Megakaryocytes":           "bone_r",
}

sc.pl.dotplot(
    adata,
    markers,
    groupby="louvain",
    group_cmaps=group_cmaps,  # Define custom color maps for each group from 'groupby'
    dendrogram=True,
    standard_scale='var',
    dot_max=1.0,
    title="Dot Plot with Unique Per-Group Colormaps\n(pbmc3k_processed)",
)

dotplot_pbmc

… coloring

- Adds the group_cmaps parameter to sc.pl.dotplot, allowing users to specify a unique colormap for each group.

- Implements a corresponding stacked colorbar legend (_plot_stacked_colorbars) to display the multiple colormaps, with group labels for clarity.

- Adds robust error handling, raising a ValueError if a plotted group is not defined in the group_cmaps dictionary.

- Fixes a pre-existing layout bug (dots overlapping in size legend, especially when dendrogram=True) by setting the legends width to 2.0 (compared to DEFAULT_LEGENDS_WIDTH = 1.5) inside the dotplot wrapper function.

- Refactors data preparation logic from DotPlot.__init__ into a new _prepare_dot_data helper method. This was done to improve code quality and resolve pre-commit linter errors related to complexity.

- Includes comprehensive tests for the new functionality, swap-axis compatibility, and error conditions.
@rwbaber rwbaber force-pushed the feature/dotplot-group-colors branch from b5e8003 to 6855232 Compare August 17, 2025 08:23
@flying-sheep
Copy link
Member

Good idea! However I’m concerned that the color maps aren’t visually comparable.

@rwbaber
Copy link
Author

rwbaber commented Aug 22, 2025

Thanks for the feedback! The visual comparability is a good point, I didn’t think about that.
I personally prefer your second suggestion of making (perceptually uniform) colormaps on the fly.
Though, the heatmap-like color bar could be an additional option. I think that should be fairly straightforward to implement.

Since colorspacious is unmaintained, perhaps we can check some alternatives. After a quick search, I found this post on the Oklab color space which might be another way to implement this: Converting from linear sRGB to Oklab.
I’ll look into it a bit more some other time and report back!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants