Issue
I need the program to display 2 graphs of mathematical functions on the same coordinate line, which the user enters manually into the input window. How can I make this graphs show up in a tkinter window? I heard about using Figure, but then 2 graphs will not be on the same coordinate line
replacements = {
'sin' : 'np.sin',
'cos' : 'np.cos',
'exp': 'np.exp',
'sqrt': 'np.sqrt',
'^': '**',
}
allowed_words = [
'x',
'sin',
'cos',
'sqrt',
'exp',
]
def string2func(string):
for word in re.findall('[a-zA-Z_]+', string):
if word not in allowed_words:
raise ValueError(
'"{}" is forbidden to use in math expression'.format(word)
)
for old, new in replacements.items():
string = string.replace(old, new)
def func(x):
return eval(string)
return func
def create_plot():
a = int(value1.get())
b = int(value2.get())
x = np.linspace(a, b, 1000)
func1 = str(value3.get())
func2 = str(value4.get())
if func1.isnumeric():
func1 = int(value3.get())
func1 = [func1] * 1000
plt.plot(x, func1 , label = 'F1(X)')
else:
func1 = str(value3.get())
strfunc1 = string2func(func1)
plt.plot(x, strfunc1(x), label ='F1(X)')
if func2.isnumeric():
func2 = int(value4.get())
func2 = [func2] * 1000
plt.plot(x, func2, label = 'F2(X)')
else:
func2 = str(value4.get())
strfunc2 = string2func(func2)
plt.plot(x, strfunc2(x), label ='F2(X)')
plt.grid(True)
plt.xlabel('x')
plt.ylabel('y')
plt.title("Simple Plot")
plt.ylim(-50, 50)
plt.show()
Solution
You can get axis
and use it to draw another line in the same plot - ax.plot()
.
Matplotlib has special classes to display in different GUIs (tkinter
, PyQt
, etc.)
Embedding in Tk — Matplotlib 3.6.0 documentation
Example which draws two lines on one plot (in Tkinter
) when you press button.
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
# --- functions ---
def draw_plots():
x = np.arange(0, 3.01, .01)
scale = np.random.randint(1, 10)
y1 = scale * np.sin(scale * np.pi * x)
scale = np.random.randint(1, 10)
y2 = scale * np.sin(scale * np.pi * x)
ax.clear() # remove previous plots
#ax.grid(True)
ax.plot(x, y1)
ax.plot(x, y2)
canvas.draw() # refresh window
# --- main ---
root = tk.Tk()
fig = Figure() # Figure(figsize=(5, 4), dpi=100)
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.get_tk_widget().pack(fill='both', expand=True) # resize plot when window is resized
ax = fig.add_subplot(111)
#ax.grid(True)
button = tk.Button(root, text='Draw', command=draw_plots)
button.pack()
tk.mainloop()
EDIT:
Example which draws on separated plots
# author: Bartlomiej "furas" Burek (https://blog.furas.pl)
# date: 2022.10.09
# [python - Plots in Tkinter - Stack Overflow](https://stackoverflow.com/questions/73997593/plots-in-tkinter/)
# [Embedding in Tk — Matplotlib 3.6.0 documentation](https://matplotlib.org/stable/gallery/user_interfaces/embedding_in_tk_sgskip.html)
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
# --- functions ---
def draw_plots():
x = np.arange(0, 3.01, .01)
scale = np.random.randint(1, 10)
y1 = scale * np.sin(scale * np.pi * x)
scale = np.random.randint(1, 10)
y2 = scale * np.sin(scale * np.pi * x)
ax1.clear() # remove previous plots
ax2.clear() # remove previous plots
#ax1.grid(True)
#ax2.grid(True)
ax1.plot(x, y1)
ax2.plot(x, y2)
canvas.draw() # refresh window
# --- main ---
root = tk.Tk()
fig = Figure() # Figure(figsize=(5, 4), dpi=100)
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.get_tk_widget().pack(fill='both', expand=True) # resize plot when window is resized
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
#ax1.grid(True)
#ax2.grid(True)
button = tk.Button(root, text='Draw', command=draw_plots)
button.pack()
tk.mainloop()
Answered By - furas
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.