Skip to content

Commit 8829e40

Browse files
committed
Reorder private level methods
1 parent 00a88d2 commit 8829e40

File tree

2 files changed

+126
-126
lines changed

2 files changed

+126
-126
lines changed

proplot/axes/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1712,7 +1712,7 @@ def _parse_colorbar_arg(
17121712
else:
17131713
levels = edges(ticks)
17141714
from . import PlotAxes
1715-
norm, cmap, _ = PlotAxes._parse_discrete_norm(
1715+
norm, cmap, _ = PlotAxes._parse_level_norm(
17161716
levels, norm, cmap, discrete_ticks=ticks, discrete_labels=labels
17171717
)
17181718

proplot/axes/plot.py

Lines changed: 125 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -2152,7 +2152,7 @@ def _parse_cmap(
21522152
# WARNING: Previously 'colors' set the edgecolors. To avoid all-black
21532153
# colormap make sure to ignore 'colors' if 'cmap' was also passed.
21542154
# WARNING: Previously tried setting number of levels to len(colors), but this
2155-
# makes single-level single-color contour plots, and since _parse_level_count is
2155+
# makes single-level single-color contour plots, and since _parse_level_num is
21562156
# only generates approximate level counts, the idea failed anyway. Users should
21572157
# pass their own levels to avoid truncation/cycling in these very special cases.
21582158
autodiverging = rc['cmap.autodiverging']
@@ -2216,7 +2216,7 @@ def _parse_cmap(
22162216
if abs(np.sign(vmax) - np.sign(vmin)) == 2:
22172217
isdiverging = True
22182218
if discrete:
2219-
levels, vmin, vmax, norm, norm_kw, kwargs = self._parse_level_list(
2219+
levels, vmin, vmax, norm, norm_kw, kwargs = self._parse_level_vals(
22202220
*args, vmin=vmin, vmax=vmax, norm=norm, norm_kw=norm_kw, extend=extend,
22212221
min_levels=min_levels, skip_autolev=skip_autolev, **kwargs
22222222
)
@@ -2250,7 +2250,7 @@ def _parse_cmap(
22502250
# Create the discrete normalizer
22512251
# Then finally warn and remove unused args
22522252
if levels is not None:
2253-
norm, cmap, kwargs = self._parse_discrete_norm(
2253+
norm, cmap, kwargs = self._parse_level_norm(
22542254
levels, norm, cmap, extend=extend, min_levels=min_levels, **kwargs
22552255
)
22562256
params = _pop_params(kwargs, *self._level_parsers, ignore_internal=True)
@@ -2336,7 +2336,119 @@ def _parse_cycle(
23362336
else:
23372337
return kwargs
23382338

2339-
def _parse_level_count(
2339+
def _parse_level_lim(
2340+
self, *args,
2341+
vmin=None, vmax=None, robust=None, inbounds=None,
2342+
negative=None, positive=None, symmetric=None, to_centers=False, **kwargs
2343+
):
2344+
"""
2345+
Return a suitable vmin and vmax based on the input data.
2346+
2347+
Parameters
2348+
----------
2349+
*args
2350+
The sample data.
2351+
vmin, vmax : float, optional
2352+
The user input minimum and maximum.
2353+
robust : bool, optional
2354+
Whether to limit the default range to exclude outliers.
2355+
inbounds : bool, optional
2356+
Whether to filter to in-bounds data.
2357+
negative, positive, symmetric : bool, optional
2358+
Whether limits should be negative, positive, or symmetric.
2359+
to_centers : bool, optional
2360+
Whether to convert coordinates to 'centers'.
2361+
2362+
Returns
2363+
-------
2364+
vmin, vmax : float
2365+
The minimum and maximum.
2366+
**kwargs
2367+
Unused arguemnts.
2368+
"""
2369+
# Parse vmin and vmax
2370+
automin = vmin is None
2371+
automax = vmax is None
2372+
if not automin and not automax:
2373+
return vmin, vmax, kwargs
2374+
2375+
# Parse input args
2376+
inbounds = _not_none(inbounds, rc['cmap.inbounds'])
2377+
robust = _not_none(robust, rc['cmap.robust'], False)
2378+
robust = 96 if robust is True else 100 if robust is False else robust
2379+
robust = np.atleast_1d(robust)
2380+
if robust.size == 1:
2381+
pmin, pmax = 50 + 0.5 * np.array([-robust.item(), robust.item()])
2382+
elif robust.size == 2:
2383+
pmin, pmax = robust.flat # pull out of array
2384+
else:
2385+
raise ValueError(f'Unexpected robust={robust!r}. Must be bool, float, or 2-tuple.') # noqa: E501
2386+
2387+
# Get sample data
2388+
# NOTE: Critical to use _to_numpy_array here because some
2389+
# commands are unstandardized.
2390+
# NOTE: Try to get reasonable *count* levels for hexbin/hist2d, but in general
2391+
# have no way to select nice ones a priori (why we disable discretenorm).
2392+
# NOTE: Currently we only ever use this function with *single* array input
2393+
# but in future could make this public as a way for users (me) to get
2394+
# automatic synced contours for a bunch of arrays in a grid.
2395+
vmins, vmaxs = [], []
2396+
if len(args) > 2:
2397+
x, y, *zs = args
2398+
else:
2399+
x, y, *zs = None, None, *args
2400+
for z in zs:
2401+
if z is None: # e.g. empty scatter color
2402+
continue
2403+
if z.ndim > 2: # e.g. imshow data
2404+
continue
2405+
z = inputs._to_numpy_array(z)
2406+
if inbounds and x is not None and y is not None: # ignore if None coords
2407+
z = self._inbounds_vlim(x, y, z, to_centers=to_centers)
2408+
imin, imax = inputs._safe_range(z, pmin, pmax)
2409+
if automin and imin is not None:
2410+
vmins.append(imin)
2411+
if automax and imax is not None:
2412+
vmaxs.append(imax)
2413+
if automin:
2414+
vmin = min(vmins, default=0)
2415+
if automax:
2416+
vmax = max(vmaxs, default=1)
2417+
2418+
# Apply modifications
2419+
# NOTE: This is also applied to manual input levels lists in _parse_level_vals
2420+
if negative:
2421+
if automax:
2422+
vmax = 0
2423+
else:
2424+
warnings._warn_proplot(
2425+
f'Incompatible arguments vmax={vmax!r} and negative=True. '
2426+
'Ignoring the latter.'
2427+
)
2428+
if positive:
2429+
if automin:
2430+
vmin = 0
2431+
else:
2432+
warnings._warn_proplot(
2433+
f'Incompatible arguments vmin={vmin!r} and positive=True. '
2434+
'Ignoring the latter.'
2435+
)
2436+
if symmetric:
2437+
if automin and not automax:
2438+
vmin = -vmax
2439+
elif automax and not automin:
2440+
vmax = -vmin
2441+
elif automin and automax:
2442+
vmin, vmax = -np.max(np.abs((vmin, vmax))), np.max(np.abs((vmin, vmax)))
2443+
else:
2444+
warnings._warn_proplot(
2445+
f'Incompatible arguments vmin={vmin!r}, vmax={vmax!r}, and '
2446+
'symmetric=True. Ignoring the latter.'
2447+
)
2448+
2449+
return vmin, vmax, kwargs
2450+
2451+
def _parse_level_num(
23402452
self, *args, levels=None, locator=None, locator_kw=None, vmin=None, vmax=None,
23412453
norm=None, norm_kw=None, extend=None, symmetric=None, **kwargs
23422454
):
@@ -2448,7 +2560,7 @@ def _parse_level_count(
24482560

24492561
return levels, kwargs
24502562

2451-
def _parse_level_list(
2563+
def _parse_level_vals(
24522564
self, *args, N=None, levels=None, values=None, extend=None,
24532565
positive=False, negative=False, nozero=False, norm=None, norm_kw=None,
24542566
skip_autolev=False, min_levels=None, **kwargs,
@@ -2541,7 +2653,7 @@ def _sanitize_levels(key, array, minsize):
25412653
levels = _not_none(levels, rc['cmap.levels'])
25422654
else:
25432655
values = _sanitize_levels('values', values, 1)
2544-
kwargs['discrete_ticks'] = values # passed to _parse_discrete_norm
2656+
kwargs['discrete_ticks'] = values # passed to _parse_level_norm
25452657
if len(values) == 1:
25462658
levels = [values[0] - 1, values[0] + 1] # weird but why not
25472659
elif norm is not None and norm not in ('segments', 'segmented'):
@@ -2569,11 +2681,11 @@ def _sanitize_levels(key, array, minsize):
25692681
# this function reverses them and adds special attribute to the normalizer.
25702682
# Then colorbar() reads this attr and flips the axis and the colormap direction
25712683
if np.iterable(levels):
2572-
pop = _pop_params(kwargs, self._parse_level_count, ignore_internal=True)
2684+
pop = _pop_params(kwargs, self._parse_level_num, ignore_internal=True)
25732685
if pop:
25742686
warnings._warn_proplot(f'Ignoring unused keyword arg(s): {pop}')
25752687
elif not skip_autolev:
2576-
levels, kwargs = self._parse_level_count(
2688+
levels, kwargs = self._parse_level_num(
25772689
*args, levels=levels, norm=norm, norm_kw=norm_kw, extend=extend,
25782690
negative=negative, positive=positive, **kwargs
25792691
)
@@ -2600,120 +2712,8 @@ def _sanitize_levels(key, array, minsize):
26002712

26012713
return levels, vmin, vmax, norm, norm_kw, kwargs
26022714

2603-
def _parse_level_lim(
2604-
self, *args,
2605-
vmin=None, vmax=None, robust=None, inbounds=None,
2606-
negative=None, positive=None, symmetric=None, to_centers=False, **kwargs
2607-
):
2608-
"""
2609-
Return a suitable vmin and vmax based on the input data.
2610-
2611-
Parameters
2612-
----------
2613-
*args
2614-
The sample data.
2615-
vmin, vmax : float, optional
2616-
The user input minimum and maximum.
2617-
robust : bool, optional
2618-
Whether to limit the default range to exclude outliers.
2619-
inbounds : bool, optional
2620-
Whether to filter to in-bounds data.
2621-
negative, positive, symmetric : bool, optional
2622-
Whether limits should be negative, positive, or symmetric.
2623-
to_centers : bool, optional
2624-
Whether to convert coordinates to 'centers'.
2625-
2626-
Returns
2627-
-------
2628-
vmin, vmax : float
2629-
The minimum and maximum.
2630-
**kwargs
2631-
Unused arguemnts.
2632-
"""
2633-
# Parse vmin and vmax
2634-
automin = vmin is None
2635-
automax = vmax is None
2636-
if not automin and not automax:
2637-
return vmin, vmax, kwargs
2638-
2639-
# Parse input args
2640-
inbounds = _not_none(inbounds, rc['cmap.inbounds'])
2641-
robust = _not_none(robust, rc['cmap.robust'], False)
2642-
robust = 96 if robust is True else 100 if robust is False else robust
2643-
robust = np.atleast_1d(robust)
2644-
if robust.size == 1:
2645-
pmin, pmax = 50 + 0.5 * np.array([-robust.item(), robust.item()])
2646-
elif robust.size == 2:
2647-
pmin, pmax = robust.flat # pull out of array
2648-
else:
2649-
raise ValueError(f'Unexpected robust={robust!r}. Must be bool, float, or 2-tuple.') # noqa: E501
2650-
2651-
# Get sample data
2652-
# NOTE: Critical to use _to_numpy_array here because some
2653-
# commands are unstandardized.
2654-
# NOTE: Try to get reasonable *count* levels for hexbin/hist2d, but in general
2655-
# have no way to select nice ones a priori (why we disable discretenorm).
2656-
# NOTE: Currently we only ever use this function with *single* array input
2657-
# but in future could make this public as a way for users (me) to get
2658-
# automatic synced contours for a bunch of arrays in a grid.
2659-
vmins, vmaxs = [], []
2660-
if len(args) > 2:
2661-
x, y, *zs = args
2662-
else:
2663-
x, y, *zs = None, None, *args
2664-
for z in zs:
2665-
if z is None: # e.g. empty scatter color
2666-
continue
2667-
if z.ndim > 2: # e.g. imshow data
2668-
continue
2669-
z = inputs._to_numpy_array(z)
2670-
if inbounds and x is not None and y is not None: # ignore if None coords
2671-
z = self._inbounds_vlim(x, y, z, to_centers=to_centers)
2672-
imin, imax = inputs._safe_range(z, pmin, pmax)
2673-
if automin and imin is not None:
2674-
vmins.append(imin)
2675-
if automax and imax is not None:
2676-
vmaxs.append(imax)
2677-
if automin:
2678-
vmin = min(vmins, default=0)
2679-
if automax:
2680-
vmax = max(vmaxs, default=1)
2681-
2682-
# Apply modifications
2683-
# NOTE: This is also applied to manual input levels lists in _parse_level_list
2684-
if negative:
2685-
if automax:
2686-
vmax = 0
2687-
else:
2688-
warnings._warn_proplot(
2689-
f'Incompatible arguments vmax={vmax!r} and negative=True. '
2690-
'Ignoring the latter.'
2691-
)
2692-
if positive:
2693-
if automin:
2694-
vmin = 0
2695-
else:
2696-
warnings._warn_proplot(
2697-
f'Incompatible arguments vmin={vmin!r} and positive=True. '
2698-
'Ignoring the latter.'
2699-
)
2700-
if symmetric:
2701-
if automin and not automax:
2702-
vmin = -vmax
2703-
elif automax and not automin:
2704-
vmax = -vmin
2705-
elif automin and automax:
2706-
vmin, vmax = -np.max(np.abs((vmin, vmax))), np.max(np.abs((vmin, vmax)))
2707-
else:
2708-
warnings._warn_proplot(
2709-
f'Incompatible arguments vmin={vmin!r}, vmax={vmax!r}, and '
2710-
'symmetric=True. Ignoring the latter.'
2711-
)
2712-
2713-
return vmin, vmax, kwargs
2714-
27152715
@staticmethod
2716-
def _parse_discrete_norm(
2716+
def _parse_level_norm(
27172717
levels, norm, cmap, *, extend=None, min_levels=None,
27182718
discrete_ticks=None, discrete_labels=None, **kwargs
27192719
):
@@ -2748,7 +2748,7 @@ def _parse_discrete_norm(
27482748
Unused arguments.
27492749
"""
27502750
# Reverse the colormap if input levels or values were descending
2751-
# See _parse_level_list for details
2751+
# See _parse_level_vals for details
27522752
min_levels = _not_none(min_levels, 2) # 1 for contour plots
27532753
unique = extend = _not_none(extend, 'neither')
27542754
under = cmap._rgba_under
@@ -3806,8 +3806,8 @@ def hexbin(self, x, y, weights, **kwargs):
38063806
%(plot.hexbin)s
38073807
"""
38083808
# WARNING: Cannot use automatic level generation here until counts are
3809-
# estimated. Inside _parse_level_list if no manual levels were provided then
3810-
# _parse_level_count is skipped and args like levels=10 or locator=5 are ignored
3809+
# estimated. Inside _parse_level_vals if no manual levels were provided then
3810+
# _parse_level_num is skipped and args like levels=10 or locator=5 are ignored
38113811
x, y, kw = self._parse_1d_plot(x, y, autovalues=True, **kwargs)
38123812
kw.update(_pop_props(kw, 'collection')) # takes LineCollection props
38133813
kw = self._parse_cmap(x, y, y, skip_autolev=True, default_discrete=False, **kw)
@@ -4200,7 +4200,7 @@ def _iter_arg_cols(self, *args, label=None, labels=None, values=None, **kwargs):
42004200
yield (i, n, *a, kw)
42014201

42024202
# Related parsing functions for warnings
4203-
_level_parsers = (_parse_level_list, _parse_level_count, _parse_level_lim)
4203+
_level_parsers = (_parse_level_vals, _parse_level_num, _parse_level_lim)
42044204

42054205
# Rename the shorthands
42064206
boxes = warnings._rename_objs('0.8.0', boxes=box)

0 commit comments

Comments
 (0)