def explore(f, x, prms=None, x_min=-10, x_max=10):
# construct the arguments for @interact
interact_args = {}
for symbol, value in (prms or {}).items():
if isinstance(value, numbers.Number):
interact_args[symbol] = widgets.fixed(value)
else:
interact_args[symbol] = value
dx = x_max - x_min
interact_args['x_range'] = widgets.FloatRangeSlider(
value=(x_min, x_max),
min=x_min - 2 * dx,
max=x_max + 2 * dx,
description=x,
)
# make the figure:
x_sc = bq.LinearScale()
y_sc = bq.LinearScale()
ax_x = bq.Axis(label='x', scale=x_sc, grid_lines='solid')
ax_y = bq.Axis(label='y', scale=y_sc, orientation='vertical', grid_lines='solid')
line = bq.Lines(x=[], y=[], scales={'x': x_sc, 'y': y_sc})
fig = bq.Figure(axes=[ax_x, ax_y], marks=[line])
display(fig)
# also display the latex expression
expression = widgets.Label('$%s$' % latex(f), description='f')
display(expression)
@widgets.interact(**interact_args)
def foo(**kwargs):
# evaluate the expression for each parameter
g = f
for symbol in sorted(prms):
g = g.subs(symbol, kwargs[symbol])
# update the expression
expression.value = '${} = {}$'.format(latex(f), latex(g))
# update the plot
x_min, x_max = kwargs['x_range']
X = np.linspace(x_min, x_max, 100)
Y = sympy.lambdify(x, g, 'numpy')(X)
line.x = X
line.y = Y