这是第一个没有FuncAnimation 动画的版本。它可能很慢。
并且在动画结束之前关闭窗口可能会有问题。
首先我使用
plt.show(block=False)
在不阻塞代码的情况下显示图
接下来我运行is_sorted() 来更新情节。
在is_sorted()里面我用
plt.cla()
致clear last drawn axis
现在我可以用新数据在同一个地方再次绘制bar。
plt.bar(indices, list_num)
之后我放慢代码速度,以便有时间在窗口中显示绘图
plt.pause(0.01)
如果没有pause,它可能会显示空窗口。
顺便说一句:
如果您在(len(list_num))-j-1 中使用-1,则不需要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")
编辑:
使用您链接中的想法,我创建了第二个版本 - 我认为它可以运行得更快,但我预计速度会更快。
在这个版本中,我将 bar 分配给变量
bar2 = plt.bar(indices, list_num)
所以以后我可以在不重新绘制的情况下改变高度
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")
我正在考虑使用 FuncAnimation 的版本,但它需要更改很多 cod。它需要创建使用单个 for-loop 而不是 while+for 的代码 - 然后 FuncAnimation 将重复代码而不是 for-loop。
我有其他想法 - 在plt.plot() 中,您可以用ax.set_ydata() 替换绘图数据,但plt.bar() 没有此功能。但set_height() 似乎很相似。
在回答How do I correctly implement a bubble sort algorithm in python tkinter? 的问题时,我直接在tkinter 中创建了动画,而没有matplotlib