Using RangeSliders#
%matplotlib ipympl
import matplotlib.pyplot as plt
import numpy as np
from mpl_interactions import ipyplot as iplt
How to automatically generate a RangeSlider#
In order to create a RangeSlider rather than a Slider you prefix the tuples with either "r"
or "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 appropriate.
# 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[0], xrange[1], 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))
Using a RangeSlider
for Scalar arguments - Thresholding an Image#
There are some arguments, such as vmin
and 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 vmin
and vmax
with a range slider.
Additionally it will also add the vmin
and 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[1].hist(im.flatten(), bins="auto")
axs[1].set_title("Histogram of Pixel Intensities")
# create interactive controls
ctrls = iplt.imshow(im, vmin_vmax=("r", im.min(), im.max()), ax=axs[0])
iplt.axvline(ctrls["vmin"], ax=axs[1], c="k")
_ = iplt.axvline(ctrls["vmax"], ax=axs[1], c="k")
Using a Matplotlib RangeSlider#
But maptlotlib doesn’t have range sliders???!?!?#
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 RangeSlider
s while Matplotlib does not, so have we broken this contract? Happily the answer is no. RangeSliders are being added to matplolibt in matplotlib/matplotlib#18829, and in the meantime they are available via RangeSlider
.
from mpl_interactions.widgets import RangeSlider
fig, axs = plt.subplots(1, 2, figsize=(12, 5))
# plot histogram of pixel intensities
axs[1].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[0])
iplt.axvline(ctrls["vmin"], ax=axs[1], c="k")
iplt.axvline(ctrls["vmax"], ax=axs[1], c="k")