Recently, I am focusing on producing a time series graph. I read all the csv data to python by using pandas,which the time will be the index.
scrollbar is added as aid for presentation. I import Slider from matplotlib.widgets to produce it. And All looks fine.
However, I want to improve it. The graph now I produce is not bad. If I want to go into the datapoint I can just click the Slider bar.
However, is it possible to add a button to control the slider bar.
What I mean is that can I add a right button. Once I click this right button, the whole graph will move right 5 datapoint( or 5 minutes as it is a time series model)
And can I make a 'left' button too?
Therefore, if I will go fast I can direct click the Slider bar. Then, If i wanna present it slow, I can just click the button?
Actually, I have read some information about 'button library'. However, I don't know how to use it to update the Slider.
Here is my code
df_BA = cs_66667_BS[['BidPrice','AskPrice']]
title_name = 'cs_66667_BS'
ax = df_BA.plot(title= title_name, fontsize= 10, figsize=(20, 10))
ax.set_xlabel('Date', fontsize= 15)
ax.set_ylabel('Price', fontsize= 15)
plt.subplots_adjust(left= 0.04, bottom= 0.25, right= 0.99, top= 0.95, wspace= 0, hspace= 0.1 )
x= df_BA.index.to_pydatetime()
x_min_index = 0
x_max_index = 1
x_min = x[0]
x_max = x[-1] - datetime.timedelta(minutes=4)
y_min = df_BA.BidPrice.min()
y_max = df_BA.AskPrice.max()
# timedelta
x_dt = datetime.timedelta(minutes=5)
axcolor = 'lightgoldenrodyellow'
axpos = plt.axes([0.05, 0.1, 0.9, 0.05], axisbg=axcolor)
slider_max = len(x) - x_max_index - 1
# Slider(axes, name, min, max)
spos = Slider(axpos, 'Pos', matplotlib.dates.date2num(x_min), matplotlib.dates.date2num(x_max))
# pretty date names
plt.gcf().autofmt_xdate()
def update(val):
pos = spos.val
xmin_time = matplotlib.dates.num2date(pos)
xmax_time = matplotlib.dates.num2date(pos) + x_dt
xmin_time = pos
ax.axis([xmin_time, xmax_time, y_min, y_max])
########################################################
fig.canvas.draw_idle()
spos.on_changed(update)
plt.show()
You can easily add a matplotlib.widgets.Button to the plot, in the same way you added a matplotlib.widgets.Slider.
You can then connect the button to a function forward() or backward() which will set the Slider to a new position.
Here is a complete working example which is hopefully close enough to your's (I did change some stuff though)
import matplotlib.pyplot as plt
import matplotlib.dates
from matplotlib.widgets import Slider, Button
import datetime
import pandas as pd
import numpy as np
rng = pd.date_range(datetime.datetime.now(), periods=340, freq='T')
data = {'BidPrice': np.random.random(340)*np.sin(np.arange(340)/30.),
'AskPrice': np.random.random(340)*np.sin(np.arange(340)/30.-2) }
df_BA = pd.DataFrame(data, columns=['BidPrice','AskPrice'], index=rng)
ax = df_BA.plot(title= "Title", fontsize= 10, figsize=(10, 8))
ax.set_xlabel('Date', fontsize= 15)
ax.set_ylabel('Price', fontsize= 15)
plt.subplots_adjust(left= 0.04, bottom= 0.25, right= 0.99, top= 0.95, wspace= 0, hspace= 0.1 )
x= df_BA.index.to_pydatetime()
x_min = x[0]
x_max = x[0] + datetime.timedelta(minutes=20)
y_min = df_BA.BidPrice.min()
y_max = df_BA.AskPrice.max()
ax.set_xlim([x_min, x_max])
ax.set_ylim([y_min, y_max])
x_dt = datetime.timedelta(minutes=10)
axpos = plt.axes([0.2, 0.1, 0.58, 0.03], axisbg='w')
axpos1 = plt.axes([0.05, 0.1, 0.05, 0.03], axisbg='w')
axpos2 = plt.axes([0.93, 0.1, 0.05, 0.03], axisbg='w')
# Slider(axes, name, min, max)
spos = Slider(axpos, 'Pos', matplotlib.dates.date2num(x_min), matplotlib.dates.date2num(x[-1]))
spos.set_val(matplotlib.dates.date2num(x[0]))
button1 = Button(axpos1, '<', color='w', hovercolor='b')
button2 = Button(axpos2, '>', color='w', hovercolor='b')
def update(val):
pos = spos.val
xmin_time = matplotlib.dates.num2date(pos)
xmax_time = matplotlib.dates.num2date(pos) + x_dt
ax.set_xlim([xmin_time, xmax_time ])
plt.gcf().canvas.draw_idle()
def forward(vl):
pos = spos.val
spos.set_val(matplotlib.dates.date2num( matplotlib.dates.num2date(pos) + datetime.timedelta(minutes=5) ))
def backward(vl):
pos = spos.val
spos.set_val(matplotlib.dates.date2num( matplotlib.dates.num2date(pos) - datetime.timedelta(minutes=5) ))
spos.on_changed(update)
button1.on_clicked(backward)
button2.on_clicked(forward)
plt.show()
Related
I don't know why but I am really struggling to get widgets working well in python. I try to look at examples about how to use them but I don't know how to extrapolate that to get it to work with my code. I am trying to get a figure to display widgets such that the type, frequency, phase, and other variables adjust the graph itself.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.widgets as widgets
from scipy import signal
from matplotlib.widgets import RadioButtons
A = 1
ang_f = 5
t = np.linspace(0, 4*np.pi, 1000)
phase = 0
s0 = A*np.sin(ang_f*t + phase)
s2 = A*signal.sawtooth(ang_f*t + phase)
s1 = A*signal.square(ang_f*t + phase)
fig, ax = plt.subplots()
l, = ax.plot(t, s1, lw=2, color='red')
plt.subplots_adjust(left=0.4)
def sinf(x, omega):
return np.sin(omega*x)
def sliderCallback(val):
# """ 'val' is the current value selected by the slider
# Recalculate sine values with val as the frequency """
axesHandle.set_ydata(sinf(x, val))
plt.draw() # Redraw the axes
def clickcallback(val):
# 'val' is the current value selected by the slider
# Recalculate sine values with val as the frequency
axesHandle.set_ydata(sinf(x, val))
plt.draw() # Redraw the axes
def closeCallback(event):
plt.close('all') # Close all open figure windows
fig = plt.figure(figsize=(7, 5))
ax = plt.axes([0.1, 0.2, 0.6, 0.7])
axesHandle, = plt.plot(x, sinf(x, 1), lw=2, color='red')
# Add axis to contain the slider
fax = plt.axes([0.1, 0.04, 0.35, 0.03]) # Frequency
tax = plt.axes([0.1, 0.12, 0.35, 0.03]) # Time
sax_3 = plt.axes([0.60, 0.1, 0.35, 0.03]) # Number of points
pax = plt.axes([0.60, 0.05, 0.35, 0.03]) # Phase
rax = plt.axes([0.85, 0.65, 0.12, 0.15]) # Type
bax = plt.axes([0.85, 0.85, 0.1, 0.1]) # Close
pointshandle = widgets.Slider(sax_3, 'Number of points', 1, 200,
valfmt='%0.0f')
pointshandle.on_changed(sliderCallback)
graphchoice = widgets.RadioButtons(rax, ('Sine', 'Squarewave', 'Sawtooth'))
graphchoice.on_clicked(clickcallback)
freqhandle = widgets.Slider(fax, 'Frequancy (Hz)', 0, 5, valinit=1)
freqhandle.on_changed(sliderCallback)
phasehandle = widgets.Slider(pax, 'Phase', 0, 0*np.pi, valinit=0)
phasehandle.on_changed(sliderCallback)
timehandle = widgets.Slider(tax, 'Time (s)', 1, 10, valinit=1)
timehandle.on_changed(sliderCallback)
buttonHandle = widgets.Button(bax, 'Close')
buttonHandle.on_clicked(closeCallback)
def hzfunc(label):
hzdict = {'Sine': s0, 'Squarewave': s1, 'Sawtooth': s2}
ydata = hzdict[label]
l.set_ydata(ydata)
plt.draw()
graphchoice.on_clicked(hzfunc)
I'm really lost so any tips to put me on the right path would be much appreciated, im just so confused atm.
I have the following equation:
y = ((b-6(x**k))/c)**(1/k)
k = 10/(6+c)
I know that when k > 1 then y is concave and when 0 < k < 1 then y is convex. However, the problem is that in the generated plot it does not matter whatever the value of k is, it always generates a concave y. I was wondering if anybody can help me to figure out what is the problem.
Codes to generate the dynamic plot:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
x = np.arange(0.0, 1.0, 0.001)
b_init = 1
c_init = 0
k = 10/(6+c_init)
delta_f = 1.0
y = ((b_init-6*(x**k))/c_init)**(1/k)
l, = plt.plot(x, y, lw=2)
ax.margins(x=0)
axcolor = 'lightgoldenrodyellow'
ax_b = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor=axcolor)
ax_c = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor=axcolor)
s_b = Slider(ax_b, 'b', 0.1, 18.0, valinit=b_init, valstep=delta_f)
s_c = Slider(ax_c, 'c', 0.1, 12.0, valinit=c_init)
def update(val):
b = s_b.val
c = s_c.val
l.set_ydata(((b-6*(x**k))/c)**(1/k))
fig.canvas.draw_idle()
s_b.on_changed(update)
s_c.on_changed(update)
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')
def reset(event):
s_b.reset()
s_c.reset()
button.on_clicked(reset)
def colorfunc(label):
l.set_color(label)
fig.canvas.draw_idle()
plt.show()
In case you are working with juypter notebooks you can use the widgets from ipywidgets as shown below.
Also, to get an intuition, it might help if you print out the b,c and k values.
%matplotlib inline
import numpy as np
import matplotlib.pyplot as p
from ipywidgets import *
def y(x,b,c):
k = 10/(6+c)
print(f' b={b:.3f},c={c:.3f},k={k:.3f}')
y = ((b-6*(x**k))/c)**(1/k)
return y
def inter(b0,c0):
y1=y(x,b0,c0)
p.figure(figsize=(20,6))
p.plot(x,y1)
dx=0.001
x = np.arange(0, 1.0+dx, dx) # assuming you want to go to 1 inclusively
b0=widgets.FloatSlider(value=10,min=-1,max=18.0,step=0.01,
description='b0',
continuous_update=False,
readout_format='.3f',
layout=Layout(width='90%', height='20px'))
c0=widgets.FloatSlider(value=0.1,min=-1,max=12.0,step=0.01,
description='c0',
continuous_update=False,
readout_format='.3f',
layout=Layout(width='90%', height='20px'))
interact(inter, b0=b0,c0=c0);
I am plotting six subplots in one figure in matplotlib. I am plotting one function with different parameter values using matplotlib sliders. There are two lines in one subplot, each representing function. I want to see where they cross and how they behave if I am changing function parameters. But I havent figured out how to plot two lines and change ydata for two lines in one subplot with sliders.
Here is part of code:
#imports
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.widgets as mw
import math
import numpy as np
#set variables
E0 = 0.5
E1 = .0003
V = .3
#x axis
N = [i for i in range(10000)]
#functions
V_fc_list = [V for n in N]
E_list = [E0*math.exp(-E1*n) for n in N]
#subplots
fig = plt.figure()
ax1 = fig.add_subplot(321)
ax2 = fig.add_subplot(322)
ax3 = fig.add_subplot(323)
ax4 = fig.add_subplot(324)
ax5 = fig.add_subplot(325)
ax6 = fig.add_subplot(326)
#sliders place
ax6.axis('off')
#Sliders
axis_color = 'lightgoldenrodyellow'
E0_slider_ax = fig.add_axes([0.57, 0.3, 0.3, 0.02], axisbg=axis_color)
E1_slider_ax = fig.add_axes([0.57, 0.25, 0.3, .02], axisbg = axis_color)
V_slider_ax = fig.add_axes([0.57, 0.2, 0.3, .02], axisbg = axis_color)
E0_slider = mw.Slider(E0_slider_ax, r'$\epsilon_0$', valmin = 0, valmax = 1, valinit = E0)
E0_slider.label.set_size(15)
E1_slider = mw.Slider(E1_slider_ax, r'$\epsilon_1$', 0.0001, 0.003, valinit = E1)
E1_slider.label.set_size(15)
V_slider = mw.Slider(V_slider_ax, r'$V_c$', 0.001, 0.99, valinit = V)
V_slider.label.set_size(15)
#slider function HERE IS THE MISTAKE
def sliders_on_change(val):
p2.set_ydata([V_slider.val for n in N])
p2.set_ydata([E0_slider.val*math.exp(-E1_slider.val*n) for n in N])
fig.canvas.draw_idle()
V_slider.on_changed(sliders_on_change)
E0_slider.on_changed(sliders_on_change)
E1_slider.on_changed(sliders_on_change)
Here is the last part of error from python
File "C:/Users/Robert/Desktop/python/multidif_S.py", line 109, in <module>
p2,= ax2.plot(N, V_fc_list, 'r-', N, E_list, 'b-', lw = 3)
ValueError: too many values to unpack (expected 1)
Thx for any help!
I changed only a few things in your code to get this:
#imports
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.widgets as mw
import math
import numpy as np
#set variables
E0 = 0.5
E1 = .0003
V = .3
#x axis
N = [i for i in range(10000)]
#functions
V_fc_list = [V for n in N]
E_list = [E0*math.exp(-E1*n) for n in N]
#subplots
fig = plt.figure()
ax1 = fig.add_subplot(321)
ax2 = fig.add_subplot(322)
ax3 = fig.add_subplot(323)
ax4 = fig.add_subplot(324)
ax5 = fig.add_subplot(325)
ax6 = fig.add_subplot(326)
#sliders place
ax6.axis('off')
#Sliders
axis_color = 'lightgoldenrodyellow'
E0_slider_ax = fig.add_axes([0.57, 0.3, 0.3, 0.02], axisbg=axis_color)
E1_slider_ax = fig.add_axes([0.57, 0.25, 0.3, .02], axisbg = axis_color)
V_slider_ax = fig.add_axes([0.57, 0.2, 0.3, .02], axisbg = axis_color)
E0_slider = mw.Slider(E0_slider_ax, r'$\epsilon_0$', valmin = 0, valmax = 1, valinit = E0)
E0_slider.label.set_size(15)
E1_slider = mw.Slider(E1_slider_ax, r'$\epsilon_1$', 0.0001, 0.003, valinit = E1)
E1_slider.label.set_size(15)
V_slider = mw.Slider(V_slider_ax, r'$V_c$', 0.001, 0.99, valinit = V)
V_slider.label.set_size(15)
# Here I introduce the plots p1 and p2. Your code didn't have any plots.
p1 = ax1.plot(np.zeros_like(N)) # plot1
p2 = ax1.plot(np.zeros_like(N)) # plot2, both in ax1
#slider function HERE IS THE MISTAKE
def sliders_on_change(val):
p1[0].set_ydata([V_slider.val for n in N]) # update p1
p2[0].set_ydata([E0_slider.val*math.exp(-E1_slider.val*n) for n in N]) # update p2
ax1.relim() # rescale the shown area (like an automatic call of ax1.set_xlim and ax1.set_ylim with proper inputs)
ax1.autoscale_view() # taken from this question: http://stackoverflow.com/questions/10984085/automatically-rescale-ylim-and-xlim-in-matplotlib
fig.canvas.draw()
V_slider.on_changed(sliders_on_change)
E0_slider.on_changed(sliders_on_change)
E1_slider.on_changed(sliders_on_change)
You see I commented where I changed something. Mostly this was adding the plots p1 and p2 and rescaling on update.
I hope this works for you. I can't help you with that error code because the code you provided does not even have 109 lines...
If you have two lines in a plot, you need to unpack them to two different variables,
p2,p3 = ax2.plot(N, V_fc_list, 'r-', N, E_list, 'b-', lw = 3)
You can then set the data on the two lines as follows:
def sliders_on_change(val):
p3.set_ydata([V_slider.val for n in N])
p2.set_ydata([E0_slider.val*math.exp(-E1_slider.val*n) for n in N])
fig.canvas.draw_idle()
I would like to make two sliders in matplotlib to manually change N and P values in my predator-prey model:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def lotka(x,t,params):
N, P = x
alpha, beta, gamma, delta = params
derivs = [alpha*N - beta*N*P, gamma*N*P - delta*P]
return derivs
N=2
P=1
alpha=3
beta=0.5
gamma=0.4
delta=3
params = [alpha, beta, gamma, delta]
x0=[N,P]
maxt = 20
tstep = 0.01
t=np.arange(0,maxt,tstep)
equation=odeint(lotka, x0, t, args=(params,))
plt.plot(t,equation)
plt.xlabel("Time")
plt.ylabel("Population size")
plt.legend(["Prey", "Predator"], loc="upper right")
plt.title('Prey & Predator Static Model')
plt.grid(color="b", alpha=0.5, linestyle="dashed", linewidth=0.5)
This is my code which produces a graph for fixed initial values of N and P. However, I'd like to change them to see how the plot changes. And for this, I'd like to use sliders like: http://matplotlib.org/users/screenshots.html#slider-demo but I do not know how to add this into my code...
Could anyone please give me any direction? Many thanks!! xx
From the example, hope the comments help you understand what's what:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
from scipy.integrate import odeint
# Function to draw
def lotka(x, t, params):
N, P = x
alpha, beta, gamma, delta = params
derivs = [alpha*N - beta*N*P, gamma*N*P - delta*P]
return derivs
# Parameters
Nmin = 1
Nmax = 100
Pmin = 1
Pmax = 100
N0 = 2
P0 = 1
alpha = 3
beta = 0.5
gamma = 0.4
delta = 3
params = [alpha, beta, gamma, delta]
x0=[N0,P0]
maxt = 20
tstep = 0.01
# Initial function values
t = np.arange(0, maxt, tstep)
prey, predator = odeint(lotka, x0, t, args=(params,)).T
# odeint returne a shape (2000, 2) array, with the value for
# each population in [[n_preys, n_predators], ...]
# The .T at the end transponses the array, so now we get each population
# over time in each line of the resultint (2, 2000) array.
# Create a figure and an axis to plot in:
fig = plt.figure()
ax = fig.add_axes([0.10, 0.3, 0.8, 0.6])
prey_plot = ax.plot(t, prey, label="Prey")[0]
predator_plot = ax.plot(t, predator, label="Predator")[0]
ax.set_xlabel("Time")
ax.set_ylabel("Population size")
ax.legend(loc="upper right")
ax.set_title('Prey & Predator Static Model')
ax.grid(color="b", alpha=0.5, linestyle="dashed", linewidth=0.5)
ax.set_ylim([0, np.max([prey, predator])])
# create a space in the figure to place the two sliders:
axcolor = 'lightgoldenrodyellow'
axis_N = fig.add_axes([0.10, 0.1, 0.8, 0.03], facecolor=axcolor)
axis_P = fig.add_axes([0.10, 0.15, 0.8, 0.03], facecolor=axcolor)
# the first argument is the rectangle, with values in percentage of the figure
# size: [left, bottom, width, height]
# create each slider on its corresponding place:
slider_N = Slider(axis_N, 'N', Nmin, Nmax, valinit=N0)
slider_P = Slider(axis_P, 'P', Pmin, Pmax, valinit=P0)
def update(val):
# retrieve the values from the sliders
x = [slider_N.val, slider_P.val]
# recalculate the function values
prey, predator = odeint(lotka, x, t, args=(params,)).T
# update the value on the graph
prey_plot.set_ydata(prey)
predator_plot.set_ydata(predator)
# redraw the graph
fig.canvas.draw_idle()
ax.set_ylim([0, np.max([prey, predator])])
# set both sliders to call update when their value is changed:
slider_N.on_changed(update)
slider_P.on_changed(update)
# create the reset button axis (where its drawn)
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
# and the button itself
button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')
def reset(event):
slider_N.reset()
slider_P.reset()
button.on_clicked(reset)
Notice, however, you should have shown how you tried to adapt the example to what you had and how it was misbehaving.
Nevertheless, welcome to Stackoverflow.
So, I have tried with this code:
from scipy import integrate
from matplotlib.widgets import Slider, Button, RadioButtons
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
plt.xlabel("Time")
plt.ylabel("Population size")
plt.legend(["Prey", "Predator"], loc="upper right")
plt.title('Prey & Predator Static Model')
plt.grid(color="b", alpha=0.5, linestyle="dashed", linewidth=0.5)
l1, l2 = plt.plot(t, equation)
axcolor = 'b'
ax_N = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor)
ax_P = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)
sN = Slider(ax_N, 'N', 0, 80, valinit=1)
sP = Slider(ax_P, 'P', 0, 80, valinit=1)
def update(val):
N = N*sN.val
P = P*sP.val
x = equation
fig.canvas.draw_idle()
l1, l2.set_ydata(y)
ax.set_ylim(y.min(), y.max())
draw()
sN.on_changed(update)
sP.on_changed(update)
plt.show()
I could not manipulate the sliders. Thank you so much #berna1111
I have developed a code that works perfectly fine but now I want to show it to my professor without always having to take my computer with me. The code is:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
a = 0.5
X, Y = np.mgrid[0:1.05:0.025, 0:1.05:0.025]
varX = #Some equation with X, Y and a (as a parameter)
varY = #Some other equation
U = varX-X
V = varY-Y
length = np.sqrt(U**2 + V**2)
fig, ax = plt.subplots()
Q = plt.quiver(X, Y, varX-X, varY-Y,
color='r',
scale=3*(2 ** .5), units='y')
plt.subplots_adjust(left=0.25, bottom=0.25)
plt.axis([0, 1, 0, 1])
axcolor = 'lightgoldenrodyellow'
axa = plt.axes([0.25, 0.10, 0.65, 0.03], axisbg=axcolor)
sa = Slider(axa, 'Alfa', 0, 1, valinit=a)
def update(val):
a = sa.val
varX = #Same equation as before
varY = #Same equation
Q.set_UVC(varX - X, varY - Y)
fig.canvas.draw_idle()
sa.on_changed(update)
resetax = plt.axes([0.8, 0.025, 0.1, 0.04])
button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975')
def reset(event):
sa.reset()
button.on_clicked(reset)
plt.show()
As I said, this code works like a charm, but how could I "save" the result? I have thought on making an html-js version, but couldn't make a Bokeh similar version for it and mpld3 doesn't seem to support sliders...
Thanks in advance,
Javirk
finally I could figure it out myself. I had to use "segment" instead of "multi_line" because I didn't want to set up a server. The code:
from __future__ import division
import numpy as np
from bokeh.layouts import row, widgetbox
from bokeh.models import CustomJS, Slider
from bokeh.plotting import figure, output_file, show, ColumnDataSource
#Declaration of variables
xx = np.linspace(0, 1, 50)
yy = np.linspace(0, 1, 50)
Y, X = np.meshgrid(xx, yy)
x0 = X[::2, ::2].flatten()
y0 = Y[::2, ::2].flatten()
#Equations and so, result: x1,y1 with same dimensions as x0,y0
#x1,y1 are the coordinates of the final point of the segment
source = ColumnDataSource(data=dict(x0=x0, y0=y0, x1=x1, y1=y1))
#Plot
plot = figure(x_range=(0, 1), y_range=(0, 1), x_axis_label='H', y_axis_label='C',
title="Retrato de fases. Modelo simplificado")
plot.segment('x0', 'y0', 'x1', 'y1', source=source, line_width=1)
#JS function that activates when slider value is changed
callback = CustomJS(args=dict(source=source), code="""
var data = source.data;
var alpha = alpha.value;
x0 = data['x0'];
y0 = data['y0'];
x1 = data['x1'];
y1 = data['y1'];
for (i = 0; i < x0.length; i++) {
#Same equations as before, but written in JS
}
source.trigger('change');
""")
#Set up all the sliders
alfa_slider = Slider(start=0, end=1, value=alpha, step=.01, title="Alpha", callback=callback)
callback.args["alpha"] = alpha_slider
output_file("slider.html", title="Phase Portrait")
layout = row(
plot,
widgetbox(alpha_slider),
)
show(layout)