CoCalc Public FilesSage Graphing Tools-version 4.sagews
Author: michael mckenzie
Views : 111
import numpy
from math import isnan

def findFunctionPoints (f, filter, steps=5):
"""
This creates and returns an array of values for a function based on the value of the independent variable
The points are created between the values 'xmin' and 'xmax'. This is called the domain of the independent variable
The points are chosen so that there are 'steps' number of intervals (spaces between two points) across the domain.
We multiply xmax by 1 + 1/steps to create a point that is one step beyond the range.
The array returnd is a one dimensional array of two dimensional tuples (x,f(x))
"""
points = []
global domMin, domMax, inverseOn, inverseSaveDom, aspectRatio
if inverseOn:
xmin, xmax = inverseSaveDom
inverseOn = False
for i in numpy.arange(domMin, domMax*(1+2/steps), (domMax - domMin)/steps):
try:
f(i)
except ValueError:
i=i-.00001
if f(i) in RR and not isnan(f(i)):
abscissa = i
if filter == 'normal':
ordinate = f(i)
elif filter == 'input negative':
ordinate = f(-i)
elif filter == 'negative':
ordinate = -f(i)
elif filter == 'absolute value':
ordinate = abs(f(i))
elif filter == 'square':
ordinate = f(i)^2
elif filter =='inverse':
inverseOn = True
inverseSaveDom = (domMin, domMax)
ordinate = i
abscissa = f(i)
points.append((abscissa, ordinate))
#             if abscissa > domMax:
#                 domMax = abscissa
#             if abscissa < domMin:
#                 domMin = abscissa
else:
continue
return points

def createSlopeFunction (points):
"""
This creates a points array of the slope between two points and assigns that value as an estimate of the slope of the curve at the higher valued point.
The array returned is a one dimensional array of two dimensional tuples (x,slope at x)
"""
global domMin, domMax
newPoints = []
slopeFunctionGraph = plot(0)
first = True
for firstPoint in points:
if first:
lastPoint = firstPoint
first = False
continue
slope = (firstPoint[1]-lastPoint[1])/(firstPoint[0]-lastPoint[0])
lastPoint = firstPoint
newPoints.append((firstPoint[0],slope))
return newPoints

def plotPoints (points,ymin,ymax):
"""
This function takes a points array and plots it on a graph
It returns the graph
"""
global domMin, domMax
Graph = plot(0)
strongGraph = plot(0)
pointsGraph = []
markerColor = 'deepskyblue'
for p in points:
Graph += point(p,xmin=domMin,xmax=domMax,size=150,color=markerColor,marker='h',alpha=0.4)
strongGraph = point(p,xmin=domMin,xmax=domMax,size=600,color=markerColor,marker='h',alpha=1)
pointsGraph.append(Graph+strongGraph)
return pointsGraph

def showContinuity (points):
"""
This function takes a points array and plots it as segments on a graph
"""
global domMin, domMax
thickness = 2
color = 'maroon'
segmentsGraph = line(points,xmin=domMin,xmax=domMax,thickness=thickness,color=color)
return segmentsGraph

def plotSegments (points,ymin,ymax):
"""
This function takes a points array and plots it as segments on a graph
"""
global domMin, domMax
segmentsGraph = line(points,xmin=domMin,xmax=domMax)
color = 'maroon'
thickness = 2
Graph = plot(0,ymin=ymin,ymax=ymax)
segmentsGraph = []
first = True
for firstPoint in points:
if first:
lastPoint = firstPoint
first = False
continue
slope = (firstPoint[1]-lastPoint[1])/(firstPoint[0]-lastPoint[0])
if slope <= 0:
slopeColor = 'red'
else:
slopeColor = 'lime'
rise = firstPoint[1]-lastPoint[1]
run = firstPoint[0]-lastPoint[0]
if firstPoint[1] > lastPoint[1]:
thirdPoint = (firstPoint[0],lastPoint[1])
else:
thirdPoint = (lastPoint[0],firstPoint[1])
g(x) = slope*(x-firstPoint[0]) + firstPoint[1]
boldGraph = line([firstPoint, lastPoint],xmin=domMin,xmax=domMax,color=color,alpha=1,thickness=thickness+1,ymin=ymin,ymax=ymax)
boldGraph += line([firstPoint,thirdPoint],xmin=domMin,xmax=domMax, color=slopeColor,alpha=1,linestyle=':',thickness=thickness,ymin=ymin,ymax=ymax)
boldGraph += line([lastPoint,thirdPoint],xmin=domMin,xmax=domMax,color=slopeColor,alpha=1,linestyle=':',thickness=thickness,ymin=ymin,ymax=ymax)
if firstPoint[1]<=ymax and firstPoint[1]>=ymin and lastPoint[1]<=ymax and lastPoint[1]>=ymin:
if firstPoint[1] > lastPoint[1]:
midPoint = (((firstPoint[0]+thirdPoint[0])/2),((firstPoint[1]+thirdPoint[1])/2))
boldGraph += text('rise',midPoint,xmin=domMin,xmax=domMax,color='black',alpha=1,ymin=ymin,ymax=ymax)
midPoint = (((lastPoint[0]+thirdPoint[0])/2),((lastPoint[1]+thirdPoint[1])/2))
boldGraph += text('run',midPoint,xmin=domMin,xmax=domMax,color='black',alpha=1,ymin=ymin,ymax=ymax)
else:
midPoint = (((firstPoint[0]+thirdPoint[0])/2),((firstPoint[1]+thirdPoint[1])/2))
boldGraph += text('run',midPoint,xmin=domMin,xmax=domMax,color='black',alpha=1,ymin=ymin,ymax=ymax)
midPoint = (((lastPoint[0]+thirdPoint[0])/2),((lastPoint[1]+thirdPoint[1])/2))
boldGraph += text('rise',midPoint,xmin=domMin,xmax=domMax,color='black',alpha=1,ymin=ymin,ymax=ymax)
#         show(boldGraph)
Graph += line([firstPoint,lastPoint],xmin=domMin,xmax=domMax,color=color,alpha=0.5,thickness=thickness,ymin=ymin,ymax=ymax)
segmentsGraph.append(Graph+boldGraph)
lastPoint = firstPoint
return segmentsGraph

def plotSlopes (points, shiftText,ymin,ymax):
"""
This function calculates the slope between any two consecutive pounts in a points array.
It then displays those points on a graph between the two points by calculating the midpoint and thnr shifting it down 1.5 pixels to make room for a line.
It returns the graph
"""
global domMin, domMax
maxPlots = 30
modBase = (len(points)+(50-1))//50
Graph = plot(0)
strongGraph = plot(0)
slopeGraph = []
#
first = True
for firstPoint in points:
if first:
lastPoint = firstPoint
first = False
continue
slope = (firstPoint[1]-lastPoint[1])/(firstPoint[0]-lastPoint[0])
color = 'red'
if slope >= 0:
color = 'lime'
plotAt = (((firstPoint[0]+lastPoint[0])/2),((firstPoint[1]+lastPoint[1])/2)-shiftText)
markerAt = (plotAt[0],slope)
if plotAt[1]<=ymax and plotAt[1]>=ymin:
Graph += point(markerAt,xmin=domMin,xmax=domMax,size=200,color=color,marker='*',alpha=0.5)
strongGraph = point(markerAt,xmin=domMin,xmax=domMax,size=800,color=color,marker='*',alpha=1)
Graph += text(str(slope.n(prec=4)),plotAt,xmin=domMin,xmax=domMax,color=color)
slopeGraph.append(Graph+strongGraph)
lastPoint = firstPoint
return slopeGraph

def plotLines (points,ymin,ymax):
"""
This function ceates a linear funtion of the line between any two consecutive pounts in a points array.
1. canculate the slope between two points
2. use the slope and one of the points to create the fucntion g(x)
It then displays those lines on a graph between the two points.
It returns the graph
"""
global domMin, domMax
thickness = 2
color = 'chocolate'
markerColor = 'deepskyblue'
Graph = plot(0)
lineGraph = []
first = True
for firstPoint in points:
if first:
lastPoint = firstPoint
first = False
continue
slope = (firstPoint[1]-lastPoint[1])/(firstPoint[0]-lastPoint[0])
g(x) = slope*(x-firstPoint[0]) + firstPoint[1]
boldGraph = plot(g(x),xmin=domMin,xmax=domMax,color=color,alpha=1,thickness=thickness+1)
boldGraph += point(firstPoint,xmin=domMin,xmax=domMax,size=600,color=markerColor,marker='h',alpha=1)
boldGraph += point(lastPoint,xmin=domMin,xmax=domMax,size=600,color=markerColor,marker='h',alpha=1)
Graph += plot(g(x),xmin=domMin,xmax=domMax,color=color,alpha=0.5,thickness=thickness)
lineGraph.append(Graph+boldGraph)
lastPoint = firstPoint
return lineGraph

# Main Procedure

# Global Variables

domMin = -10
domMax = 10
xStep = 0.25
inverseOn = False
inverseSaveDom = (domMin, domMax)
Xrange = (domMin, domMax)
aspectRatio = 100
fileCount = 1

@interact (width=200,auto_update=False)
def _(  #f         = input_box      (default=((x+4)*(x+1)*(x-1)*(x-4)).expand(), label='function'),
f         = selector       ([(x+4)*(x-5),
-(x-3)(x+4)
(x+4)*(x+1)*(x-5),
(x+5)*(x+2)*(x-1)*(x-4),
1/x,
1/(x-3)+4,
sqrt(x-3)+2,
e^x,
e^(x+2)-3,
log(x),
log(x+3),
1-e^-x
],label = 'function',buttons=False, width=50),
xrange    = range_slider   (round(domMin*2),round(domMax*2),xStep,label='xrange',default=(domMin/2, domMax/2),width = 200),
yrange    = range_slider   (-400,500,10,label='yrange',default=(-50, 100),width = 200),
type      = selector       (['table','points','lines','segments','plot'],label = 'type',buttons=true, width=20, default= 'table'),
level     = selector       (['function','derivative','2nd derivative','continuity'],label = 'level',buttons=true, width=20, default= 'function'),
tables    = selector       (['function','derivative','2nd derivative'],label = 'tables',buttons=false, width=20, default= 'function'),
showSlope = checkbox       (label = 'Show Slopes', default= False),
animateGr = checkbox       (label = 'Show Animation', default= True),
logAnis   = checkbox       (label = 'Log Animations', default= True),
filter    = selector       (['normal', 'negative','absolute value','square', 'inverse'],label = 'filter',buttons=true, width=20, default= 'normal'),
shiftText = slider         (-50,30,1,label='shift',default=20,width = 20),
aspect    = slider         (1,300,1,label='aspect',default=100,width = 20),
deltaX    = slider         (5,100,1,label='deltaX',default=5,width = 20),
fName     = input_box      (default="general quartic", type=str, label='Log File Name'),
):

global fileCount, domMin, domMax, Xrange, aspectRatio
f=f.expand()

def displayOutput(Points, plotFunction):
global fileCount
graphs = plotFunction(Points,ymin,ymax)
slopeGraphs = plotSlopes(Points, -shiftText,ymin,ymax)
if not animateGr:
thePlot = graphs[len(graphs)-1]
if showSlope:
thePlot += slopeGraphs[len(slopeGraphs)-1]
thePlot.show(figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax)
else:
if showSlope:
for i in range(len(slopeGraphs)):
graphs[i] += slopeGraphs[i]
graphs[len(graphs)-1] += slopeGraphs[len(slopeGraphs)-1]
show(animate(graphs,figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":")),delay=500/deltaX)
if logAnis:
a=animate(graphs,figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":"))
a.gif(savefile = 'graph log files/'+fName+str(fileCount)+'.gif',delay=500/deltaX,iterations=2)
fileCount += 1

domMin, domMax = xrange
ymin, ymax = yrange
deltaXRange = 1
aspectRatio = aspect
functionPoints = findFunctionPoints(f, filter=filter, steps=deltaX)
slopeFunctionPoints = createSlopeFunction(functionPoints)
secondSlopeFunctionPoints = createSlopeFunction(slopeFunctionPoints)
html('<h1 align=center>Function Plotting Toolkit</h1>')
if filter == 'normal':
show(f)
elif filter == 'negative input':
show(f(-x))
elif filter == 'negative input':
show(-f)
elif filter == 'absolute value':
show(abs(f))
elif filter == 'square':
show(f^2)
elif filter =='inverse':
show(f)
if level == 'function':
if type == 'plot':
if filter == 'normal':
showPlot = plot(f(x),figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":"))
showPlot.show()
showPlot.save('graph log files/'+fName+str(fileCount)+'.pdf')
fileCount += 1
elif filter == 'negative':
plot(-f(x) ,figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":")).show()
elif filter == 'absolute value':
plot(abs(f(x)),figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":")).show()
elif filter == 'square':
plot(f(x)^2,figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":")).show()
elif filter =='inverse':
plot(f(x),figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":")).show()
elif type == 'segments':
displayOutput(functionPoints, plotSegments)
elif type == 'points':
displayOutput(functionPoints, plotPoints)
elif type == 'lines':
displayOutput(functionPoints, plotLines)
elif type == 'table':
if tables == 'function':
tempTable = []
for row in range(0,len(functionPoints)):
tempTable.append([round(functionPoints[row][0],2), round(functionPoints[row][1],2)])
pointsTable = table(tempTable,header_row=['$x$',"$y=f(x)$",],frame=True, align='right')
tempTable.insert(0,['$x$',"$y=f(x)$"])
if tables == 'derivative':
tempTable = []
for row in range(0,len(slopeFunctionPoints)):
tempTable.append([round(functionPoints[row+1][0],2), round(functionPoints[row+1][1],2), round(slopeFunctionPoints[row][1],2)])
pointsTable = table(tempTable,header_row=['$x$',"$y=f(x)$", "$y=f'(x)$"],frame=True, align='right')
tempTable.insert(0,['$x$',"$y=f(x)$", "$y=f'(x)$"])
if tables == '2nd derivative':
tempTable = []
for row in range(0,len(secondSlopeFunctionPoints)):
tempTable.append([round(functionPoints[row+2][0],2), round(functionPoints[row+2][1],2) , round(slopeFunctionPoints[row+1][1],2), round(secondSlopeFunctionPoints[row][1],2)])
pointsTable = table(tempTable,header_row=['$x$',"$y=f(x)$", "$y=f'(x)$", "$y=f''(x)$"], frame=True, align='right')
tempTable.insert(0,['$x$',"$y=f(x)$", "$y=f'(x)$", "$y=f''(x)$"])
try:
show(pointsTable)
openFile = open('graph log files/'+fName+str(fileCount)+'.txt', 'w')
openFile.write(str(pointsTable))
fileCount += 1
except Exception as errmsg:
print('table print error')
elif level == 'derivative':
pretty_print('derivative',f.derivative(x))
if type == 'plot':
plot(f(x).derivative(x) ,figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":")).show()
elif type == 'segments':
displayOutput(slopeFunctionPoints, plotSegments)
elif type == 'points':
displayOutput(slopeFunctionPoints, plotPoints)
elif type == 'lines':
displayOutput(slopeFunctionPoints, plotLines)
elif type == 'table':
try:
show((table([(n(i[0],prec=6),n(i[1],prec=15)) for i in slopeFunctionPoints],header_row=['$x$',"$y=f'(x)$"],frame=True, align='right')))
except Exception as errmsg:
tempTable = ([(n(i[0],prec=6),n(i[1],prec=15)) for i in secondSlopeFunctionPoints])
tempTable.insert(0,['$x$',"$y=f(x)$"])
elif level ==  '2nd derivative':
pretty_print('derivative',f.derivative(x))
pretty_print('2nd derivative', f.derivative(x).derivative(x))
if type == 'plot':
plot(f(x).derivative(x).derivative(x) ,figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":")).show()
elif type == 'segments':
displayOutput(secondSlopeFunctionPoints, plotSegments)
elif type == 'points':
displayOutput(secondSlopeFunctionPoints, plotPoints)
elif type == 'lines':
displayOutput(secondSlopeFunctionPoints, plotLines)
elif type == 'table':
try:
show((table([(n(i[0],prec=6),n(i[1],prec=15)) for i in secondSlopeFunctionPoints],header_row=['$x$',"$y=f''(x)$"],frame=True, align='right')))
except Exception as errmsg:
tempTable = ([(n(i[0],prec=6),n(i[1],prec=15)) for i in secondSlopeFunctionPoints])
tempTable.insert(0,['$x$',"$y=f''(x)$"])
elif level == 'continuity':
domMin, domMax = xrange
segmentsGraph = []
Graph = plot(0)
for i in range(5,30):
color = 'red'
functionPoints = findFunctionPoints(f, filter=filter, steps=i)
segmentGraph = line(functionPoints,xmin=domMin,xmax=domMax,ymin=ymin,ymax=ymax,color='red',alpha=1,thickness=2)
segmentsGraph.append(segmentGraph)
for i in range(len(functionPoints)):
if i >= len(functionPoints)-1:
break
else:
firstPoint = functionPoints[i]
lastPoint = functionPoints[i+1]
if firstPoint[1]<ymin or firstPoint[1]>ymax:
continue
slope = (firstPoint[1]-lastPoint[1])/(firstPoint[0]-lastPoint[0])
g(x) = slope*(x-firstPoint[0]) + firstPoint[1]
boldGraph = plot(g(x),xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,color='slateblue',alpha=1,thickness=3)
segmentsGraph.append(segmentGraph+boldGraph)
show(animate(segmentsGraph,figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":")),delay=500/deltaX)
if logAnis:
a=animate(segmentsGraph,figsize=[10,6],xmin=domMin-xStep,xmax=domMax+xStep,ymin=ymin,ymax=ymax,gridlines='major',gridlinesstyle=dict(color="slategray", linestyle=":"))
a.gif(savefile = 'graph log files/'+fName+str(fileCount)+'.gif',delay=50,iterations=2)
fileCount += 1

/cocalc/lib/python2.7/site-packages/smc_sagews/sage_server.py:1234: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...) See http://trac.sagemath.org/5930 for details. flags=compile_flags), namespace, locals)
Interact: please open in CoCalc
@interact
def Midpoint(ShowSolution=checkbox(default=True, label='Check to show solution')):
x1=Integer(randint(-5,10))
x2=Integer(randint(-5,10))
y1=Integer(randint(-5,10))
y2=Integer(randint(-5,10))
html('Find the midpoint of $(%s,%s)$ and $(%s,%s)$.'% (x1,y1,x2,y2))
if ShowSolution==True:
html('$M=\\left(\\frac{(%s)+(%s)}{2},\\frac{(%s)+(%s)}{2}\\right)$'%(x1,x2,y1,y2))
html('$M=\\left(\\frac{%s}{2},\\frac{%s}{2}\\right)$'%(x1+x2,y1+y2))
if (x1+x2)/2 in ZZ or(x1+x2)/2 in ZZ:
html('$M=\\left(%s,%s\\right)$'%(latex((x1+x2)/2),latex((y1+y2)/2)))

Interact: please open in CoCalc
f=(x-2)*(x+2)*x
pretty_print(f.expand())

$\displaystyle x^{3} - 4 \, x$