@@ -1286,9 +1286,20 @@ def _render_images(
12861286 ),
12871287 )
12881288
1289- # True if user gave n cmaps for n channels
1290- got_multiple_cmaps = isinstance (render_params .cmap_params , list )
1291- if got_multiple_cmaps :
1289+ # A list of cmap_params can be either user-supplied (one cmap per channel) or
1290+ # synthesized upstream to carry per-channel norms when the user only set `norm`
1291+ # (or `palette + norm=list`). The synthesized form must not trigger the
1292+ # blending warning or conflict with `palette`.
1293+ if isinstance (render_params .cmap_params , list ):
1294+ got_multiple_cmaps = True
1295+ user_supplied_multi_cmaps = any (not cp .cmap_is_default for cp in render_params .cmap_params )
1296+ if len (render_params .cmap_params ) != n_channels :
1297+ raise ValueError ("If 'cmap' is provided, its length must match the number of channels." )
1298+ else :
1299+ got_multiple_cmaps = False
1300+ user_supplied_multi_cmaps = False
1301+
1302+ if user_supplied_multi_cmaps :
12921303 logger .warning (
12931304 "You're blending multiple cmaps. "
12941305 "If the plot doesn't look like you expect, it might be because your "
@@ -1297,10 +1308,6 @@ def _render_images(
12971308 "Consider using 'palette' instead."
12981309 )
12991310
1300- # not using got_multiple_cmaps here because of ruff :(
1301- if isinstance (render_params .cmap_params , list ) and len (render_params .cmap_params ) != n_channels :
1302- raise ValueError ("If 'cmap' is provided, its length must match the number of channels." )
1303-
13041311 # Detect RGB(A) images by channel names — skip when user overrides with palette/cmap
13051312 is_rgb , has_alpha = _is_rgb_image (channels )
13061313 has_explicit_cmap = (
@@ -1527,8 +1534,9 @@ def _render_images(
15271534 zorder = render_params .zorder ,
15281535 )
15291536
1530- # 2C) Image has n channels and palette info
1531- elif palette is not None and not got_multiple_cmaps :
1537+ # 2C) palette set; also covers `palette + norm=list` since synthesized
1538+ # default cmaps don't conflict and per-channel norms are already in `layers`.
1539+ elif palette is not None and not user_supplied_multi_cmaps :
15321540 if len (palette ) != n_channels :
15331541 raise ValueError ("If 'palette' is provided, its length must match the number of channels." )
15341542
@@ -1567,10 +1575,6 @@ def _render_images(
15671575 zorder = render_params .zorder ,
15681576 )
15691577
1570- # 2D) Image has n channels, no palette but cmap info
1571- elif palette is not None and got_multiple_cmaps :
1572- raise ValueError ("If 'palette' is provided, 'cmap' must be None." )
1573-
15741578 # Collect channel legend entries (single point for all multi-channel paths)
15751579 if render_params .channels_as_legend and channel_legend_entries is not None :
15761580 if legend_colors is not None :
0 commit comments