# coding: utf-8
"""Tools to build ipython widgets."""
from __future__ import annotations
import ipywidgets as ipw
from collections import OrderedDict
#def add_docstrings(*tuples):
# """
# This decorator adds to the docstring the documentation for functions.
# When writing high-level API, it's quite common to call thirdy-party functions
# with a restricted set of arguments while optional keyword arguments are
# collected in an optional dictionary.
#
# The first item of the tuple contains the function (python object) wrapped by the code.
# The second item is list of strings with the name of the actual arguments passed to function.
# """
# from functools import wraps
# def wrapper(func):
# @wraps(func)
# def wrapped_func(*args, **kwargs):
# return func(*args, **kwargs)
#
# # Add docstrings for the functions that will be called by func.
# lines = []
# app = lines.append
# for t in tuples:
# fname = t[0].__name__
# # List of strings or string.
# if isinstance(t[1], (list, tuple)):
# fargs = ",".join("`%s`" % a for a in t[1])
# else:
# fargs = "`%s`" % t[1]
# app("\n%s are passed to function :func:`%s` in module :mod:`%s`" % (fargs, fname, t[0].__module__))
# app("Docstring of `%s`:" % fname)
# app(t[0].__doc__)
# s = "\n".join(lines)
#
# if wrapped_func.__doc__ is not None:
# # Add s at the end of the docstring.
# wrapped_func.__doc__ += "\n" + s
# else:
# # Use s
# wrapped_func.__doc__ = s
# return wrapped_func
# return wrapper
[docs]
def str2bool_or_none(*args):
d = {"None": None, "True": True, "False": False}
l = [d[a] for a in args]
return l[0] if len(l) == 1 else l
# Taken from matplotlib.markers.MarkerStyle (replaced dict with OrderedDict).
_mpl_markers = OrderedDict([
('.', 'point'),
(',', 'pixel'),
('o', 'circle'),
('v', 'triangle_down'),
('^', 'triangle_up'),
('<', 'triangle_left'),
('>', 'triangle_right'),
('1', 'tri_down'),
('2', 'tri_up'),
('3', 'tri_left'),
('4', 'tri_right'),
('8', 'octagon'),
('s', 'square'),
('p', 'pentagon'),
('*', 'star'),
('h', 'hexagon1'),
('H', 'hexagon2'),
('+', 'plus'),
('x', 'x'),
('D', 'diamond'),
('d', 'thin_diamond'),
('|', 'vline'),
('_', 'hline'),
#(TICKLEFT: 'tickleft',
#(TICKRIGHT: 'tickright',
#(TICKUP: 'tickup',
#(TICKDOWN: 'tickdown',
#(CARETLEFT: 'caretleft',
#(CARETRIGHT: 'caretright',
#(CARETUP: 'caretup',
#(CARETDOWN: 'caretdown',
("None", 'nothing'),
(None, 'nothing'),
(' ', 'nothing'),
('', 'nothing'),
])
[docs]
def markers_dropdown(default="o"):
return ipw.Dropdown(
options={name: key for key, name in _mpl_markers.items()},
value=default,
description='marker',
)
_mpl_colors = OrderedDict([
("None", "None"),
("blue", "b"),
("green", "g"),
("red", "r"),
("cyan", "c"),
("magenta", "m"),
("yellow", "y"),
("black", "k"),
("white", "w"),
])
[docs]
def colors_dropdow(default="None"):
return ipw.Dropdown(
options=_mpl_colors,
value=default,
description='color',
)
[docs]
def linewidth_slider(default=1, orientation="horizontal"):
return ipw.FloatSlider(
value=default,
min=0,
max=10,
step=0.5,
description='linewidth',
orientation=orientation,
readout_format='.1f'
)
[docs]
def size_slider(default=5, orientation="horizontal"):
return ipw.FloatSlider(
value=default,
min=0,
max=20,
step=0.5,
description='size',
orientation=orientation,
readout_format='.1f'
)
[docs]
def saturation_slider(default=0.75, orientation="horizontal"):
return ipw.FloatSlider(
value=default,
min=0,
max=1,
step=0.05,
description='saturation',
orientation=orientation,
readout_format='.1f'
)
# Have colormaps separated into categories:
# http://matplotlib.org/examples/color/colormaps_reference.html
_mpl_categ_cmaps = OrderedDict([
#('Perceptually Uniform Sequential',
('Uniform', ['viridis', 'inferno', 'plasma', 'magma']),
('Sequential', ['Blues', 'BuGn', 'BuPu',
'GnBu', 'Greens', 'Greys', 'Oranges', 'OrRd',
'PuBu', 'PuBuGn', 'PuRd', 'Purples', 'RdPu',
'Reds', 'YlGn', 'YlGnBu', 'YlOrBr', 'YlOrRd']),
('Sequential(2)', ['afmhot', 'autumn', 'bone', 'cool',
'copper', 'gist_heat', 'gray', 'hot',
'pink', 'spring', 'summer', 'winter']),
('Diverging', ['BrBG', 'bwr', 'coolwarm', 'PiYG', 'PRGn', 'PuOr',
'RdBu', 'RdGy', 'RdYlBu', 'RdYlGn', 'Spectral',
'seismic']),
('Qualitative', ['Accent', 'Dark2', 'Paired', 'Pastel1',
'Pastel2', 'Set1', 'Set2', 'Set3']),
('Miscellaneous', ['gist_earth', 'terrain', 'ocean', 'gist_stern',
'brg', 'CMRmap', 'cubehelix',
'gnuplot', 'gnuplot2', 'gist_ncar',
'nipy_spectral', 'jet', 'rainbow',
'gist_rainbow', 'hsv', 'flag', 'prism'])
])
# flat list.
_mpl_cmaps = [cm for sublist in _mpl_categ_cmaps.values() for cm in sublist]
#def colormap_widget():
# from IPython.display import display, clear_output
# w_type = ipw.Dropdown(options=list(_mpl_categ_cmaps.keys()), description='colormap category')
# w_cmap = ipw.Dropdown(options=_mpl_categ_cmaps["Uniform"], description='colormap name')
#
# def on_value_change(change):
# print(change)
# print(w_cmap.value)
# w_cmap.options = _mpl_categ_cmaps[w_type.value]
# print(w_cmap.value)
#
# w_type.observe(on_value_change, names='value')
# box = ipw.HBox(children=[w_type, w_cmap])
# return display(box)