Problem
In multi-panel figures (multiple coordinate systems, or scanpy-style color=[...]), each panel's colorbar/legend is drawn outside the panel via inset_axes anchored to the right of ax.transAxes. When panels get small (grids, constrained canvases), the colorbar/legend — and especially its tick labels — spill into the adjacent panel.
This is most visible when several panels each carry their own colorbar (continuous) or legend (categorical): the left panel's colorbar collides with the right panel's y-axis labels.
Root cause
_draw_colorbar in pl/basic.py places the colorbar with:
cax = inset_axes(spec.ax, ..., bbox_to_anchor=(1 + pad, 0, fraction, 1), bbox_transform=spec.ax.transAxes)
i.e. outside the panel's cell. No layout engine reserves that space, so it overflows the neighbour. Categorical legends are similarly placed in the right margin.
How scanpy avoids this
scanpy reserves the colorbar/legend space inside each panel's own cell (steals from the axes), so it can never overflow:
- Continuous:
plt.colorbar(cax, ax=ax, pad=0.01, fraction=0.08, aspect=30, location=...) — ax=ax shrinks the panel and places the colorbar in the reclaimed space.
- Categorical (multi-panel): shrink the axis first, then add the legend in the freed space:
box = ax.get_position(); ax.set_position([box.x0, box.y0, box.width * 0.91, box.height])
Proposed fix
Switch the colorbar subsystem to space-stealing plt.colorbar(ax=ax, location=, fraction=, pad=) and adopt the shrink-then-place pattern for categorical legends. This makes both single- and multi-panel layouts robust at any figure size.
Note: library-wide rendering change — affects every colorbar/legend and requires regenerating a large set of visual baselines. Preserve the existing public knobs (location left/right/top/bottom, colorbar_params, same-side stacking, alpha, label).
Discovered while implementing #611 (multi-panel color=[...]).
Problem
In multi-panel figures (multiple coordinate systems, or scanpy-style
color=[...]), each panel's colorbar/legend is drawn outside the panel viainset_axesanchored to the right ofax.transAxes. When panels get small (grids, constrained canvases), the colorbar/legend — and especially its tick labels — spill into the adjacent panel.This is most visible when several panels each carry their own colorbar (continuous) or legend (categorical): the left panel's colorbar collides with the right panel's y-axis labels.
Root cause
_draw_colorbarinpl/basic.pyplaces the colorbar with:i.e. outside the panel's cell. No layout engine reserves that space, so it overflows the neighbour. Categorical legends are similarly placed in the right margin.
How scanpy avoids this
scanpy reserves the colorbar/legend space inside each panel's own cell (steals from the axes), so it can never overflow:
plt.colorbar(cax, ax=ax, pad=0.01, fraction=0.08, aspect=30, location=...)—ax=axshrinks the panel and places the colorbar in the reclaimed space.Proposed fix
Switch the colorbar subsystem to space-stealing
plt.colorbar(ax=ax, location=, fraction=, pad=)and adopt the shrink-then-place pattern for categorical legends. This makes both single- and multi-panel layouts robust at any figure size.Note: library-wide rendering change — affects every colorbar/legend and requires regenerating a large set of visual baselines. Preserve the existing public knobs (location left/right/top/bottom,
colorbar_params, same-side stacking, alpha, label).Discovered while implementing #611 (multi-panel
color=[...]).