Skip to content

Commit 50d1bb0

Browse files
committed
Some ideas for a colormap __getitem__ method.
1 parent 03e7111 commit 50d1bb0

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

lib/matplotlib/colors.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,90 @@ def truncate(self, minval=0.0, maxval=1.0, name=None, N=None):
755755
name = "trunc({},{:.2f},{:.2f})".format(self.name, minval, maxval)
756756
return ListedColormap(self(np.linspace(minval, maxval, N)), name)
757757

758+
def __getitem__(self, item):
759+
"""Advanced indexing for colorbars.
760+
761+
762+
Examples
763+
--------
764+
import matplotlib.pyplat as plt
765+
cmap = plt.get_cmap('viridis', 128)
766+
767+
# ### float indexing
768+
# for float-style indexing, the values must be in [0.0, 1.0]
769+
# Truncate the colormap between 20 and 70%
770+
new_cm = cmap[0.2, 0.7]
771+
# equivalently:
772+
new_cm = cmap[0.2:0.7]
773+
774+
# Same as above, but specify the number of points
775+
new_cm = cmap[0.2, 0.7, 64]
776+
# equivalently, use `np.mgrid` complex-indexing:
777+
new_cm = cmap[0.2:0.7:1j * 64]
778+
779+
# ### Int-style indexing
780+
# for int-style indexing, the values must be in [0, self.N]
781+
new_cm = cmap[12:100]
782+
783+
# Same as above, but 4x fewer points
784+
new_cm = cmap[12:100:4]
785+
786+
# negative values are supported (same as above)
787+
new_cm = cmap[12:-28:4]
788+
789+
# And so is `np.mgrid` complex-indexing (same as above)
790+
new_cm = cmap[12:-28:1j * 22]
791+
"""
792+
if isinstance(item, tuple):
793+
if len(item) == 2:
794+
N = self.N
795+
elif len(item) == 3:
796+
N = item[2]
797+
else:
798+
raise IndexError("Invalid colorbar itemization")
799+
return self.truncate(item[0], item[1], N=N)
800+
elif isinstance(item, slice):
801+
name = self.name + '[{:s}]'.format(str(item))
802+
sss = [item.start, item.stop, item.step]
803+
if any([isinstance(s, int) for s in sss]):
804+
# This is an integer-style itemization
805+
if sss[0] is None:
806+
sss[0] = 0
807+
elif sss[0] < 0:
808+
sss[0] = sss[0] % self.N
809+
if sss[1] is None:
810+
sss[1] = self.N
811+
elif sss[1] < 0:
812+
sss[1] = sss[1] % self.N
813+
if sss[2] is None:
814+
sss[2] = 1
815+
sss[0] = sss[0] / self.N
816+
sss[1] = sss[1] / self.N
817+
if not isinstance(sss[2], complex):
818+
sss[2] = sss[2] / self.N
819+
else:
820+
if sss[0] is None:
821+
sss[0] = 0.0
822+
if sss[1] is None:
823+
sss[1] = 1.0
824+
if sss[2] is None:
825+
sss[2] = self.N * 1j
826+
if sss[0] < 0 or sss[0] >= 1 or sss[1] <= 0 or sss[1] > 1:
827+
raise IndexError("Invalid colorbar itemization - outside bounds")
828+
points = np.mgrid[slice(*sss)]
829+
elif isinstance(item, (list, np.ndarray)):
830+
name = self.name + '[...]'
831+
if isinstance(item, list):
832+
item = np.array(item)
833+
if item.dtype.kind in ('u', 'i'):
834+
item = item.astype('f') / self.N
835+
points = item
836+
else:
837+
raise IndexError("Invalid colorbar itemization")
838+
if len(points) <= 1:
839+
raise IndexError("Invalid colorbar itemization - too few points")
840+
return ListedColormap(self(points), name=name)
841+
758842

759843
class LinearSegmentedColormap(Colormap):
760844
"""Colormap objects based on lookup tables using linear segments.

0 commit comments

Comments
 (0)