Skip to content

Commit

Permalink
Merge pull request #194 from ianhi/imshow-alpha
Browse files Browse the repository at this point in the history
Overhaul how scalar arguments are handled
  • Loading branch information
ianhi authored May 27, 2021
2 parents e7f77aa + e5a4075 commit ab06aa2
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 96 deletions.
2 changes: 1 addition & 1 deletion mpl_interactions/_version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version_info = (0, 17, 9)
version_info = (0, 17, 10)
__version__ = ".".join(map(str, version_info))
106 changes: 89 additions & 17 deletions mpl_interactions/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,20 +391,92 @@ def gogogo_controls(
return controls, params


def prep_scalar(arg, name=None):
if isinstance(arg, tuple):
if isinstance(arg[0], Controls):
# index controls. e.g. ctrls['size']

def f(*args, **kwargs):
return kwargs[arg[1][0]]

return f, arg, None
elif name is not None:
# name will be set by calling function if from ipyplot
# this case is if given an abbreviation e.g.: `s = (0, 10)`
def f(*args, **kwargs):
return kwargs[name]

return f, None, (name, arg)
return arg, None, None
def _gen_f(key):
def f(*args, **kwargs):
return kwargs[key]

return f


def _gen_param_excluder(added_kwargs):
"""
Pass through all the original keys, but exclude any kwargs that we added
manually through prep_scalar
Parameters
----------
added_kwargs : list of str
Returns
-------
excluder : callable
"""

def excluder(params, except_=None):
"""
Parameters
----------
params : dict
except : str
"""
return {k: v for k, v in params.items() if k not in added_kwargs or k == except_}

return excluder


def prep_scalars(kwarg_dict, **kwargs):
"""
Process potentially scalar arguments. This allows for passing in
slider shorthands for these arguments, and for passing indexed controls objects for them.
Parameters
----------
kwarg_dict : dict
The kwargs passed to the calling functions
kwargs :
The arguments to process
Returns
-------
funcs : dict
The processed arguments. Re-assign the args as `s = funcs['s']` to
make use of any autogenerated functions to connect callbacks to these
scalar values.
extra_ctrls : list of Controls
Any extra controls objects that need to be used. Useful for `gogogo_controls`
param_excluder : function
A function to exclude any scalar kwargs we added from params. Use this in the
update functions to avoid calling user provided functions with the kwargs that
we added here.
"""
extra_ctrls = []
added_kwargs = []

for name, arg in kwargs.items():
if isinstance(arg, tuple):
if isinstance(arg[0], Controls):
# index controls. e.g. ctrls['size']
# arg looks like (controls, ['size'])

# factory function to avoid scoping shenanigans

extra_ctrls.append(arg)
kwargs[name] = _gen_f(arg[1][0])
elif name is not None:
# name will be set by calling function if from ipyplot
# this case is if given an abbreviation e.g.: `s = (0, 10)`

kwargs[name] = _gen_f(name)

# Modify the calling functions kwargs in place to add the arg
kwarg_dict[name] = arg
added_kwargs.append(name)

if len(added_kwargs) == 0:
# shortcircuit options
def param_excluder(params, except_=None):
return params

else:
param_excluder = _gen_param_excluder(added_kwargs)
return kwargs, extra_ctrls, param_excluder
20 changes: 9 additions & 11 deletions mpl_interactions/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from .helpers import *
from .utils import figure, ioff, nearest_idx
from .controller import gogogo_controls, prep_scalar
from .controller import gogogo_controls, prep_scalars
from .xarray_helpers import get_hs_axes, get_hs_extent, get_hs_fmts

# functions that are methods
Expand Down Expand Up @@ -666,15 +666,11 @@ def hyperslicer(
if "extent" not in kwargs:
extent = None

args = []
extra_ctrls = []
# fmt: off
vmin, ec, arg = prep_scalar(vmin, name='vmin'); extra_ctrls.append(ec); args.append(arg)
vmax, ec, arg = prep_scalar(vmax, name='vmax'); extra_ctrls.append(ec); args.append(arg)
# fmt: on
for a in args:
if a is not None:
kwargs[a[0]] = a[1]
funcs, extra_ctrls, param_excluder = prep_scalars(kwargs, vmin=vmin, vmax=vmax, alpha=alpha)
vmin = funcs["vmin"]
vmax = funcs["vmax"]
alpha = funcs["alpha"]
if vmin_vmax is not None:
if isinstance(vmin_vmax, tuple) and not isinstance(vmin_vmax[0], str):
vmin_vmax = ("r", *vmin_vmax)
Expand Down Expand Up @@ -719,9 +715,11 @@ def update(params, indices, cache):
im.norm.autoscale(new_data)

if isinstance(vmin, Callable):
im.norm.vmin = vmin(**params)
im.norm.vmin = vmin(**param_excluder(params, "vmin"))
if isinstance(vmax, Callable):
im.norm.vmax = vmax(**params)
im.norm.vmax = vmax(**param_excluder(params, "vmax"))
if isinstance(alpha, Callable):
im.set_alpha(callable_else_value_no_cast(alpha, param_excluder(params, "alpha"), cache))

controls._register_function(update, fig, params.keys())
# make it once here so we can use the dims in update
Expand Down
Loading

0 comments on commit ab06aa2

Please sign in to comment.