It looks like to do this you need to implement plt.pause()
and plt.draw()
and the window will update. My code that does what you want (I think) is:
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
plt.show()
plt.plot(5, 0, marker='o', markersize=3, color="red")
plt.draw()
plt.pause(0.001)
if input(">") == "a":
x = np.arange(-6, 6, 0.01)
y = -10/25*(x)**2 + 10
plt.plot(x, y)
plt.draw()
plt.pause(0.001)
input('press enter to continue')
Where I used the techniques as described in the accepted answer at Plotting in a non-blocking way with Matplotlib
I'm not sure if my code can be simplified more of not, but it seems to do what you are aiming for! Let me know if this was what you were asking, or if I was unclear/off topic.
From the documentation of plt.ion() at https://matplotlib.org/api/_as_gen/matplotlib.pyplot.ion.html?highlight=ion#matplotlib.pyplot.ion
Turn the interactive mode on.
From the documentation for plt.pause() at https://matplotlib.org/api/_as_gen/matplotlib.pyplot.pause.html?highlight=pause#matplotlib.pyplot.pause
Pause for interval seconds.
If there is an active figure, it will be updated and displayed before the pause, and the GUI event loop (if any) will run during the pause.
This can be used for crude animation. For more complex animation, see matplotlib.animation.
Notes
This function is experimental; its behavior may be changed or extended in a future release.
Finally the plt.draw()
documentation (https://matplotlib.org/api/_as_gen/matplotlib.pyplot.draw.html?highlight=pyplot%20draw#matplotlib.pyplot.draw) states
Redraw the current figure.
This is used to update a figure that has been altered, but not automatically re-drawn. If interactive mode is on (ion()), this should be only rarely needed, but there may be ways to modify the state of a figure without marking it as stale. Please report these cases as bugs.
A more object-oriented alternative, given any Figure instance, fig, that was created using a pyplot function, is:
fig.canvas.draw_idle()
So my understanding of these functions is that the plt.ion()
puts it into interactive mode and is preferred to plt.show(block=False)
as the block=False is deprecated (according to the linked answer above). Once you've generated your plot you draw to it, and then you need to run the GUI loop to actually show it has changed so you run plt.pause()
. From the description of plt.draw()
though I think you can omit this and go straight to plt.pause()
to update the image (I did not test to confirm this though)
UPDATE
It seems you are begging XD for a code that will continually plot to the same axis. Here is how you can do that with threading
(you should thread events that have to do computations so your GUI doesn't freeze)
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
import threading
import random
import time
root = tk.Tk()
root.withdraw()
def _destroyWindow():
root.quit()
root.destroy()
root.protocol('WM_DELETE_WINDOW', _destroyWindow)
fig = Figure(figsize=(12, 8), facecolor='white')
axis = fig.add_subplot(111)
xValues = [1, 2, 3, 4]
yValues = [5, 7, 6, 8]
axis.plot(xValues, yValues)
axis.set_xlabel('Horizontal Label')
axis.set_ylabel('Vertical Label')
axis.grid(linestyle='-')
canvas = FigureCanvasTkAgg(fig, master=root)
canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
def get_new_data():
while True:
print('plotting new values')
xValues = [random.randint(1, 5) for _ in range(4)]
yValues = [random.randint(1, 5) for _ in range(4)]
axis.plot(xValues, yValues)
fig.canvas.draw_idle()
time.sleep(1)
def thread_maker():
t = threading.Thread(target=get_new_data)
t.start()
thread_maker()
root.update()
root.deiconify()
root.mainloop()