ich möchte Buttons mit Matplotlib bauen nach diesem Vorbild: https://matplotlib.org/stable/gallery/a ... dulum.html, dabei hab ich mit dem Button "nächstes Bild" angefangen.
Als Beispiel wird das Newton-Verfahren zur Bestimmung von Nullstellen benutzt, die entsprechenden Daten wurden von einem anderen Skript bereits berechnet und sind unter "data" in der main-function eingefügt.
Der Code sieht wahrscheinlich nicht schön aus, funktioniert aber bisher ganz ok.
Der Knackpunkt ist jetzt, dass man eigentlich in der Funktion "next()" den Zähler i um 1 erhöhen sollte, damit durch Drücken des "Next-Buttons" immer eine neue Gerade gezeichnet wird, was bisher für die erste Gerade klappt. Gibt es da einen Weg, obwohl i nicht innerhalb von next() definiert wurde?
Alternativ müsste man eine Abfrage machen, á la "if Button pressed: i += 1" in der Funktion plot_Newton, aber ich hab noch nichts dazu gefunden, ob das mit matplotlib geht...
Es gibt zwar eine Methode get_active(), aber die gibt nur an, ob der Knopf überhaupt gedrückt werden kann oder nicht.
Hier der Code:
Code: Alles auswählen
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.widgets import Button
def f(x):
# Funktion, deren Nullstellen bestimmt werden soll (f(x) = 0).
return x**2 - 3*x - 5
def df(x):
# df/dx
return 2*x - 3
def gerade(x0, fx0, dfx0, x):
return dfx0*(x - x0) + fx0
def plot_Newton(data, i=0):
# Vorbereitungen; bleiben in jedem Plot gleich
data = np.array(data)
xvals = data[:, 0]
xmin, xmax = np.min(xvals), np.max(xvals)
xrange = xmax - xmin
x = np.linspace(xmin - .1*xrange, xmax + .1*xrange, 100)
f_x = f(x)
fmin, fmax = np.min(f_x), np.max(f_x)
frange = fmax - fmin
fig, ax = plt.subplots()
ax.axis([x[0], x[-1], fmin - .1*frange, fmax + .1*frange])
ax.plot(x, f_x, 'k--', label='f(x) = $x^2$ - 5x + 3')
# Zeichnen der Gerade, ändert sich für jeden Tupel in data, angegeben mit i
x0, fx0 = data[i, 0], data[i, 1]
dfx0 = df(x0)
y = gerade(x0, fx0, dfx0, x)
line, = ax.plot(x, y, 'r-', label=f"y = f'($x_0)\cdot x$ + b")
axnext = fig.add_axes([.05, .05, .1, .1])
def next(event):
x0, fx0 = data[i+1, 0], data[i+1, 1]
dfx0 = df(x0)
y = gerade(x0, fx0, dfx0, x)
line.set_ydata(y)
# hier soll die Variable i um 1 erhöht werden
plt.draw()
button_next = Button(axnext, 'Next')
button_next.on_clicked(next)
plt.show()
def main():
data = [(2, -7), (9.0, 49.0), (5.733333333333333, 10.671111111111113), (4.472965879265091, 1.5885261192744569),
(4.205804030830568, 0.07137545325894834), (4.1926147066138695, 0.0001739582732938061), (4.192582403761021, 1.0434764163846921e-09)]
plot_Newton(data, 0)
if __name__ == '__main__':
main()