Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
array += [[0, 4, 4, 5, 5, 0]]
labels += ('HSL saturation', 'HPL saturation')
if rgb:
array += [np.array([4, 4, 5, 5, 6, 6]) + 2 * int(saturation)]
labels += ('Red', 'Green', 'Blue')
fig, axs = ui.subplots(
array=array, span=False, share=1,
axwidth=axwidth, axpad='1em',
)
# Iterate through colormaps
mc = ms = mp = 0
cmaps = []
for cmap in args:
# Get colormap and avoid registering new names
name = cmap if isinstance(cmap, str) else getattr(cmap, 'name', None)
cmap = constructor.Colormap(cmap, N=N) # arbitrary cmap argument
if name is not None:
cmap.name = name
cmap._init()
cmaps.append(cmap)
# Get clipped RGB table
x = np.linspace(0, 1, N)
lut = cmap._lut[:-3, :3].copy()
rgb_data = lut.T # 3 by N
hcl_data = np.array([to_xyz(color, space='hcl') for color in lut]).T # 3 by N
hsl_data = [to_xyz(color, space='hsl')[1] for color in lut]
hpl_data = [to_xyz(color, space='hpl')[1] for color in lut]
# Plot channels
# If rgb is False, the zip will just truncate the other iterables
data = tuple(hcl_data)
def _update_features(self):
"""
Update geographic features.
"""
# NOTE: The e.g. cfeature.COASTLINE features are just for convenience,
# lo res versions. Use NaturalEarthFeature instead.
# WARNING: Seems cartopy features cannot be updated! Updating _kwargs
# attribute does *nothing*.
reso = rc['reso'] # resolution cannot be changed after feature created
try:
reso = constructor.CARTOPY_RESOS[reso]
except KeyError:
raise ValueError(
f'Invalid resolution {reso!r}. Options are: '
+ ', '.join(map(repr, constructor.CARTOPY_RESOS)) + '.'
)
for name, args in constructor.CARTOPY_FEATURES.items():
# Draw feature or toggle feature off
b = rc.get(name, context=True)
attr = f'_{name}_feature'
feat = getattr(self, attr, None)
drawn = feat is not None # if exists, apply *updated* settings
if b is not None:
if not b:
if drawn: # toggle existing feature off
feat.set_visible(False)
else:
if not drawn:
feat = cfeature.NaturalEarthFeature(*args, reso)
feat = self.add_feature(feat) # convert to FeatureArtist
# Update formatters
loninline = _not_none(loninline, rc.get('grid.loninline', context=True))
latinline = _not_none(latinline, rc.get('grid.latinline', context=True))
labelpad = _not_none(labelpad, rc.get('grid.pad', context=True))
rotatelabels = _not_none(
rotatelabels, rc.get('grid.rotatelabels', context=True)
)
dms = _not_none(dms, rc.get('grid.dmslabels', context=True))
nsteps = _not_none(nsteps, rc.get('grid.nsteps', context=True))
if lonformatter is not None:
lonformatter_kw = lonformatter_kw or {}
formatter = constructor.Formatter(lonformatter, **lonformatter_kw)
self._lonaxis.set_major_formatter(formatter)
if latformatter is not None:
latformatter_kw = latformatter_kw or {}
formatter = constructor.Formatter(latformatter, **latformatter_kw)
self._lataxis.set_major_formatter(formatter)
if dms is not None: # harmless if these are not GeoLocators
self._lonaxis.get_major_formatter()._dms = dms
self._lataxis.get_major_formatter()._dms = dms
self._lonaxis.get_major_locator()._dms = dms
self._lataxis.get_major_locator()._dms = dms
# Apply worker functions
self._update_extent(lonlim=lonlim, latlim=latlim, boundinglat=boundinglat)
self._update_boundary(patch_kw or {})
self._update_features()
self._update_major_gridlines(
longrid=longrid, latgrid=latgrid, # gridline toggles
lonarray=lonarray, latarray=latarray, # label toggles
loninline=loninline, latinline=latinline, rotatelabels=rotatelabels,
labelpad=labelpad, nsteps=nsteps,
def __init__(self, axes, projection=None):
super().__init__(axes)
if self._use_dms(projection):
locator = formatter = 'dmslon'
else:
locator = formatter = 'deglon'
self.set_major_formatter(constructor.Formatter(formatter), default=True)
self.set_major_locator(constructor.Locator(locator), default=True)
self.set_minor_locator(mticker.AutoMinorLocator(), default=True)
# Determine and temporarily set cycler
# NOTE: Axes cycle has no getter, only set_prop_cycle, which sets a
# prop_cycler attribute on the hidden _get_lines and _get_patches_for_fill
# objects. This is the only way to query current axes cycler! Should not
# wrap set_prop_cycle because would get messy and fragile.
# NOTE: The _get_lines cycler is an *itertools cycler*. Has no length, so
# we must cycle over it with next(). We try calling next() the same number
# of times as the length of input cycle. If the input cycle *is* in fact
# the same, below does not reset the color position, cycles us to start!
if cycle is not None or cycle_kw:
# Get the new cycler
cycle_args = () if cycle is None else (cycle,)
if y.ndim > 1 and y.shape[1] > 1: # default samples count
cycle_kw.setdefault('N', y.shape[1])
cycle = constructor.Cycle(*cycle_args, **cycle_kw)
# Get the original property cycle
# NOTE: Matplotlib saves itertools.cycle(cycler), not the original
# cycler object, so we must build up the keys again.
i = 0
by_key = {}
cycle_orig = self._get_lines.prop_cycler
for i in range(len(cycle)): # use the cycler object length as a guess
prop = next(cycle_orig)
for key, value in prop.items():
if key not in by_key:
by_key[key] = set()
if isinstance(value, (list, np.ndarray)):
value = tuple(value)
by_key[key].add(value)
def __init__(self, axes, projection=None):
super().__init__(axes)
if self._use_dms(projection):
locator = formatter = 'dmslon'
else:
locator = formatter = 'deglon'
self.set_major_formatter(constructor.Formatter(formatter), default=True)
self.set_major_locator(constructor.Locator(locator), default=True)
self.set_minor_locator(mticker.AutoMinorLocator(), default=True)
'weight': 'tick.labelweight'
},
context=True,
)
for t in axis.get_ticklabels():
t.update(kw)
# Tick locator, which in this case applies to gridlines
# NOTE: Must convert theta locator input to radians, then back
# to degrees.
if locator is not None:
if r == 'theta' and (
not isinstance(locator, (str, mticker.Locator))):
# real axis limts are rad
locator = np.deg2rad(locator)
locator = constructor.Locator(locator, **locator_kw)
locator.set_axis(axis) # this is what set_locator does
grids = np.array(locator())
if r == 'r':
grids = grids[(grids >= min_) & (grids <= max_)]
self.set_rgrids(grids)
else:
grids = np.rad2deg(grids)
grids = grids[(grids >= min_) & (grids <= max_)]
if grids[-1] == min_ + 360: # exclusive if 360 degrees
grids = grids[:-1]
self.set_thetagrids(grids)
# Tick formatter and toggling
if formatter is not None:
formatter = constructor.Formatter(formatter, **formatter_kw) # noqa: E501
axis.set_major_formatter(formatter)
def _update_features(self):
"""
Update geographic features.
"""
# NOTE: Also notable are drawcounties, blumarble, drawlsmask,
# shadedrelief, and etopo methods.
for name, method in constructor.BASEMAP_FEATURES.items():
# Draw feature or toggle on and off
b = rc.get(name, context=True)
attr = f'_{name}_feature'
feat = getattr(self, attr, None)
drawn = feat is not None # if exists, apply *updated* settings
if b is not None:
if not b:
if drawn: # toggle existing feature off
for obj in feat:
feat.set_visible(False)
else:
if not drawn:
feat = getattr(self.projection, method)(ax=self)
if not isinstance(feat, (list, tuple)): # list of artists?
feat = (feat,)
setattr(self, attr, feat)
warnings._warn_proplot(
'Inheriting projection from the main axes. '
f'Ignoring proj_kw keyword args: {proj_kw}'
)
if proj in ('cartopy', 'basemap'):
map_projection = copy.copy(self.projection)
kwargs.setdefault('map_projection', map_projection)
# Create new projection
elif proj == 'cartesian':
pass
elif proj == 'polar':
proj = 'polar2' # custom proplot name
else:
proj_kw.setdefault('basemap', basemap)
map_projection = constructor.Proj(proj, **proj_kw)
kwargs.setdefault('map_projection', map_projection)
proj = 'basemap' if proj_kw['basemap'] else 'cartopy'
# This puts the rectangle into figure-relative coordinates.
locator = self._make_inset_locator(bounds, transform)
cls = mprojections.get_projection_class(proj)
bb = locator(None, None)
ax = cls(self.figure, bb.bounds, zorder=zorder, label=label, **kwargs)
# The following locator lets the axes move if we used data coordinates,
# is called by ax.apply_aspect()
zoom = _not_none(zoom, self.name == ax.name) # only zoom when same projection
ax.set_axes_locator(locator)
self.add_child_axes(ax)
ax._inset_zoom = zoom
ax._inset_parent = self
if minorlocator in (True, False):
warnings._warn_proplot(
f'You passed {x}minorticks={minorlocator}, but this '
'argument is used to specify tick *locations*. If '
'you just want to *toggle* minor ticks on and off, '
f'please use {x}tickminor=True or {x}tickminor=False.'
)
minorlocator = None
if tickminor or minorlocator:
isdefault = minorlocator is None
if isdefault:
minorlocator = getattr(
axis._scale, '_default_minor_locator', None
)
if not minorlocator:
minorlocator = constructor.Locator('minor')
else:
minorlocator = constructor.Locator(
minorlocator, **minorlocator_kw
)
axis.set_minor_locator(minorlocator)
axis.isDefault_minloc = isdefault
elif tickminor is not None and not tickminor:
# NOTE: Generally if you *enable* minor ticks on a dual
# axis, want to allow FuncScale updates to change the
# minor tick locators. If you *disable* minor ticks, do
# not want FuncScale applications to turn them on. So we
# allow below to set isDefault_minloc to False.
axis.set_minor_locator(constructor.Locator('null'))
# Major formatter
# NOTE: The only reliable way to disable ticks labels and then