`DecisionBoundaryDisplay` with `response_method="predict"`  has inconsistent handling for the colormap in the multiclass case

### Describe the bug

This issue was discovered while reviewing #32867, but since it's not directly related, let's open a dedicated issue to avoid derailing the original discussion.

As can be seen in the plots below, passing `multiclass_colors="gist_rainbow"` has no impact when `response_method="predict"` but I don't see any reason why it wouldn't be the case.

<img width="1211" height="1211" alt="Image" src="https://github.com/user-attachments/assets/fce86173-f63b-487d-b19a-53a460ed9621" />

I think we should refactor the code to have consistent colormap configuration for all the response methods (in particular for the multiclass case).

### Steps/Code to Reproduce

```python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.inspection import DecisionBoundaryDisplay


data = np.array(
    [
        [-1, -1],
        [-2, -1],
        [1, 1],
        [2, 1],
        [2, 2],
        [3, 2],
        [3, 3],
    ]
)
target = np.arange(data.shape[0])
clf = LogisticRegression().fit(data, target)

cmap = "gist_rainbow"
_, axes = plt.subplots(nrows=3, ncols=3, figsize=(12, 12), constrained_layout=True)
for plot_method_idx, plot_method in enumerate(["contourf", "contour", "pcolormesh"]):
    for response_method_idx, response_method in enumerate(
        ["predict_proba", "decision_function", "predict"]
    ):
        ax = axes[plot_method_idx, response_method_idx]
        display = DecisionBoundaryDisplay.from_estimator(
            clf,
            data,
            multiclass_colors=cmap,
            response_method=response_method,
            plot_method=plot_method,
            ax=ax,
            alpha=0.5,
        )
        ax.scatter(
            data[:, 0],
            data[:, 1],
            c=target.astype(int),
            edgecolors="black",
            cmap=cmap,
        )
        ax.set_title(f"plot_method={plot_method}\nresponse_method={response_method}")
```

### Expected Results

I would expect the colored areas of the right most columns to also use the `"gist_rainbow"` colormap as the other columns.

### Actual Results

The right most column seems to ignore the `multiclass_colors` argument and falls back to the default "viridis" colormap which is not very well suited for multiclass problems with a large number of classes.

### Versions

```shell
System:
    python: 3.13.7 | packaged by conda-forge | (main, Sep  3 2025, 14:24:46) [Clang 19.1.7 ]
executable: /Users/ogrisel/miniforge3/envs/dev/bin/python3.13
   machine: macOS-15.6.1-arm64-arm-64bit-Mach-O

Python dependencies:
      sklearn: 1.9.dev0
          pip: 25.2
   setuptools: 80.9.0
        numpy: 2.3.3
        scipy: 1.16.3
       Cython: 3.1.4
       pandas: 3.0.0.dev0+2566.g2bb3fef887
   matplotlib: 3.10.6
       joblib: 1.5.2
threadpoolctl: 3.6.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 10
         prefix: libopenblas
       filepath: /Users/ogrisel/miniforge3/envs/dev/lib/libopenblas.0.dylib
        version: 0.3.30
threading_layer: openmp
   architecture: VORTEX

       user_api: openmp
   internal_api: openmp
    num_threads: 10
         prefix: libomp
       filepath: /Users/ogrisel/miniforge3/envs/dev/lib/libomp.dylib
        version: None
```

COMMENT:
Responding to some of the comments from #31693, as well here to have the discussion in a single place.

With regard to the 2 issues below:

> There is a detailed handling of colors using the multiclass_colors parameter, but this is only taken into account when multiclass predict_proba or decision_function are used. The distinction is made [based on the output shape](https://github.com/scikit-learn/scikit-learn/blob/bd0dd87f792ee88c8ec70248299aae779b51ac16/sklearn/inspection/_plot/decision_boundary.py#L219), and predict will always have self.response.ndim == 2, but can still be multiclass.

(from https://github.com/scikit-learn/scikit-learn/pull/31693#issuecomment-3632331775)

> What is the reason for handling colors by different parameters in the binary (currently including multiclass predict) and multiclass cases?

(From above)

I can't think of a reason why multiclass `predict` should be handled differently. I think it was an oversight as #29797 was originally about adding support for plotting of multiclass `decision_function` and `predict_probas` (`predict` was already supported), we when the `multiclass_colors` parameter was added later in the PR, we just didn't think about `predict`.

> What is the reason for handling colors by different parameters in the binary (currently including multiclass predict) and multiclass cases?

Again, just because we were thinking about multiclass. I would be happy to deprecate `multiclass_colors` for `class_colors` (or maybe `label_colors`?). Current input options:

```
        * list: list of Matplotlib
          `color <https://matplotlib.org/stable/users/explain/colors/colors.html#colors-def>`_
          strings, of length `n_classes`
        * str: name of :class:`matplotlib.colors.Colormap`
        * None: 'viridis' colormap is used to sample colors
```

I think the default `multiclass_colors` value currently ([tab10](https://matplotlib.org/stable/users/explain/colors/colormaps.html#qualitative)) would be reasonable for binary case, as the first 2 colors are blue and orange. I do think we should advise against use of a string mpl colormap for use in the binary case in the docs, but probably fine if allow it.

---

I see several issues:

1. current issue: `predict` ignores `multiclass_colors`
2. https://github.com/scikit-learn/scikit-learn/issues/32866 - mpl bug when number of classes >7, that is propagated
3.  Zooming in on an area of the plot means we calculate the responses only for a subset of the data points, which doesn't necessarily include all classes, and results in inconsistent colors: https://github.com/scikit-learn/scikit-learn/pull/31693#issuecomment-3616504984
4. `multiclass_colors` -> `class_colors` (or maybe `label_colors`?)

It seems that items 1,2,3 all would benefit from knowing the full number of classes, which we can obtain from the fitted `estimator.classes_` (and would avoid expensive calls to `np.unique`, which is done in #32867). There are 2 ways we could do this, pass number of classes (i.e. `n_responses`, which we currently use in `plot`) to `plot` (probably via class instantiation in `from_estimator`), or move the color and level logic (currently handled by `plot`) to `from_estimator`.
I think the former (passing `n_responses`/`n_classes`) to plot would be preferable (it certainly would reduce the git diff) but you may have a better feel @AnneBeyer when you implement this.

Also I think issue 1 should be addressed first - it seems a more important bug to fix, and the restructure (i.e. passing of `n_classes` would be useful for subsequent issues).

Labels: Bug, module:inspection