%matplotlib ipympl import matplotlib.pyplot as plt import numpy as np from mpl_interactions import ipyplot as iplt
In order to createa a RangeSlider rather than a Slider you prefix the tuples with either
"range", then the rest of the tuple is created according to the rules from converting tuples to sliders. So arrays will remain arrays, or the values will be passed through to np.linspace as approriate.
# passed through to np.linspace ("range", min, max, [step]) ("r", min, max, [step]) # array used directly ("range", np.array) ("r", np.array)
then function can use them the same as any other kwargs, except now they are tuples rather than just numbers.
def f_x(xrange, **kwargs): return np.linspace(xrange, xrange, 1000) def f_y(x, tau, **kwargs): return np.sin(x * tau) fig, ax = plt.subplots() controls = iplt.plot(f_x, f_y, xrange=("r", -1, 3), tau=(5, 10))
RangeSliderfor Scalar arguments - Thresholding an Image¶
There are some arguments, such as
vmax that are both scalar and often make sense to have as two ends of a RangeSlider. For these mpl_interactions treats them as a special case and offers a third argument
vmin_vmax that can be used to control both
vmax with a range slider.
Additionally it will also add the
vmax parameters individually to the controls object. This means that they can be used for other things, such as determinging the positions of the vertical lines on the histogram below. These are accessed by indexing the
controls object. For more examples of controlling a scalar argument see Scalar Arguments
N = 128 im = np.random.randn(N * N).reshape(N, N) fig, axs = plt.subplots(1, 2, figsize=(12, 5)) # plot histogram of pixel intensities axs.hist(im.flatten(), bins="auto") axs.set_title("Histogram of Pixel Intensities") # create interactive controls ctrls = iplt.imshow(im, vmin_vmax=("r", im.min(), im.max()), ax=axs) iplt.axvline(ctrls["vmin"], ax=axs, c="k") _ = iplt.axvline(ctrls["vmax"], ax=axs, c="k")
One of the implicit promises of this library is that it will work equally well both in and out of a jupyter notebook. So it leverages ipywidgets when available but otherwise will use matplotlib widgets. However, ipywidgets has RangeSliders while Matplotlib does not, so have we broken this contract? Happily the answer is no. RangeSliders are being added to matplolibt in https://github.com/matplotlib/matplotlib/pull/18829, and in the meantime they are availiable via
from mpl_interactions.widgets import RangeSlider fig, axs = plt.subplots(1, 2, figsize=(12, 5)) # plot histogram of pixel intensities axs.hist(im.flatten(), bins="auto") # make thresholding slider plt.subplots_adjust(bottom=0.25) s_ax = plt.axes([0.575, 0.1, 0.25, 0.05]) slider = RangeSlider(s_ax, "threshold", im.min(), im.max(), valinit=(im.min(), im.max())) # create interactive controls ctrls = iplt.imshow(im, vmin_vmax=slider, ax=axs) iplt.axvline(ctrls["vmin"], ax=axs, c="k") iplt.axvline(ctrls["vmax"], ax=axs, c="k")