I am trying to plot interactive matplotlib figure in Tkinter. I took the slider_demo https://matplotlib.org/stable/gallery/widgets/slider_demo.html and tried to encapsulate it in FigureCanvasTkAgg. The code run correctly but if I move the sliders several times (alternating the two) the program freeze???
To try to understand the problem I took the original demo and did the following changes: all the code to plot has been encapsulated in a function plot_sin() and in main I just call this function and do a plt.show(). I have the same problem as explained before. Therefore the problem does not seems to be related to embedding the plot in tkinter but something else that I do not understand.
May be someone can tell me what I did wrong
I’m trying to draw an interactive matplotlib figure in Tkinter. I’ve taken the slider_demo https://matplotlib.org/stable/gallery/widgets/slider_demo.html and tried encapsulating it in FigureCanvasTkAgg. The code runs correctly but if I move the sliders several times (alternating between the two) the program hangs????
To try and understand the problem, I took the original demo and made the following changes: all the plotting code has been encapsulated in a plot_sin() function and in main I just call this function and do a plt.show(). But I have the exact same problem as explained above. Therefore, the problem doesn’t seem to be related to the plot integration in tkinter, but to something else I don’t understand.
Maybe someone can tell me what I’ve done wrong.
I have added my test code.
commented at the end is the code to test in Tkinter (same problem)
import matplotlib.pyplot as plt
import numpy as np
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # type: ignore[misc]
from matplotlib.widgets import Slider
def plot_sin():
def f(t, amplitude, frequency):
return amplitude * np.sin(2 * np.pi * frequency * t)
t = np.linspace(0, 1, 1000)
init_a = 5
init_f = 3
fig, ax = plt.subplots()
(line,) = ax.plot(t, f(t, init_a, init_f), lw=2)
ax.set_xlabel("Time [s]")
fig.subplots_adjust(left=0.25, bottom=0.25)
axfreq = fig.add_axes((0.25, 0.1, 0.65, 0.03))
freq_slider = Slider(ax=axfreq, label="Freq", valmin=0.1, valmax=30, valinit=init_f)
axamp = fig.add_axes((0.1, 0.25, 0.0225, 0.63))
amp_slider = Slider(
ax=axamp,
label="Amplitude",
valmin=0,
valmax=10,
valinit=init_a,
orientation="vertical",
)
def update(val):
line.set_ydata(f(t, amp_slider.val, freq_slider.val))
# fig.canvas.draw_idle()
freq_slider.on_changed(update)
amp_slider.on_changed(update)
return fig
fig = plot_sin()
# to display in tkinter comment next line and uncomment following
# plt.show()
# root = tk.Tk()
# root.protocol("WM_DELETE_WINDOW", quit)
# canvas = FigureCanvasTkAgg(fig, master=root)
# # canvas.draw()
# canvas.get_tk_widget().pack()
# root.mainloop()