Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8e93d20

Browse files
committed
Bivariate works with imshow, pcolor, pcolormesh, pcolorfast
1 parent 90eae1f commit 8e93d20

File tree

2 files changed

+115
-12
lines changed

2 files changed

+115
-12
lines changed

lib/matplotlib/axes/_axes.py

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5081,12 +5081,30 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
50815081
if not self._hold:
50825082
self.cla()
50835083

5084-
if norm is not None and not isinstance(norm, mcolors.Normalize):
5085-
msg = "'norm' must be an instance of 'mcolors.Normalize'"
5084+
isNorm = isinstance(norm, (mcolors.Normalize, mcolors.BivariateNorm))
5085+
if norm is not None and not isNorm:
5086+
msg = "'norm' must be an instance of 'mcolors.Normalize' " \
5087+
"or 'mcolors.BivariateNorm'"
50865088
raise ValueError(msg)
5089+
50875090
if aspect is None:
50885091
aspect = rcParams['image.aspect']
50895092
self.set_aspect(aspect)
5093+
5094+
temp = np.asarray(X)
5095+
if (temp.ndim == 3 and isinstance(norm, mcolors.BivariateNorm) or
5096+
isinstance(cmap, mcolors.BivariateColormap)):
5097+
if cmap is None:
5098+
cmap = mcolors.BivariateColormap()
5099+
if norm is None:
5100+
norm = mcolors.BivariateNorm()
5101+
temp = norm(temp)
5102+
temp[0] = temp[0] * (cmap.N-1)
5103+
temp[1] = temp[1] * (cmap.N-1)
5104+
temp = temp.astype(int)
5105+
X = temp[0] + cmap.N * temp[1]
5106+
norm = mcolors.NoNorm()
5107+
50905108
im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent,
50915109
filternorm=filternorm, filterrad=filterrad,
50925110
resample=resample, **kwargs)
@@ -5113,7 +5131,6 @@ def imshow(self, X, cmap=None, norm=None, aspect=None,
51135131

51145132
@staticmethod
51155133
def _pcolorargs(funcname, *args, **kw):
5116-
# This takes one kwarg, allmatch.
51175134
# If allmatch is True, then the incoming X, Y, C must
51185135
# have matching dimensions, taking into account that
51195136
# X and Y can be 1-D rather than 2-D. This perfect
@@ -5126,9 +5143,25 @@ def _pcolorargs(funcname, *args, **kw):
51265143
# is False.
51275144

51285145
allmatch = kw.pop("allmatch", False)
5146+
norm = kw.pop("norm", None)
5147+
cmap = kw.pop("cmap", None)
51295148

51305149
if len(args) == 1:
51315150
C = np.asanyarray(args[0])
5151+
5152+
if (C.ndim == 3 and isinstance(norm, mcolors.BivariateNorm) or
5153+
isinstance(cmap, mcolors.BivariateColormap)):
5154+
if cmap is None:
5155+
cmap = mcolors.BivariateColormap()
5156+
if norm is None:
5157+
norm = mcolors.BivariateNorm()
5158+
C = norm(C)
5159+
C[0] = C[0] * (cmap.N-1)
5160+
C[1] = C[1] * (cmap.N-1)
5161+
C = C.astype(int)
5162+
C = C[0] + cmap.N * C[1]
5163+
C = np.array(C)
5164+
51325165
numRows, numCols = C.shape
51335166
if allmatch:
51345167
X, Y = np.meshgrid(np.arange(numCols), np.arange(numRows))
@@ -5140,6 +5173,18 @@ def _pcolorargs(funcname, *args, **kw):
51405173

51415174
if len(args) == 3:
51425175
X, Y, C = [np.asanyarray(a) for a in args]
5176+
if (C.ndim == 3 and isinstance(norm, mcolors.BivariateNorm) or
5177+
isinstance(cmap, mcolors.BivariateColormap)):
5178+
if cmap is None:
5179+
cmap = mcolors.BivariateColormap()
5180+
if norm is None:
5181+
norm = mcolors.BivariateNorm()
5182+
C = norm(C)
5183+
C[0] = C[0] * (cmap.N-1)
5184+
C[1] = C[1] * (cmap.N-1)
5185+
C = C.astype(int)
5186+
C = C[0] + cmap.N * C[1]
5187+
C = np.array(C)
51435188
numRows, numCols = C.shape
51445189
else:
51455190
raise TypeError(
@@ -5325,9 +5370,14 @@ def pcolor(self, *args, **kwargs):
53255370
vmin = kwargs.pop('vmin', None)
53265371
vmax = kwargs.pop('vmax', None)
53275372

5328-
X, Y, C = self._pcolorargs('pcolor', *args, allmatch=False)
5373+
kw = {'norm': norm, 'cmap': cmap, 'allmatch': False}
5374+
X, Y, C = self._pcolorargs('pcolor', *args, **kw)
53295375
Ny, Nx = X.shape
53305376

5377+
if (isinstance(norm, mcolors.BivariateNorm) or
5378+
isinstance(cmap, mcolors.BivariateColormap)):
5379+
norm = mcolors.NoNorm()
5380+
53315381
# unit conversion allows e.g. datetime objects as axis values
53325382
self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs)
53335383
X = self.convert_xunits(X)
@@ -5393,9 +5443,13 @@ def pcolor(self, *args, **kwargs):
53935443

53945444
collection.set_alpha(alpha)
53955445
collection.set_array(C)
5396-
if norm is not None and not isinstance(norm, mcolors.Normalize):
5397-
msg = "'norm' must be an instance of 'mcolors.Normalize'"
5446+
5447+
isNorm = isinstance(norm, (mcolors.Normalize, mcolors.BivariateNorm))
5448+
if norm is not None and not isNorm:
5449+
msg = "'norm' must be an instance of 'mcolors.Normalize' " \
5450+
"or 'mcolors.BivariateNorm'"
53985451
raise ValueError(msg)
5452+
53995453
collection.set_cmap(cmap)
54005454
collection.set_norm(norm)
54015455
collection.set_clim(vmin, vmax)
@@ -5525,9 +5579,14 @@ def pcolormesh(self, *args, **kwargs):
55255579

55265580
allmatch = (shading == 'gouraud')
55275581

5528-
X, Y, C = self._pcolorargs('pcolormesh', *args, allmatch=allmatch)
5582+
kw = {'norm': norm, 'cmap': cmap, 'allmatch': allmatch}
5583+
X, Y, C = self._pcolorargs('pcolormesh', *args, **kw)
55295584
Ny, Nx = X.shape
55305585

5586+
if (isinstance(norm, mcolors.BivariateNorm) or
5587+
isinstance(cmap, mcolors.BivariateColormap)):
5588+
norm = mcolors.NoNorm()
5589+
55315590
# unit conversion allows e.g. datetime objects as axis values
55325591
self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs)
55335592
X = self.convert_xunits(X)
@@ -5666,11 +5725,28 @@ def pcolorfast(self, *args, **kwargs):
56665725
cmap = kwargs.pop('cmap', None)
56675726
vmin = kwargs.pop('vmin', None)
56685727
vmax = kwargs.pop('vmax', None)
5669-
if norm is not None and not isinstance(norm, mcolors.Normalize):
5670-
msg = "'norm' must be an instance of 'mcolors.Normalize'"
5728+
isNorm = isinstance(norm, (mcolors.Normalize, mcolors.BivariateNorm))
5729+
if norm is not None and not isNorm:
5730+
msg = "'norm' must be an instance of 'mcolors.Normalize' " \
5731+
"or 'mcolors.BivariateNorm'"
56715732
raise ValueError(msg)
56725733

5673-
C = args[-1]
5734+
C = np.asarray(args[-1])
5735+
5736+
if (C.ndim == 3 and isinstance(norm, mcolors.BivariateNorm) or
5737+
isinstance(cmap, mcolors.BivariateColormap)):
5738+
if cmap is None:
5739+
cmap = mcolors.BivariateColormap()
5740+
if norm is None:
5741+
norm = mcolors.BivariateNorm()
5742+
C = norm(C)
5743+
C[0] = C[0] * (cmap.N-1)
5744+
C[1] = C[1] * (cmap.N-1)
5745+
C = C.astype(int)
5746+
C = C[0] + cmap.N * C[1]
5747+
C = np.array(C)
5748+
norm = mcolors.NoNorm()
5749+
56745750
nr, nc = C.shape
56755751
if len(args) == 1:
56765752
style = "image"

lib/matplotlib/colors.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,32 @@ def reversed(self, name=None):
855855
return ListedColormap(colors_r, name=name, N=self.N)
856856

857857

858+
class BivariateColormap(Colormap):
859+
def __init__(self, name, N=256):
860+
Colormap.__init__(self, name, N)
861+
862+
def _init(self):
863+
red = np.linspace(0, 1, self.N)
864+
green = np.linspace(0, 1, self.N)
865+
red_mesh, green_mesh = np.meshgrid(red, green)
866+
blue_mesh = np.zeros_like(red_mesh)
867+
alpha_mesh = np.ones_like(red_mesh)
868+
bivariate_cmap = np.dstack((red_mesh, green_mesh, blue_mesh, alpha_mesh))
869+
self._lut = np.vstack(bivariate_cmap)
870+
self._isinit = True
871+
self.N = self.N * self.N
872+
self._set_extremes()
873+
874+
def _resample(self, lutsize):
875+
"""
876+
Return a new color map with *lutsize x lutsize* entries.
877+
"""
878+
return BivariateColormap(self.name, lutsize)
879+
880+
def reversed(self, name=None):
881+
raise NotImplementedError()
882+
883+
858884
class Normalize(object):
859885
"""
860886
A class which, when called, can normalize data into
@@ -1387,8 +1413,8 @@ def __call__(self, values, clip=None):
13871413
if clip is None:
13881414
clip = [self.norm1.clip, self.norm2.clip]
13891415

1390-
return [self.norm1(values[0], clip=clip[0]),
1391-
self.norm2(values[1], clip=clip[1])]
1416+
return np.array([self.norm1(values[0], clip=clip[0]),
1417+
self.norm2(values[1], clip=clip[1])])
13921418

13931419
def inverse(self, values):
13941420
"""
@@ -1403,6 +1429,7 @@ def inverse(self, values):
14031429
"""
14041430
return [self.norm1.inverse(values[0]), self.norm.inverse(values[1])]
14051431

1432+
14061433
def rgb_to_hsv(arr):
14071434
"""
14081435
convert float rgb values (in the range [0, 1]), in a numpy array to hsv

0 commit comments

Comments
 (0)