Tkinter & matplotlib - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: GUI (https://python-forum.io/forum-10.html) +--- Thread: Tkinter & matplotlib (/thread-22658.html) |
Tkinter & matplotlib - PillyChepper - Nov-21-2019 Hey! I've been trying to solve a problem with matlib and Tkinter where i am unable to assign a number to points in a subplot. I'm trying to make a script for creating Bezier curves for my homework assignment and have been stuck on this. import tkinter from tkinter import * from matplotlib.backends.backend_tkagg import * from matplotlib.backend_bases import key_press_handler from matplotlib.figure import Figure from matplotlib import pyplot as plt from matplotlib import animation import numpy as np from scipy.special import comb def inputik(): global nPoints fig.clear("all") nPoints = int(pocetbodu_entry.get()) pocetbodu_entry.delete(0, "end") vykresleni() def bernstein_poly(i, n, t): """ Bernsteinův polynom t ... parametr n ... počet bodů i ... (počet bodů - 1) """ return comb(n, i) * ( t**(n-i) ) * (1 - t)**i def bezier_curve(points, nTimes=1000): """ Ze zadaných bodů a kroku sestrojí bezierovu křivku """ nPoints = len(points) xPoints = np.array([p[0] for p in points]) yPoints = np.array([p[1] for p in points]) t = np.linspace(0.0, 1.0, nTimes) polynomial_array = np.array([ bernstein_poly(i, nPoints-1, t) for i in range(0, nPoints) ]) xvals = np.dot(xPoints, polynomial_array) yvals = np.dot(yPoints, polynomial_array) return xvals, yvals def vykresleni(): if __name__ == "__main__": from matplotlib import pyplot as plt global ax1 #nPoints = (pocetbodu_entry.get()) points = np.random.rand(nPoints, 2) * 200 xpoints = [p[0] for p in points] ypoints = [p[1] for p in points] xvals, yvals = bezier_curve(points, nTimes=1000) ax1 = fig.add_subplot(111).plot(xvals, yvals) ax2 = fig.add_subplot(111).plot(xpoints, ypoints, "ro") for nr in range(len(points)): ax2.text(points[nr][0], points[nr][0], nr) for i in range(nPoints-1): pomocna_1x = [xpoints[i], xpoints[i+1]] pomocna_1y = [ypoints[i], ypoints[i+1]] ax3=fig.add_subplot(111).plot(pomocna_1x, pomocna_1y,'b--', linewidth=2) canvas.draw() # canvas a vykreslovací ploška root = tkinter.Tk() root.wm_title("Beziereček") fig = plt.Figure(figsize=(5, 4), dpi=100, frameon=False) canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea. canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) toolbar = NavigationToolbar2Tk(canvas, root) toolbar.update() canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) def on_key_press(event): print("you pressed {}".format(event.key)) key_press_handler(event, canvas, toolbar) canvas.mpl_connect("key_press_event", on_key_press) def konec(): root.quit() root.destroy() #tlačítka a blbítka pocetbodu = Label(root, text = "Počet řídících bodů: ") pocetbodu_entry = Entry(root) buttonQuit = Button(master=root, text="Quit", command=konec) buttonQuit.pack(side=tkinter.BOTTOM) buttonSubmit = Button(master=root, text="Submit", command=inputik) buttonSubmit.pack(side=tkinter.BOTTOM) pocetbodu_entry.pack(side=tkinter.BOTTOM) pocetbodu.pack(side=tkinter.BOTTOM) tkinter.mainloop()here's the problematic part #nPoints = (pocetbodu_entry.get()) points = np.random.rand(nPoints, 2) * 200 xpoints = [p[0] for p in points] ypoints = [p[1] for p in points] xvals, yvals = bezier_curve(points, nTimes=1000) ax1 = fig.add_subplot(111).plot(xvals, yvals) ax2 = fig.add_subplot(111).plot(xpoints, ypoints, "ro") for nr in range(len(points)): ax2.text(points[nr][0], points[nr][0], nr)since matlib is creating a weird list as ax2, I seem to be unable to assign the numbers to the indiviual points. Thanks in advance! Have a good day RE: Tkinter & matplotlib - Larz60+ - Nov-21-2019 You are trying to use an undefined object pocetbodu_entry
RE: Tkinter & matplotlib - PillyChepper - Nov-21-2019 (Nov-21-2019, 07:34 PM)Larz60+ Wrote: You are trying to use an undefined object pocetbodu_entry That is defined at the end pocetbodu = Label(root, text = "Počet řídících bodů: ") pocetbodu_entry = Entry(root) buttonQuit = Button(master=root, text="Quit", command=konec) buttonQuit.pack(side=tkinter.BOTTOM) buttonSubmit = Button(master=root, text="Submit", command=inputik) buttonSubmit.pack(side=tkinter.BOTTOM) pocetbodu_entry.pack(side=tkinter.BOTTOM) pocetbodu.pack(side=tkinter.BOTTOM)That shouldn't be the problem, because without the problematic part with the for cycle that should assign number to each points, the script works just fine, I just really need those points to be labeled RE: Tkinter & matplotlib - Larz60+ - Nov-22-2019 It needs to defined before you execute line 17 RE: Tkinter & matplotlib - PillyChepper - Nov-22-2019 (Nov-22-2019, 02:37 AM)Larz60+ Wrote: It needs to defined before you execute line 17 Line 17 is part of a function, which gets called after the button is called, this part is working fine. The variable succesfully gets its value from the entry line, problem is after that with the subplot from matlib. RE: Tkinter & matplotlib - Larz60+ - Nov-22-2019 Again: The error is: Which very clearly states that 'pocetbodu_entry' is not defined I suggest that you run step by step through a debugger and watch the program flow. RE: Tkinter & matplotlib - PillyChepper - Nov-22-2019 (Nov-22-2019, 04:43 PM)Larz60+ Wrote: Again: I am getting different error, I'm sorry if I am misunderstanding something, but as far as I can understand it, pocetbodu_entry is defined and works fine, its the line 68 which I can't figure out, without the for cycle on line 67, everything works fine and gets ploted.
RE: Tkinter & matplotlib - Larz60+ - Nov-22-2019 I recopied your script and am getting same error now. I'll revisit the code after I finish this session. RE: Tkinter & matplotlib - Larz60+ - Nov-22-2019 OK, now that My code copy is correct, I added some debugging printouts as follows: import tkinter from tkinter import * from matplotlib.backends.backend_tkagg import * from matplotlib.backend_bases import key_press_handler from matplotlib.figure import Figure from matplotlib import pyplot as plt from matplotlib import animation import numpy as np from scipy.special import comb def inputik(): global nPoints fig.clear("all") nPoints = int(pocetbodu_entry.get()) pocetbodu_entry.delete(0, "end") vykresleni() def bernstein_poly(i, n, t): """ Bernsteinův polynom t ... parametr n ... počet bodů i ... (počet bodů - 1) """ return comb(n, i) * ( t**(n-i) ) * (1 - t)**i def bezier_curve(points, nTimes=1000): """ Ze zadaných bodů a kroku sestrojí bezierovu křivku """ nPoints = len(points) xPoints = np.array([p[0] for p in points]) yPoints = np.array([p[1] for p in points]) t = np.linspace(0.0, 1.0, nTimes) polynomial_array = np.array([ bernstein_poly(i, nPoints-1, t) for i in range(0, nPoints) ]) xvals = np.dot(xPoints, polynomial_array) yvals = np.dot(yPoints, polynomial_array) return xvals, yvals def vykresleni(): if __name__ == "__main__": from matplotlib import pyplot as plt global ax1 #nPoints = (pocetbodu_entry.get()) points = np.random.rand(nPoints, 2) * 200 xpoints = [p[0] for p in points] ypoints = [p[1] for p in points] xvals, yvals = bezier_curve(points, nTimes=1000) print(f"\nPoints") for x, y in points: print(f"x: {x:20}, y: {y:20}") print() ax1 = fig.add_subplot(111).plot(xvals, yvals) ax2 = fig.add_subplot(111).plot(xpoints, ypoints, "ro") for nr in range(len(points)): print(f"nr: {nr}, points[nr][0]: {points[nr][0]}, points[nr][1]: {points[nr][1]}") ax2.text(points[nr][0], points[nr][0], nr) for i in range(nPoints-1): pomocna_1x = [xpoints[i], xpoints[i+1]] pomocna_1y = [ypoints[i], ypoints[i+1]] ax3=fig.add_subplot(111).plot(pomocna_1x, pomocna_1y,'b--', linewidth=2) canvas.draw() # canvas a vykreslovací ploška root = tkinter.Tk() root.wm_title("Beziereček") fig = plt.Figure(figsize=(5, 4), dpi=100, frameon=False) canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea. canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) toolbar = NavigationToolbar2Tk(canvas, root) toolbar.update() canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1) def on_key_press(event): print("you pressed {}".format(event.key)) key_press_handler(event, canvas, toolbar) canvas.mpl_connect("key_press_event", on_key_press) def konec(): root.quit() root.destroy() #tlačítka a blbítka pocetbodu = Label(root, text = "Počet řídících bodů: ") pocetbodu_entry = Entry(root) buttonQuit = Button(master=root, text="Quit", command=konec) buttonQuit.pack(side=tkinter.BOTTOM) buttonSubmit = Button(master=root, text="Submit", command=inputik) buttonSubmit.pack(side=tkinter.BOTTOM) pocetbodu_entry.pack(side=tkinter.BOTTOM) pocetbodu.pack(side=tkinter.BOTTOM) tkinter.mainloop()which quickly exposed what I think is part the problem. your line 69 reads ax2.text(points[nr][0], points[nr][0], nr) and I think it should be: ax2.text(points[nr][0], points[nr][1], nr) There are still some issues Is that correct? RE: Tkinter & matplotlib - PillyChepper - Nov-23-2019 (Nov-22-2019, 05:56 PM)Larz60+ Wrote: OK, now that My code copy is correct, I added some debugging printouts as follows: Oh yeah, you're right, line 69 should in fact read as you said. Still can't figure out how to get it into the plot |