Python-programmatuur bij Functie met je GR onderzoeken
FunCties tekenen in Python
Het tekenen van de functies gebeurt met matplotlib. Dat is vrij technisch. Hieronder worden enkele details uitgelegd die wij gebruiken. Voor andere details moet je kijken op internet.
- Numpy heeft een procedure $linspace$ die een lijst van $x$-waarden genereert, gegeven $X_0$ en $X_1$. De derde variabele is $NP$, het aantal punten dat wordt getekend. Om de Bezier-kromme te tekenen (zie 6. en 7.) wordt dan gebruik gemaakt van een parameterkromme (bewegingsvergelijking).
We hebben hier te maken met een aantal $t$-waarden en drukken $x$ en $y$ uit in $t$. - In elke functie maken we gebruik van $fig = plt.figure(figsize=(6, 6), dpi=150)$. Door de waarde achter $dpi$ aan te passen kun je een plaatje krijgen met hogere of lagere resolutie, belangrijk voor je werkstuk.
- Ook keert $ax = fig.add\_subplot(1, 1, 1)$ altijd terug. In principe kun je verschillende plotten naast en onder elkaar plaatsen. Daarvoor moeten de coördinaten worden aangepast.
- Met $plt.plot(x,y, ‘r’,label=‘y=ln(x)’)$ wordt uiteindelijk de functie getekend. $x, y$ zijn de $x$ en $y$-coördinaat. Daarna volgt de kleur ($‘r’$ staat voor rood, $‘b’$ voor blauw en $‘g’$ voor groen. Tenslotte kan er voor worden gekozen om een $label$ mee te geven. Enkele regels verder op staat $legend$. Hier kun je aangeven waar deze labels worden geplaatst.
- Hierboven werd simpel gebruik gemaakt van $‘r’$ om een kleur weer te geven. Er zijn bijzonder veel benamingen. Los daarvan kun je er ook voor kiezen om zelf een kleur te kiezen uit het RGB-spectrum. De basiskleuren op de computer zijn rood, groen en blauw. Die varieren allen van $0$ tot $1$. $c = (0, 0, 0) $ levert het ontbreken van deze drie kleuren op, dus zwart en $c = (1, 1, 1)$ is wit. Voor $N = 100$ kun je met $c = (i/N, 0, 1-i/N)$ langzaam van rood naar blauw gaan in $100$ stappen.
VersChillen met de GR's van Texas Instruments en Numworks
De grafische rekenmachines hebben een beperkt geheugen en bevatten bij lange na niet alle bibliotheken van Python. Bovendien heeft Texas Instruments (voor de TI-84CE-T Python Editie) een eigen plot-bibliotheek (ti_plotlib) en heeft de plot-bibliotheek van Numworks net wat andere functionaliteit. Bij dat laatste heeft het team van Numworks zelf ons bijgestaan.
Dat betekent dat je de standaard Python-programmatuur op een aantal plaatsen moet aanpassen.
Numpy
Beide GR's kunnen geen gebruik maken van Numpy. Dat betekent dat de procedure $linspace$ niet gebruikt kan worden, en bovendien het werken met arrays iets anders moet. In onderstaande programmatuur betekent dat vooral het volgende.
De constructie
x = linspace(A, B, N)
moet herschreven worden naar
x = [A + i*(B-A)/(N-1) for i in range(N)]
Het werken met een vector $x$ moet dan verder aangepast. In plaats van
x = wiskundige_bewerking(x)
moet je schrijven
x = [wiskundige_bewerking(xi) for xi in x]
Mathplotlib
Om te beginnen heeft de TI dus een eigen plotlib. Dus op de TI schrijf je niet
import mathplotlib.pyplot as plt
maar
import ti_plotlib as plt
Verder zijn er al dan niet subtiele verschillen tussen de plot-bibliotheken.
Op de GR kun je om te beginnen geen figure definiëren met subplots. Ook de assen kun je niet afzonderlijk benaderen.
De kleuren in RGB lopen op een GR van $0$ tot $255$ en niet van $0$ tot $1$ zoals in standaard Python.
Verder moet je op de TI vóór je een punt tekent de kleur instellen, en vervolgens een stip ('.') apart tekenen, met
plt.color(waardeR, waardeG, waardeB) plt.plot(x,y,'.')
terwijl je op de Numworks de kleur als vector invoert:
plt.plot(x,y,[waardeR, waardeG, waardeB])
Bovendien moet je op de TI eerst handmatig het scherm leegmaken en het window handmatig op de juiste dimensies zetten:
plt.cls() plt.window(x_min, x_max, y_min, y_max)
Op dit moment heb ik nog niet goed in de gaten hoe ik alle labels en titels kan toevoegen aan de figuren, evenmin de legenda.
Geheugen
Ten slotte heeft de beperking van het geheugen ook tot gevolg dat je minder punten of lijnen kunt tekenen. In het algemeen zul je de waarde van $NP$ (flink) moeten verlagen, evenals sommige andere waarden. Bij de vulkaan kun je minder paden van lavabommen tekenen.
De programmatuur zelf (standaard Python)
# 4. Natuurlijke logaritme (Opgave 1-3) import matplotlib.pyplot as plt import numpy as np import math PN = 100 PU = 1/PN X0 = 17*PU X1 = 4.5 x1 = np.linspace(X0, X1, PN) x2 = np.linspace(-X1, X1, PN) #p = np.exp(1) # Hiermee raken de krommen p = 2.65 # Hiermee raken de krommen net niet Titel = 'log(x) en exp(x)' f1 = p*np.log(x1) f2 = np.exp(x2/p) f3 = x2 Xas = 0 Yas = 0 fig = plt.figure(figsize=(6, 6), dpi=150) ax = fig.add_subplot(1, 1, 1) ax.spines['left'].set_position(('data',Yas)) ax.spines['bottom'].set_position(('data',Xas)) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.set_title(Titel) plt.plot(x1,f1, 'r',label='y=ln(x)') plt.plot(x2,f2, 'b',label='y=e^x') plt.plot(x2,f3, 'g',label='y=x') plt.axis('equal') plt.legend(loc='upper left') plt.show()
# 5. Natuurlijke logaritme (Opgave 1-3) # Uitvergroting rondom het raakpunt. import matplotlib.pyplot as plt import numpy as np import math PN = 100 PU = 1/PN X0 = 2.3 X1 = 3 x1 = np.linspace(X0, X1, PN) x2 = np.linspace(X0, X1, PN) #p = np.exp(1) # Hiermee raken de krommen p = 2.7 # Hiermee raken de krommen net niet Titel = 'log(x) en exp(x)' f1 = p*np.log(x1) f2 = np.exp(x2/p) f3 = x2 Xas = X0 - 0.1 Yas = X0 - 0.1 fig = plt.figure(figsize=(6, 6), dpi=150) ax = fig.add_subplot(1, 1, 1) ax.spines['left'].set_position(('data',Yas)) ax.spines['bottom'].set_position(('data',Xas)) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.set_title(Titel) plt.plot(x1,f1, 'r',label='y=ln(x)') plt.plot(x2,f2, 'b',label='y=e^x') plt.plot(x2,f3, 'g',label='y=x') plt.axis('equal') plt.legend(loc='upper left') plt.show()
# 6. Bezierkromme (Opgave 7) # x(t) = -4t^2+6t # y(t) = 6t^2-8t+4 import matplotlib.pyplot as plt import numpy as np import math PN = 100 T0 = 0.2 T1 = 1 Ax = 0 Ay = 4 Bx = 2 By = 2 Cx = 3 Cy = 0 x = (1-t)**2*Ax + t**2*Bx + 2*t*(1-t)*Cx y = (1-t)**2*Ay + t**2*By + 2*t*(1-t)*Cy t = np.linspace(T0, T1, PN) Titel = 'Bezier' Xas = 1.2 Yas = 1 fig = plt.figure(figsize=(6, 6), dpi=150) ax = fig.add_subplot(1, 1, 1) ax.spines['left'].set_position(('data',Yas)) ax.spines['bottom'].set_position(('data',Xas)) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.set_title(Titel) plt.plot(x,y, 'r') plt.axis('equal') plt.show()
# 7. Bezierkrommem (Opgave 7) # x(t) = -4t^2+6t # y(t) = 6t^2-8t+4 # Je kunt zelf eens proberen om het punt C een andere baan te laten beschrijven. import matplotlib.pyplot as plt import numpy as np import math PN = 100 T0 = 0 T1 = 1 Ax = 0 Ay = 4 Bx = 2 By = 2 t = np.linspace(T0, T1, PN) Titel = 'Beziers' Xas = 1.2 Yas = -1 CRange = 160 fig = plt.figure(figsize=(6, 6), dpi=150) ax = fig.add_subplot(1, 1, 1) ax.spines['left'].set_position(('data',Yas)) ax.spines['bottom'].set_position(('data',Xas)) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.set_title(Titel) for i in range(CRange): Cx = 3 - 5*i/CRange Cy = 0 x = (1-t)**2*Ax + t**2*Bx + 2*t*(1-t)*Cx y = (1-t)**2*Ay + t**2*By + 2*t*(1-t)*Cy plt.plot(x,y, c = (i/CRange, 0, 1-i/CRange)) plt.axis('equal') plt.show()
# 8. Gebroken sinuskromme (Opgave 8) # Let op het was nog wel een gepuzzel om bij de polen (plaatsen waar de functie # niet bestaat) een gebiedje te definieren waar geen functiewaarden worden # berekend. import matplotlib.pyplot as plt import numpy as np import math Pi2 = math.pi/2 PN = 100 PUP = 1/6 PU = 1/1000 X0 = -3 X1 = 3 x1 = np.linspace(X0, X1, PN) x2 = np.linspace(X0, -Pi2-PUP, PN) x3 = np.linspace(-Pi2+PUP, -PU, PN) x4 = np.linspace(PU, Pi2-PUP, PN) x5 = np.linspace(Pi2+PUP, X1, PN) Titel = 'sin(x) en sin(x)/sin(2x)' f1 = np.sin(x1) f2 = np.sin(x2)/np.sin(2*x2) f3 = np.sin(x3)/np.sin(2*x3) f4 = np.sin(x4)/np.sin(2*x4) f5 = np.sin(x5)/np.sin(2*x5) Xas = 0 Yas = 0 fig = plt.figure(figsize=(6, 8), dpi=150) ax = fig.add_subplot(1, 1, 1) ax.spines['left'].set_position(('data',Yas)) ax.spines['bottom'].set_position(('data',Xas)) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.set_title(Titel) #plt.plot(range(5)) plt.plot(x1,f1, 'r',label='y=sin(x)') plt.plot(x2,f2, 'b',label='y=sin(x)/sin(2x)') plt.plot(x3,f3, 'b') plt.plot(x4,f4, 'b') plt.plot(x5,f5, 'b') plt.axis('equal') plt.legend(loc='upper left') plt.show()
# 9. Evenwijdige raaklijnen. Opgave 9 - 11 # De berekening die ten grondslag ligt voor de tekening is hier niet # terug te vinden. Kijk daarvoor bij de uitwerkingen van het eindexamen. import matplotlib.pyplot as plt import numpy as np import math PN = 1000 PU = 1/PN X0 = 0 X1 = 2.5 x = np.linspace(X0, X1, PN) x2 = np.linspace(-1, X1-1.5, PN) x3 = np.linspace(11/16, X1, PN) Titel = 'x^2-2x^1.5+x' f = x*x+x-2*x*np.sqrt(x) g = x2 h = x3-27/16 Xas = X0 Yas = X0 fig = plt.figure(figsize=(6, 6), dpi=150) ax = fig.add_subplot(1, 1, 1) ax.spines['left'].set_position(('data',Yas)) ax.spines['bottom'].set_position(('data',Xas)) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.set_title(Titel) plt.plot(x,f, 'r') plt.plot(x2,g, 'b') plt.plot(x3,h, 'g') plt.axis('equal') #plt.legend(loc='upper center') plt.show()
# 10. Vulkaan, Opgave 12 - 14 # ta = tan(alpha) # y = -(1 + ta^2)/x^2*9000 + ta*x + 2000 # # Hier zijn in een tekening meerdere functies met varierende alpha # getekend. import matplotlib.pyplot as plt import numpy as np import math Pi = math.pi Titel = 'Vulkaan' fig = plt.figure(figsize=(6, 6), dpi=150) ax = fig.add_subplot(1, 1, 1) ax.spines['left'].set_position(('data',Yas)) ax.spines['bottom'].set_position(('data',Xas)) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.set_title(Titel) RNG = 100 BND = 3.9 RST = 1/2-1/BND XX = 9000 * 4250 X = math.sqrt(XX) for ii in range(RNG+1): i = RNG-ii alpha = (1/(BND*RNG) * (i-4) + RST) * Pi ta = math.tan(alpha) a = -(1 + ta**2)/9000 b = ta c = 2000 disc = b*b - 4*a*c worteldisc = math.sqrt(disc) X0 = (-b+worteldisc)/(2*a) X1 = (-b-worteldisc)/(2*a) PN = round((X1-X0)/100) xm = np.linspace(-X1, 0, PN) fm = a*xm**2 - b*xm + c plt.plot(xm, fm, c = (i/RNG, 0.5-i/(2*RNG), 1-i/RNG)) xp = np.linspace(0, X1, PN) fp = a*xp**2 + b*xp + c plt.plot(xp,fp, c = (i/RNG, 0.5-i/(2*RNG), 1-i/RNG)) PN = round(X/50) x = np.linspace(-X, X, PN) f = -x**2/9000 + 4250 plt.plot(x,f, c = (0,1,0)) Xas = 0 Yas = -7000 #Yas = 0 plt.axis('equal') #plt.legend(loc='upper center') plt.show()
# 11. Scheve asymptoot, Opgave 15 import matplotlib.pyplot as plt import numpy as np import math Titel = 'x + 2/x' Xas = 0 Yas = 0 fig = plt.figure(figsize=(6, 6), dpi=150) ax = fig.add_subplot(1, 1, 1) ax.spines['left'].set_position(('data',Yas)) ax.spines['bottom'].set_position(('data',Xas)) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.set_title(Titel) PN = 500 PU = 1/PN X0 = 0.3 X1 = 6 p0 = 0.6 p1 = 3.7 RNG = 150 X0 = 0 # g = x # x = np.linspace(X0, X1, PN) # plt.plot(x,g, 'b',label='y=x') for i in range(RNG+1): p = p0 + i*(p1-p0)/RNG fp = p + 2/p rcp = 1-2/p**2 cnt = fp - p*rcp X2 = -cnt/rcp if rcp < 0: XX0 = X0 XX1 = min(X1,X2) else: XX0 = max(X0,X2) XX1 = X1 x = np.linspace(XX0, XX1, PN) h = rcp*x + cnt plt.plot(x,h, c = (0, 1-i/RNG, i/RNG)) X0 = 0.3 X1 = 6 x = np.linspace(X0, X1, PN) f = x + 2/x plt.plot(x,f, 'r') # plt.legend(loc='upper center') plt.axis('equal') plt.show()