Skip to content

Per-point size array is cumulatively reordered across multi-color subplots #4024

@Marius1311

Description

@Marius1311

Per-point size array is cumulatively reordered across multi-color subplots

Bug description

When calling sc.pl.embedding (or sc.pl.umap, etc.) with multiple color keys and a per-point size array, the marker sizes are incorrect in all subplots after the first.

The root cause is in scatterplots.py (line 299): the size variable is reordered in-place within the per-color loop, but the reordered result carries over to the next iteration:

for count, (value_to_plot, dims) in enumerate(zip(color, dimensions, strict=True)):
    ...
    order = ...  # computed from this color's values
    if isinstance(size, np.ndarray):
        size = np.array(size)[order]  # mutates the loop variable!

Each subplot computes its own order for z-ordering, but applies it to the already-reordered size from the previous iteration. This means:

  • Subplot 1: correct sizes
  • Subplot 2: sizes scrambled by order_1 ∘ order_2
  • Subplot 3: sizes scrambled by order_1 ∘ order_2 ∘ order_3
  • etc.

Note that color_source_vector, color_vector, and coords don't have this problem because they are freshly computed from adata / basis_values each iteration.

Reproduction

import scanpy as sc
import numpy as np

adata = sc.datasets.pbmc3k_processed()
sizes = np.random.default_rng(0).uniform(10, 200, size=adata.n_obs)
sc.pl.umap(adata, color=["louvain", "n_genes", "n_counts"], size=sizes)
# Dot sizes visibly differ across the three panels despite being the same array

Expected behavior

The same per-point size array should be applied consistently to all subplots: the i-th point should always get size[i], regardless of what z-ordering is applied.

Suggested fix

Use a loop-local variable (e.g., _size) so each iteration reorders from the original array. See PR #4023.

Versions

Confirmed on main as of commit 1fbe008d.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions