Posts: 5
Threads: 1
Joined: Nov 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
Posts: 12,025
Threads: 484
Joined: Sep 2016
You are trying to use an undefined object pocetbodu_entry
Error: Exception in Tkinter callback
Traceback (most recent call last):
File "/home/captainkirk/.pyenv/versions/3.7.4/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/media/captainkirk/Data-3TB/projects/T-Z/T/TryStuff/src/PyMatplotlib.py", line 17, in inputik
nPoints = int(pocetbodu_entry.get())
NameError: name 'pocetbodu_entry' is not defined
Posts: 5
Threads: 1
Joined: Nov 2019
(Nov-21-2019, 07:34 PM)Larz60+ Wrote: You are trying to use an undefined object pocetbodu_entry
Error: Exception in Tkinter callback
Traceback (most recent call last):
File "/home/captainkirk/.pyenv/versions/3.7.4/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/media/captainkirk/Data-3TB/projects/T-Z/T/TryStuff/src/PyMatplotlib.py", line 17, in inputik
nPoints = int(pocetbodu_entry.get())
NameError: name 'pocetbodu_entry' is not defined
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
Posts: 12,025
Threads: 484
Joined: Sep 2016
It needs to defined before you execute line 17
Posts: 5
Threads: 1
Joined: Nov 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.
Posts: 12,025
Threads: 484
Joined: Sep 2016
Again:
The error is:
Error: Exception in Tkinter callback
Traceback (most recent call last):
File "/home/captainkirk/.pyenv/versions/3.7.4/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/media/captainkirk/Data-3TB/projects/T-Z/T/TryStuff/src/PyMatplotlib.py", line 17, in inputik
nPoints = int(pocetbodu_entry.get())
NameError: name 'pocetbodu_entry' is not defined
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.
Posts: 5
Threads: 1
Joined: Nov 2019
(Nov-22-2019, 04:43 PM)Larz60+ Wrote: Again:
The error is:
Error: Exception in Tkinter callback
Traceback (most recent call last):
File "/home/captainkirk/.pyenv/versions/3.7.4/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/media/captainkirk/Data-3TB/projects/T-Z/T/TryStuff/src/PyMatplotlib.py", line 17, in inputik
nPoints = int(pocetbodu_entry.get())
NameError: name 'pocetbodu_entry' is not defined
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.
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.
Error: C:/Users/Admin/Downloads/Škola/Python projects/Hangman/testtest.py:66: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance. In a future version, a new instance will always be created and returned. Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.
ax2 = fig.add_subplot(111).plot(xpoints, ypoints, "ro")
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files (x86)\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/Users/Admin/Downloads/Škola/Python projects/Hangman/testtest.py", line 19, in inputik
vykresleni()
File "C:/Users/Admin/Downloads/Škola/Python projects/Hangman/testtest.py", line 68, in vykresleni
ax2.text(points[nr][0], points[nr][0], nr)
AttributeError: 'list' object has no attribute 'text'
Posts: 12,025
Threads: 484
Joined: Sep 2016
I recopied your script and am getting same error now.
I'll revisit the code after I finish this session.
Posts: 12,025
Threads: 484
Joined: Sep 2016
Nov-22-2019, 05:56 PM
(This post was last modified: Nov-22-2019, 05:56 PM by Larz60+.)
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?
Posts: 5
Threads: 1
Joined: Nov 2019
(Nov-22-2019, 05:56 PM)Larz60+ Wrote: 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?
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
|