Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork8.1k
Multivar imshow#30597
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?
Multivar imshow#30597
Conversation
1efde4a to35746f5Compare…how, pcolor, pcolormesh, and Collection
| iflen(x.dtype.descr)==1: | ||
| # Arrays with dtype 'object' get returned here. | ||
| # For example the 'c' kwarg of scatter, which supports multiple types. | ||
| # `plt.scatter([3, 4], [2, 5], c=[(1, 0, 0), 'y'])` | ||
| returnx | ||
| else: | ||
| # In case of a dtype with multiple fields | ||
| # for example image data using a MultiNorm | ||
| try: | ||
| mask=np.empty(x.shape,dtype=np.dtype('bool, '*len(x.dtype.descr))) | ||
| fordd,dminzip(x.dtype.descr,mask.dtype.descr): | ||
| mask[dm[0]]=~np.isfinite(x[dd[0]]) | ||
| xm=np.ma.array(x,mask=mask,copy=False) | ||
| exceptTypeError: | ||
| returnx | ||
| returnxm |
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.
Does this get recycled in other places and if so should it be factored into it;s own private function?
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 don't think this is used anywhere else
lib/matplotlib/axes/_axes.py Outdated
| Only 'data' is available when using `~matplotlib.colors.BivarColormap` | ||
| or `~matplotlib.colors.MultivarColormap` |
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.
what do you mean by data?
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.
'data' refers to the keyword argumentinterpolation_stage
interpolation_stage : {'auto', 'data', 'rgba'}, default: 'auto' Supported values: - 'data': Interpolation is carried out on the data provided by the user This is useful if interpolating between pixels during upsampling. - 'rgba': The interpolation is carried out in RGBA-space after the color-mapping has been applied. This is useful if downsampling and combining pixels visually. - 'auto': Select a suitable interpolation stage automatically. This uses 'rgba' when downsampling, or upsampling at a rate less than 3, and 'data' when upsampling at a higher rate. See :doc:`/gallery/images_contours_and_fields/image_antialiasing` for a discussion of image antialiasing. Only 'data' is available when using `~matplotlib.colors.BivarColormap` or `~matplotlib.colors.MultivarColormap`I'm changing the last lines to:
When using a `~matplotlib.colors.BivarColormap` or `~matplotlib.colors.MultivarColormap`, 'data' is the only valid interpolation_stage.in an attempt to increase clarity
lib/matplotlib/axes/_axes.py Outdated
| C : 2Dor 3Darray-like | ||
| The color-mapped values. Color-mapping is controlled by *cmap*, | ||
| *norm*, *vmin*, and *vmax*. | ||
| *norm*, *vmin*, and *vmax*. 3D arrays are supported only if the | ||
| cmap supports v channels, where v is the size along the first axis. | ||
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 (?, ?, ?) notation might help make this clearer?
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.
good idea. Does the following work for you?
Parameters ---------- C : 2D (I, J) or 3D (v, I, J) array-like The color-mapped values. Color-mapping is controlled by *cmap*, *norm*, *vmin*, and *vmax*. 3D arrays are supported only if the cmap supports v channels. X, Y : array-like, optional The coordinates of the corners of quadrilaterals of a pcolormesh:: (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1]) ●╶───╴● │ │ ●╶───╴● (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1]) Note that the column index corresponds to the x-coordinate, and the row index corresponds to y. For details, see the :ref:`Notes <axes-pcolormesh-grid-orientation>` section below. If ``shading='flat'`` the dimensions of *X* and *Y* should be one greater than those of *C*, and the quadrilateral is colored due to the value at ``C[i, j]``. If *X*, *Y* and *C* have equal dimensions, a warning will be raised and the last row and column of *C* will be ignored.I'm using uppercase I and J inC : 2D (I, J) or 3D (v, I, J) array-like as these refer to the length, while the lowercase versions are used further down for the corresponding indexes.
lib/matplotlib/axes/_axes.py Outdated
| ifcolorizerisNone: | ||
| cmap=mcolorizer._ensure_cmap(cmap,accept_multivariate=True) | ||
| C=mcolorizer._ensure_multivariate_data(args[-1],cmap.n_variates) | ||
| else: | ||
| C=mcolorizer._ensure_multivariate_data(args[-1], | ||
| colorizer.cmap.n_variates) |
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.
| ifcolorizerisNone: | |
| cmap=mcolorizer._ensure_cmap(cmap,accept_multivariate=True) | |
| C=mcolorizer._ensure_multivariate_data(args[-1],cmap.n_variates) | |
| else: | |
| C=mcolorizer._ensure_multivariate_data(args[-1], | |
| colorizer.cmap.n_variates) | |
| ifcolorizerisNone: | |
| cmap=mcolorizer._ensure_cmap(cmap,accept_multivariate=True) | |
| colorizer= | |
| C=mcolorizer._ensure_multivariate_data(args[-1], | |
| colorizer.cmap.n_variates) |
is there a reason to not instantiate the colorizer here?
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 believe it was designed this way to ensure error handling was done in the same way as previously, but I was able to rework it to a cleaner state by doing
mcolorizer.ColorizingArtist._check_exclusionary_keywords(colorizer, vmin=vmin, vmax=vmax, norm=norm, cmap=cmap)before the creation of the QuadMesh rather than
collection._check_exclusionary_keywords(colorizer, vmin=vmin, vmax=vmax)after.
| ifcolorizerisNone: | ||
| cmap=mcolorizer._ensure_cmap(cmap,accept_multivariate=True) | ||
| C=mcolorizer._ensure_multivariate_data(args[-1],cmap.n_variates) | ||
| else: | ||
| C=mcolorizer._ensure_multivariate_data(args[-1], | ||
| colorizer.cmap.n_variates) | ||
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.
potentially turn into a helper function if it repeats?
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.
The following lines are repeated for pcolor and pcolormesh:
mcolorizer.ColorizingArtist._check_exclusionary_keywords(colorizer,vmin=vmin,vmax=vmax,norm=norm,cmap=cmap)ifcolorizerisNone:colorizer=mcolorizer.Colorizer(cmap=cmap,norm=norm)C=mcolorizer._ensure_multivariate_data(args[-1],colorizer.cmap.n_variates)
We could make this a helper function :)
If so, should it be part of the Axes class? and do you have a suggestion for a name?
EDIT: this is after modifying it in accordance with one of your comments above :)
| fig,axes=plt.subplots(2,3) | ||
| # interpolation='nearest' to reduce size of baseline image | ||
| axes[0,0].imshow(x_1,interpolation='nearest',alpha=0.5) |
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.
are the other interpolations tested?
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.
Nope!,
I'm changing one of tests so that it is :)
lib/matplotlib/image.py Outdated
| raiseValueError("'data' is the only valid interpolation_stage " | ||
| "when using multiple color channels, not " | ||
| f"{interpolation_stage}") |
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.
flip this around to start with the error then reason then solution
lib/matplotlib/image.py Outdated
| A_resampled= [_resample(self,a.astype(_get_scaled_dtype(a)), | ||
| out_shape,t) | ||
| forainarrs] |
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.
| A_resampled= [_resample(self,a.astype(_get_scaled_dtype(a)), | |
| out_shape,t) | |
| forainarrs] | |
| A_resampled= [_resample(self, | |
| a.astype(_get_scaled_dtype(a)),out_shape,t) | |
| forainarrs] |
just that the line break here is weird
lib/matplotlib/image.py Outdated
| mask= (np.where(self._getmaskarray(A),np.float32(np.nan), | ||
| np.float32(1)) |
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.
| mask= (np.where(self._getmaskarray(A),np.float32(np.nan), | |
| np.float32(1)) | |
| mask= (np.where(self._getmaskarray(A),np.float32(np.nan),np.float32(1)) |
lib/matplotlib/image.py Outdated
| returnfig | ||
| def_get_scaled_dtype(A): |
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.
make it an inline function inside _make_image
ksunden left a comment
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.
General thoughts on return types:
Doing things likefloat | tuple[float, ...] as is done for several things here (vmin/vmax, clip, etc) is potentially problematic.
Humans may easily work with that, but type checkers will likely yell that they didn't check for all possible outcomes
None is a bit of a special case in being more acceptable (easier to check, etc)
Consider moving these in new code toalways return a tuple (even if single element) This keeps the branching needed to a minimum and is nottoo cumbersome to work for in the single variable case.
Obviously, existing APIs need to maintain back-compat, so this is limited to new code.
Consider whether conceptually an empty tuple is what is truly meant by theNone case, but if it is not, retainNone
| vmin:float|tuple[float]|None= ..., | ||
| vmax:float|tuple[float]|None= ..., |
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.
| vmin:float|tuple[float]|None= ..., | |
| vmax:float|tuple[float]|None= ..., | |
| vmin:float|tuple[float, ...]|None= ..., | |
| vmax:float|tuple[float, ...]|None= ..., |
| vmin:float|tuple[float]|None= ..., | ||
| vmax:float|tuple[float]|None= ..., |
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.
| vmin:float|tuple[float]|None= ..., | |
| vmax:float|tuple[float]|None= ..., | |
| vmin:float|tuple[float, ...]|None= ..., | |
| vmax:float|tuple[float, ...]|None= ..., |
| vmin:float|tuple[float]|None= ..., | ||
| vmax:float|tuple[float]|None= ..., |
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.
| vmin:float|tuple[float]|None= ..., | |
| vmax:float|tuple[float]|None= ..., | |
| vmin:float|tuple[float, ...]|None= ..., | |
| vmax:float|tuple[float, ...]|None= ..., |
| defnorm(self)->colors.Norm: ... | ||
| @norm.setter | ||
| defnorm(self,norm:colors.Norm|str|None)->None: ... | ||
| defnorm(self,norm:colors.Norm|str|tuple[str]|None)->None: ... |
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.
tuple[str, ...]
| vmin:float|tuple[float]|None=None, | ||
| vmax:float|tuple[float]|None=None, |
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.
| vmin:float|tuple[float]|None=None, | |
| vmax:float|tuple[float]|None=None, | |
| vmin:float|tuple[float, ...]|None=None, | |
| vmax:float|tuple[float, ...]|None=None, |
| vmin:float|tuple[float]|None=None, | ||
| vmax:float|tuple[float]|None=None, |
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.
| vmin:float|tuple[float]|None=None, | |
| vmax:float|tuple[float]|None=None, | |
| vmin:float|tuple[float, ...]|None=None, | |
| vmax:float|tuple[float, ...]|None=None, |
| vmin:float|tuple[float]|None=None, | ||
| vmax:float|tuple[float]|None=None, |
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.
| vmin:float|tuple[float]|None=None, | |
| vmax:float|tuple[float]|None=None, | |
| vmin:float|tuple[float, ...]|None=None, | |
| vmax:float|tuple[float, ...]|None=None, |
Uh oh!
There was an error while loading.Please reload this page.
Exposes the functionality of
MultiNorm,BivarColormapandMultivarColormapto the top level plotting functionsax.imshow(),ax.pcolor()andax.pcolormesh(). This coloses#30526, seeBivariate and Multivariate ColormappingAs a side-effect of the pcolor/pcolormesh implementation,
Collectionalso gets the new functionality.In short, this PR allows you to plot multivariate data more easily, but it does not:
These will come in later PRs. SeeBivariate and Multivariate Colormapping
Examples demonstrating new functionality: