CoCalc Public FilesSage Graphing Tools-version 4.sagewsOpen in with one click!
Author: michael mckenzie
Views : 30
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') html.table(rows=tempTable,header=True) 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)$"]) html.table(rows=tempTable,header=True) 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)$"]) html.table(rows=tempTable,header=True) 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
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())
x34x\displaystyle x^{3} - 4 \, x