It is first version without FuncAnimation for animation. It may be slow.
And it may have problem to close window befor end of animation.
First I use
plt.show(block=False)
to display plots without blocking code
and next I run is_sorted()
to update plot.
Inside is_sorted()
I use
plt.cla()
to clear last drawn axis
And now I can draw bar
again in the same place but with new data.
plt.bar(indices, list_num)
After that I slow down code so it has time to display plot in window
plt.pause(0.01)
without pause
it may display empty window.
BTW:
if you use -1
in (len(list_num))-j-1
then you don't need if i+1 >= len(list_num): break
import random
import matplotlib.pyplot as plt
import numpy as np
# --- functions --
def is_sorted(list_num):
flag = True
j = -1
while flag:
flag = False
j += 1
for i in range(0, (len(list_num))-j-1):
if list_num[i] > list_num[i+1]:
# in Python you can do it without `tempvar`
list_num[i], list_num[i+1] = list_num[i+1], list_num[i]
flag = True
plt.cla()
plt.bar(indices, list_num)
plt.pause(0.01)
if closed:
flag = False
break # it exits `for`-loop but not `while`-loop and I need `flag = False`
def on_close(event):
global closed # to assign value to external variable which I need in `is_sorted
closed = True
print('Closing window')
# --- main ---
closed = False # default value at start
print("bubble sort")
plt.style.use('fivethirtyeight')
#n = int(input("How many items would you like to sort? "))
n = 20
list_num = np.random.randint(0, 500, n)
orig_list_num = list_num.copy()
indices = np.arange(n)
#unsorted graph
plt.subplot(1, 2, 1)
plt.bar(indices, orig_list_num)
plt.xlabel("Unsorted")
#sorted graph
plt.subplot(1, 2, 2)
plt.bar(indices, list_num)
plt.xlabel("Sorted")
plt.ion() # `Interaction ON` siliar to `block=False`
#plt.show(block=False)
# assign function to plot
fig = plt.gcf()
fig.canvas.mpl_connect('close_event', on_close)
is_sorted(list_num)
input("Press ENTER to exit")
EDIT:
Using idea from your link I created second version - I think it can run little faster but I expected much better speed.
In this version I assign bar to variable
bar2 = plt.bar(indices, list_num)
so later I can chagen bar heigh without drawing all again
bar2[i].set_height(list_num[i])
bar2[i+1].set_height(list_num[i+1])
import random
import matplotlib.pyplot as plt
import numpy as np
# --- functions --
def is_sorted(list_num):
flag = True
j = -1
while flag:
flag = False
j += 1
for i in range(0, (len(list_num))-j-1):
if list_num[i] > list_num[i+1]:
# in Python you can do it without `tempvar`
list_num[i], list_num[i+1] = list_num[i+1], list_num[i]
flag = True
# replace all values
#for rect, value in zip(bar2, list_num):
# rect.set_height(value)
# replace only two new values
bar2[i].set_height(list_num[i])
bar2[i+1].set_height(list_num[i+1])
plt.pause(0.001)
if closed:
flag = False
break # it exits `for`-loop but not `while`-loop and I need `flag = False`
def on_close(event):
global closed # to assign value to external variable which I need in `is_sorted
closed = True
print('Closing window')
# --- main ---
closed = False # default value at start
print("bubble sort")
plt.style.use('fivethirtyeight')
#n = int(input("How many items would you like to sort? "))
n = 20
list_num = np.random.randint(0, 500, n)
orig_list_num = list_num.copy()
indices = np.arange(n)
#unsorted graph
plt.subplot(1, 2, 1)
plt.bar(indices, orig_list_num)
plt.xlabel("Unsorted")
#sorted graph
plt.subplot(1, 2, 2)
bar2 = plt.bar(indices, list_num)
plt.xlabel("Sorted")
plt.ion() # `Interaction ON` siliar to `block=False`
#plt.show(block=False)
# assign function to plot
fig = plt.gcf()
fig.canvas.mpl_connect('close_event', on_close)
is_sorted(list_num)
input("Press ENTER to exit")
I was thinking about version with FuncAnimation
but it would need to change a lot cod. It would need to create code which use single for
-loop instead while
+for
- and then FuncAnimation
would repeate code instead this for
-loop.
I had other idea - in plt.plot()
you could replace in plot data with ax.set_ydata()
but plt.bar()
doesn't have this function. But set_height()
seems similar.
In answer to question How do I correctly implement a bubble sort algorithm in python tkinter? I created animation directly in tkinter
without matplotlib