matplotlib / matplotlib/matplotlib

[ENH]: Design considerations for discrete colormapping

Open
#31,195 12 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

New feature topic: color/color & colormaps
Dominant language
Python
Stars
23.2k
Forks
8.5k
Avg merge
1d 6h
Merged PRs (30d)
66

Description

### Problem

Colormapping (or the current colorizer concept) works via the pipeline: data → [norm] → normed values → [colormap] → RGB values.

Colormap:
- primarily maps [0, 1] → RGB
- but can also map ints *0, ..., N* → RGB via indexing the *lookup table* (lut)

Norm:
- primarily maps continuous intervals to [0, 1]
- except for `BoundaryNorm`, which maps intervals specified via a sequence of interval borders → *0, ..., N*

The current colormapping/colorizer handles the discrete boundary case implicitly through the generic norm+cmap pipeline. This has a numberer of disadvantages:
- Users have to carefully tune BoundaryNorm and a colormap with appropirately many colors.
- We have some internal special casing on BoundaryNorm

### Proposed solution

Let's reconsider and generalize data-to-color-conversion. IMHO we have to conceptually distinguish the following cases:

| | **discrete colors** | **continuous colors** |
|---------------------|---------------------|-----------------------|
| **discrete data** | oridinal colorizer | N/A |
| **continuous data** | boundary colorizer | continuous colorizer |

- **continuous colorizer** is what we currently typically do with colormapping
*norm*: range → [0, 1]
*cmap*: [0, 1] → RGB
*cmap visualization*: as we currently have
- **boundary colorizer** take continuous input and maps it to discrete levels - this is what BoundaryNorm is currently for. The transfer function works like `stairs()`.
*norm*: interval borders → 1, ..., N
*cmap*: 1, ..., N → RGB
*constraint*: n_borders = n_colors + 1
*cmap visualization*: discrete colors; ticks at the borders and/or labels centered on the color patches
- **discrete colorizers** map to discrete data to discrete color values. Primary use cases will be mapping e.g. categorical data, e.g. `scatter()` or more general Collections with.
*norm*: ordinal values → 1, ..., N; optional, we could also have a direct value -> rgb mapping without a norm
*cmap*: 1, ..., N → RGB
*constraint*: n_values = n_colors;
*cmap visualization*: equal-sized discrete colors; ticks/labels centered on the color patches; alternative: colored legend for the discrete entries

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the current colormapping/colorizer pipeline and BoundaryNorm behavior described in the issue. Compare the proposed continuous, boundary, and discrete colorizer cases, including their constraints and visualization needs. Done would require an agreed design and implementation scope, which the issue does not yet define.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
data-visualization
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.