GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Multivariate plotting in imshow, pcolor and pcolormesh by trygvrad · Pull Request #29221 · matplotlib/matplotlib

Conversation

@trygvrad

@trygvrad trygvrad commented Dec 3, 2024

Copy link
Copy Markdown
Contributor

PR summary

This PR continues the work of #28658 and #28454, aiming to close #14168.

Features included in this PR:

  1. A MultiNorm class. This is a subclass of colors.Normalize and holds n_variate norms.
  2. Exposes the functionality provided by MultiNorm together with BivarColormap and MultivarColormap to the plotting functions axes.imshow(...), axes.pcolor, and `axes.pcolormesh(...)
import matplotlib.pyplot as plt
import numpy as np

im_A = np.arange(500)[np.newaxis, :]*np.ones((100, 500))
im_B = np.arange(100)[:, np.newaxis]*np.ones((100, 500))
im_A[:, :] = np.sin(im_A**0.5)**2
im_B[:, :] = np.sin(im_B**0.5)**2

fig, axes = plt.subplots(3, 1, figsize=(8, 6))

cm = axes[0].imshow(im_A, cmap='grey', vmin=0, vmax=1)
axes[0].set_title('A')

cm = axes[1].imshow(im_B, cmap='grey', vmin=0, vmax=1)
axes[1].set_title('B')

cm = axes[2].imshow((im_A, im_B),
                    cmap='BiOrangeBlue',
                    vmin=(0, 0), vmax=(1, 1))
axes[2].set_title('A & B')
for ax in axes:
    ax.set_xticks([])
    ax.set_yticks([])

image


Features not included in this PR:

  • Multivariate equivalent of fig.colorbar(...). I will make a draft for this, but I may need help with regards to the layout engine.
  • Examples. Some documentation is ready on a separate branch, see this, and this, but the PR that includes these will be made after we find a fig.colorbar(...) solution for bivariate/multivariate colormaps.
  • A selection of colormaps. I have written about this here and here. You can see the proposed colormaps/documentation here and [here](file:///home/trygvrad/trygvrad.github.io/mpl_docs/Bivariate colormap reference.html), but we will need a separate discussion on these (in particular regarding the names)
  • The multivariate implementation for axes.imshow(...) included here only accepts interpolation_stage=='rgba', and not interpolation_stage=='data'.

PR checklist

  • "closes Feature request: Bivariate colormapping #14168", but I suggest we keep Feature request: Bivariate colormapping #14168 open until we have a fig.colorbar(...) equivalent for multivariate colormaps.
  • new and changed code is tested
  • Plotting related features are demonstrated in an example
  • New Features and API Changes are noted with a directive and release note
  • Documentation complies with general and docstring guidelines

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@github-actions github-actions Bot added topic: color/color & colormaps topic: images topic: collections and mappables labels Dec 3, 2024
@trygvrad

trygvrad commented Dec 3, 2024

Copy link
Copy Markdown
Contributor Author

Also: this does not (yet) include changes to the docstrings, i.e. the following will need to change:

"""

Parameters
----------
X : array-like or PIL image
    The image data. Supported array shapes are:

    - (M, N): an image with scalar data. The values are mapped to
      colors using normalization and a colormap. See parameters *norm*,
      *cmap*, *vmin*, *vmax*.
    - (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
    - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
      i.e. including transparency.

    The first two dimensions (M, N) define the rows and columns of
    the image.

    Out-of-range RGB(A) values are clipped.
"""

to include a line like

"""
etc.
    - (K, M, N): multiple images with scalar data when combined with a
    multivariate or bivariate colormap using a MultiNorm.
"""
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This was referenced Dec 13, 2024
2D Normalization & Colormapping for ScalerMappables #8738
Closed
Wishlist: Multidimensional colormaps #4369
Closed
@github-actions github-actions Bot added the status: needs rebase label Dec 20, 2024
@github-actions github-actions Bot added the Documentation: API files in lib/ and doc/api label Jan 6, 2025
@trygvrad
trygvrad force-pushed the multivariate-norm branch from 5afd692 to 90680bd Compare January 6, 2025 08:56
@github-actions github-actions Bot removed the status: needs rebase label Jan 6, 2025
@trygvrad
trygvrad force-pushed the multivariate-norm branch from 90680bd to 206c9b8 Compare January 6, 2025 10:52
@trygvrad

trygvrad commented Jan 6, 2025

Copy link
Copy Markdown
Contributor Author

I updated the docstrings, so now this PR should be ready for review.

There is an error with the docs on circleci, but I haven't found a link between the error and the changes made in this PR, so I believe it to be unrelated.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@tacaswell tacaswell modified the milestones: v3.10.0-doc, v3.11.0 Jan 23, 2025
story645
story645 reviewed Jan 28, 2025
View reviewed changes
Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/cbook.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/colorizer.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/colors.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/colors.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/colors.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/tests/test_multivariate_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/tests/test_multivariate_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added status: needs rebase topic: transforms and scales labels Feb 1, 2025
@trygvrad
trygvrad force-pushed the multivariate-norm branch from d4215a3 to e30e7e6 Compare February 8, 2025 10:18
@github-actions github-actions Bot removed the status: needs rebase label Feb 8, 2025
@trygvrad

trygvrad commented Feb 8, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

@story645
Thank you for the feedback :)
I believe I have addressed all the comments now (I'll mark them as resolved in the coming days).

also: this will need a squash-merge

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@trygvrad
trygvrad force-pushed the multivariate-norm branch from e30e7e6 to f936378 Compare February 20, 2025 19:18
tacaswell
tacaswell reviewed Feb 20, 2025
View reviewed changes
Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

tacaswell
tacaswell reviewed Feb 20, 2025
View reviewed changes
Comment thread lib/matplotlib/axes/_axes.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

tacaswell
tacaswell reviewed Feb 20, 2025
View reviewed changes
Comment thread lib/matplotlib/colorizer.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

tacaswell
tacaswell reviewed Feb 20, 2025
View reviewed changes
Comment thread lib/matplotlib/colorizer.py
# pass scalar data
# and already formatted data
return data
elif data.dtype in [np.complex64, np.complex128]:

@tacaswell tacaswell Feb 20, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Option 1 please.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/matplotlib/colors.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/image.py
if A.ndim == 3 and A.shape[-1] == 1:
A = A.squeeze(-1) # If just (M, N, 1), assume scalar and apply colormap.
if not (A.ndim == 2 or A.ndim == 3 and A.shape[-1] in [3, 4]):
if A.ndim == 3 and A.shape[0] == 2:

@tacaswell tacaswell Feb 20, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to verify, these are here as a hint to the user to use multi-variate color maps and data that would have failed before would still fail now?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trygvrad trygvrad Feb 23, 2025

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is the intention

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/matplotlib/image.py
raise TypeError(f"Image data of dtype {A.dtype} cannot be "
f"converted to float")
else:
for key in A.dtype.fields:

@tacaswell tacaswell Feb 20, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this fails to catch n_input >1 + non-float-like + non-structured data?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trygvrad trygvrad Feb 23, 2025

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be true.
I'm trying to think of a data type that can not be cast to float and is not structured in order to test this

If you try something with data type object, it depends a bit on the shape, all the cases I have tried have been caught:

fig, ax = plt.subplots()

im = np.empty((5,5), dtype='object')
ax.imshow(im, cmap='BiOrangeBlue')
> ValueError: Invalid data entry for mutlivariate data. The data must contain complex numbers, or have a first dimension 2, or be of a dtype with 2 fields

im = np.empty((2,5,5), dtype='object')
ax.imshow(im, cmap='BiOrangeBlue')
> TypeError: Image data of dtype [('f0', 'O'), ('f1', 'O')] cannot be converted to a sequence of floats

Where the first error originates in colorizer._ensure_multivariate_data()

Do you have some idea of other tests I should run, or do we want to have specific tests for _normalize_image_array()?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread lib/matplotlib/image.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread lib/matplotlib/image.py Outdated
Check validity of image-like input *A* and normalize it to a format suitable for
Image subclasses.
"""
A = mcolorizer._ensure_multivariate_data(n_input, A)

@tacaswell tacaswell Feb 20, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor thing. bit jarring that sometimes the API in f(n_input, A) and othertimes f(A, n_input). I think we should prefer f(A, n_input) everywhere for internal consistency and no-API change on existing functions (like the one we are in now).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trygvrad trygvrad Feb 23, 2025

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good comment :) I will try to address it soon

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@trygvrad trygvrad Feb 24, 2025

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the call signature of colorizer._ensure_multivariate_data(...) to colorizer._ensure_multivariate_data(A, n_input)

I looked to see if there were any other functions with a similar signature which should be flipped, but I did not find any in my quick search.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@trygvrad
trygvrad force-pushed the multivariate-norm branch from 63e789a to 7fc99b5 Compare February 24, 2025 21:18
@story645

story645 commented Feb 27, 2025

Copy link
Copy Markdown
Member

If you've got the bandwidth, @greglucas can you give this a look (skim) since you've been working on colormapping?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the status: needs rebase label Feb 28, 2025
@trygvrad
trygvrad force-pushed the multivariate-norm branch from 7fc99b5 to dc6dee7 Compare March 9, 2025 15:45
@story645 story645 assigned anntzer Mar 27, 2025
@trygvrad

trygvrad commented Mar 27, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

@story645 @tacaswell would you two be willing to finish your review of this?
Or perhaps @ksunden?

EDIT: my apologies @story645 I didn't see you had just assigned this when I wrote my comment :)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@story645

story645 commented Apr 1, 2025

Copy link
Copy Markdown
Member

@anntzer asked if the more cleanup/refactor/not directly necessary for implementation parts of this PR could be spun off into a different set and if this PR could get rebased to clean up the commit history.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@anntzer

anntzer commented Apr 1, 2025

Copy link
Copy Markdown
Contributor

(Just to give an example, I'm currently splitting off #29807 into a bunch of smaller preparatory PRs: #29817, #29828, #29838, #29843, #29829.)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@trygvrad

trygvrad commented Apr 1, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

@anntzer I'll see what I can do.
I thinking of splitting it as:

1. MultiNorm class
2a. Add support for multivariate pcolor and pcolormesh + tests 
2b. Add support for multivariate imshow + tests

I'll also see if there are some misc changes that can be a separate PR between 1 and 2.
In any case, 1. will have to be merged before 2a and b. Would you like me to make all the branches at once, or does it make more sense to make the PR for 2a and b once 1. is merged?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@anntzer

anntzer commented Apr 2, 2025

Copy link
Copy Markdown
Contributor

I guess it doesn't really matter, because we know the end result thanks to this PR anyways.
(I won't be able to review anything before next week, in any case.)

trygvrad reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This was referenced Apr 6, 2025
MultiNorm class #29876
Merged
Preparations for multivariate plotting #29877
Closed
@trygvrad

trygvrad commented Apr 6, 2025

Copy link
Copy Markdown
Contributor Author

@anntzer @story645 I opened PRs:
#29876 → The MultiNorm class
#29877 → Other changes needed to expose the functionality.

Hopefully this is easier to review :)

anntzer reacted with thumbs up emoji story645 reacted with heart emoji
All reactions
  • 👍 1 reaction
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

trygvrad and others added 12 commits April 13, 2025 13:13
@trygvrad
MultiNorm class
1ad6e44
@trygvrad
Multivariate plots for imshow, pcolor and pcolormesh
b00cf92
@trygvrad
docstrings for multivariate plotting in imshow, pcolor and pcolormesh
7755c90
@trygvrad
Additional tests for colors.MultiNorm
65f41c0
@trygvrad
Incorporating feedback from @story645
5bab105
@trygvrad
Fix for mouseover image data with a MultiNorm
63d606f
If an image is shown, and the user hovers over the image, the value at that coordinate should be displayed. The number formating is handled by colorizer.Colorizer._format_cursor_data_override(). This is now updated to also handle the case where a MultiNorm is used (i.e. a bivariat or multivariate colormap), in which case multiple values are displayed.
@trygvrad
More feedback from @story645
5189e61
@trygvrad
updated test for im.format_cursor_data
86c46a4
The previous version of this test passed for numpy 1.x but not for 2.x. This should pass for both
@trygvrad @tacaswell
Apply suggestions from tacaswell
e63aa3d
Co-authored-by: Thomas A Caswell <[email protected]>
@trygvrad
updated test image multivariate_imshow_alpha.png due to a fix for alp…
cbb1979
…ha in imshow
@trygvrad
change call signature of colorizer._ensure_multivariate_data()
e1ee7dc
changed from  colorizer._ensure_multivariate_data(n_input, A)
to  colorizer._ensure_multivariate_data(A, n_input)
@trygvrad
updated reference images in response to fix on main
fa40bef
@trygvrad
trygvrad force-pushed the multivariate-norm branch from 29093b3 to fa40bef Compare April 13, 2025 11:40
@github-actions github-actions Bot added the status: needs rebase label May 13, 2025
@trygvrad trygvrad added this to Bivariate and Multivariate Colormapping Jul 3, 2025
@trygvrad trygvrad moved this to Superseded in Bivariate and Multivariate Colormapping Jul 3, 2025
@QuLogic

QuLogic commented Oct 2, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

@trygvrad moved this to Superseded in Bivariate and Multivariate Colormapping on Jul 3

Should this be closed if it's superseded?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@trygvrad

trygvrad commented Oct 4, 2025

Copy link
Copy Markdown
Contributor Author

@trygvrad moved this to Superseded in Bivariate and Multivariate Colormapping on Jul 3

Should this be closed if it's superseded?

Yes :)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@trygvrad trygvrad closed this Oct 4, 2025
@github-project-automation github-project-automation Bot moved this from Superseded to Done in Bivariate and Multivariate Colormapping Oct 4, 2025
@QuLogic QuLogic added the status: superseded label Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@tacaswell tacaswell tacaswell left review comments
@story645 story645 story645 left review comments

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@story645 story645

@anntzer anntzer

Labels

Documentation: API files in lib/ and doc/api status: needs rebase status: superseded topic: collections and mappables topic: color/color & colormaps topic: images topic: transforms and scales

Projects

Bivariate and Multivariate Colormapping
Status: Done

Milestone

v3.11.0

Development

Successfully merging this pull request may close these issues.

Feature request: Bivariate colormapping

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@trygvrad @story645 @anntzer @QuLogic @tacaswell
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.