Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Draft for multivariate and bivariate colormaps#26996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading.Please reload this page.
Conversation
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.
Thank you for opening your first PR into Matplotlib!
If you have not heard from us in a week or so, please leave a new comment below and that should bring it to our attention. Most of our reviewers are volunteers and sometimes things fall through the cracks.
You can also join uson gitter for real-time discussion.
For details on testing, writing docs, and our review process, please seethe developer guide
We strive to be a welcoming and open project. Please follow ourCode of Conduct.
@@ -1249,6 +1249,103 @@ def colorbar( | |||
cax.figure.stale = True | |||
return cb | |||
def colorbars(self, mappable, shape=(-1, -1), fraction_per_row=0.15, pad=0.05, |
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 see this is just a placeholder, butcolorbars
seems too close tocolorbar
. Could this bemultivariate_colorbars
?
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.
Agreed.multivariate_colorbars
would definitely work, or alternativelymultivar_colorbars
if we want it a bit shorter.
'variate' is quite a long word, and it has made sense to me to shorten it to 'var' in some cases.
However, looking at it now I think it is more important that we are consistent (which I have not really been so far, with functions such asensure_multivariate_norm
and classes likeMultivarColormap
).
09d734f
to92b49df
Compare…ormapVectorMappable cannot be an iterable because it messes up flattening of the artist treematplotlib.multivar_colormapsworking pcolormeshpm = axes[0].pcolormesh((A,B,C), cmap = '3VarSubA')works, and all tests passDuplicate signals are merged merged:when calling functions in VectorMappable that causes multiple scalarmappables to update, 'changed' is now only emitted one time by VectorMappableAdded ensure_cmap() so that cmap always has a variable n_variates that can be used to evaluate the shape of the input dataalso added working implementation of bivariate colormaps with square and circular cliphtml representation of multivariate cmaplint for flake8very basic fig.colorbars() and fig.colorbar_2d()renamed fn to ensure_multivariate_normerror messages for multivariate colormapsfix for resmapling of 2d colormaps (to reduce file size)trying to get imshow to workfixed TypeError in imshow with wrong shapefix for test_format_cursor_data in test_imagefix for imshow with bivariate colormap
When a logNorm is used, values <= 0 are masked.This commit lets masked arrays work with multivariate and bivaraite colormaps.This intersects with alpha (when alpha is set), and this commit addresses this.
Added test for multivar vmin, vmax, norm and alpha.
added support for multivariate/bivaraite colormaps in pcolor
Changes to allow PatchCollection to use a bivariate/multivariate colormaps.This is important because choropleth maps are often based on PatchCollection objects.
Cleanup to allow checking of input when clim or norm is reset on a vectormappabletests wrong mulrivar input
removed code redundancy
cleanup errors not needed
fix for _repr_html_ for bivariate colormaps with shape='circle'
Previously, the following code would give an error.cmap = mpl.bivar_colormaps['BiOrangeBlue']cmap((1.0,1.0))because calling a mpl.bivar_colormaps() assumed a 2D array.Same issue for mpl.multivar_colormaps
Previously, the shape of bivariate colormaps was only respected when they were attached to a scalarmappable, but now cm.BivarColormap.__call__() includes the code to enforce the shape ('square', 'circle', etc.)
fixes in documentation syntaxfixes to documentation syntax for correct rendering in sphinx
fix to fig.colorbar_2D() so that it works correctly with not-yet-scaled datafix to fig.colorbar_2D() so that it works correctly with various norms (colors.LogNorm, etc.)fix to fig.colorbars() so that it it only works with multivariate colorbars
92b49df
tocc81df7
CompareMinor updates to .pyi files for multivariate and bivariate
ef16916
to945dc75
Compare
Uh oh!
There was an error while loading.Please reload this page.
PR summary
This draft PR is a reply to#14168 Feature request: Bivariate colormapping
The context of this draft PR is the discussion thread for#14168 and the weekly meeting Sep 15th 2023.
It was suggested that a class
VectorMappable
should be a drop-in replacement forScalarMappable
.And it would be of interest to see how
VectorMappable
and multivariate colormaps can be threaded through the existing api.It was further suggested that the new functionality should be triggered by providing a multivariate or bivariate colormap.
This ensures that the new functionality is only triggered when the user showsintent.
This draft PR is intended to allow for further discussion of#14168 at the next few weekly meetings.
The following functionality is supported:
Multivariate colormaps:
(data fromhttps://arxiv.org/abs/1812.10366)
Bivariate colormaps:
Minimum changes required
This implementation is designed to make minimal changes to the existing code.
I have tried to list the significant changes bellow:
cm.VectorMappable
is a drop in replacement forcm.ScalarMappable
.VectorMappable
uses delegation and contains one or moreScalarMappables
(.scalars
).A new function
axes._base.ensure_cmap(cmap)
is added.ensure_cmap(cmap)
takes a colormap, string or None and returns aColormap
,MultivarColormap
, orBivarColormap
object.None will always return the default (1D) colormap. i.e. to use bivariate or multivariate data, the user must show intent by actively choosing a suitable colormap.
A new function
axes._base.ensure_multivariate_norm(n_variates, data, norm, vmin, vmax)
is added.When called, this ensures that
data
,norm
,vmin
, andvmax
all have lengthn_variates
. Single arguments are repeated if neccessary.The new member varaible
n_variates
is accessible on allColormap
,BivarColormap
, andMultivarColormap
objects. It is 1, 2 or n, respectively.Figure.pcolormesh()
is adapted to support multivariate data by the following four changes:collections.Collection
now inherits fromcm.VectorMappable
instead ofcm.ScalarMappable
cmap = ensure_cmap(cmap)
is called immediately inFigure.pcolormesh()
. This gives access tocmap.n_variates
.cmap.n_variates > 1
, the functionensure_multivariate_norm()
is called to ensure the correct length of the norm parametersaxes._pcolorargs()
takes an additional keyword argument (n_variates
), so that ifn_variates > 1
, it can correctly extract the dimensions from the input data.Implementation of multivariate and bivariate colormaps
Multivariate data (2-8 variates) is supported vi the class
colors.MultivarColormap
.MultivarColormap
is iterable, and iterating onMultivarColormap
returns (1D) Colormap objects.MultivarColormap.combination_mode
is either'Add'
or'Sub'
, and this determines if the colormaps are are combined by adding or subtracting the RGB values.The file
_cm_listed_multivar
contains new 1D colormaps to bulid the multivariate colormaps.The multivariate colormaps are contained in a
cm.ColormapRegistry()
accessible atmpl.multivar_colormaps
2D colormaps are supported via the class
colors.BivarColormap
.There are two subclasses:
SegmentedBivarColormap
andBivarColormapFromImage
SegmentedBivarColormap
repurposes_image.resample()
to extrapolate a smaller image to a larger image. By using this we do not need to store the full (256,256,3) LUT in the source files, but can get away with (65,65,3) for complex colormaps or (9,9,3) for more simple colormaps with no significant loss in fidelity.BivarColormap.shape
is either'square'
or'circle'
. This changes how values outside the colormap are interpolated onto the colormap.The bivariate colormaps are contained in a
cm.ColormapRegistry()
accessible atmpl.bivar_colormaps
Further work
There are a number of further topics that need to be worked on to make this more than a draft PR (as lited below).
However I think it would be conducive to first discuss the points above, and whether the design desicions made so far, are sensible.
Figure.colorbars()
andFigure.colorbar_2D()
.These are only for illustration purposes, and will need to be completely rewritten, and we need to think about return types.
scatter, hexbin, imshow, pcolor, pcolorfast, specgram, contour, contourf, hist2d, matshow
, others?].Figure.colorbars()/Figure.colorbar_2D()
with various placement options, norms etc.PR checklist