Python 实时更新matplotlib条形图
我正在编写冒泡排序算法,它接受一个随机整数列表,按递增顺序排序,并将排序后的整数列表绘制为条形图的y值。我的第一个条形图是未排序的列表,第二个是已排序的列表 我想让图表实时更新。我会通过提供排序越来越多的matplotlib列表来实现这一点。(即每次都有新的名单) 我在matplotlib中查阅了许多关于更新图表的教程,但它们大多是针对散点图这样的教程,在散点图中一次添加一个点。我也见过,但我一生都无法理解 那么,我该如何实时更新这个条形图呢?谢谢大家! 我的代码如下。您可以忽略排序算法。您需要知道的是,它以[1,2,3,4,5]的形式返回一个排序后的数字列表Python 实时更新matplotlib条形图,python,matplotlib,Python,Matplotlib,我正在编写冒泡排序算法,它接受一个随机整数列表,按递增顺序排序,并将排序后的整数列表绘制为条形图的y值。我的第一个条形图是未排序的列表,第二个是已排序的列表 我想让图表实时更新。我会通过提供排序越来越多的matplotlib列表来实现这一点。(即每次都有新的名单) 我在matplotlib中查阅了许多关于更新图表的教程,但它们大多是针对散点图这样的教程,在散点图中一次添加一个点。我也见过,但我一生都无法理解 那么,我该如何实时更新这个条形图呢?谢谢大家! 我的代码如下。您可以忽略排序算法。您需要
import random
import matplotlib.pyplot as plt
import numpy as np
print("bubble sort")
plt.style.use('fivethirtyeight')
n = int(input("How many items would you like to sort? "))
list_num = np.random.randint(0,500, n)
orig_list_num = list_num.copy()
def is_sorted(list_num):
Flag = True
j=-1
while Flag == True:
Flag=False
j+=1
for i in range(0, (len(list_num))-j):
if i+1 >= len(list_num):
break
if list_num[i] > list_num[i+1]:
tempvar=list_num[i]
list_num[i] = list_num[i+1]
list_num[i+1] = tempvar
Flag=True
return list_num
list_num = is_sorted(list_num)
#unsorted graph
indices = np.arange(n)
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.show()
这是第一个没有动画的版本。它可能很慢。
在动画结束之前关闭窗口可能会有问题 首先我使用
plt.show(block=False)
显示无阻塞代码的绘图
接下来我运行is_sorted()
来更新绘图
内部已排序()
我使用
plt.cla()
清除上次绘制的轴的步骤
现在我可以在同一个地方用新数据再次绘制bar
plt.bar(indices, list_num)
之后,我减慢代码的速度,以便有时间在窗口中显示绘图
plt.pause(0.01)
如果不暂停,则可能会显示空窗口
顺便说一句: 如果在
(len(list_num))-j-1中使用-1
,那么如果i+1>=len(list_num):break
编辑: 使用你们链接中的想法,我创建了第二个版本——我认为它可以运行得更快一点,但我希望速度会更好 在这个版本中,我将bar分配给变量
bar2 = plt.bar(indices, list_num)
所以以后我不用再画了,就可以查根杆高了
bar2[i].set_height(list_num[i])
bar2[i+1].set_height(list_num[i+1])
我正在考虑使用
FuncAnimation
的版本,但它需要做很多更改。它需要创建使用单个进行-循环的代码,而+进行-循环,然后FuncAnimation
将重复此进行-循环
我有其他想法-在plt.plot()
中,可以用ax.set_ydata()
替换绘图中的数据,但是plt.bar()
没有此功能。但是set\u height()
似乎类似
在回答问题时,我直接在tkinter
中创建了动画,而没有matplotlib
您看过吗?一次添加一个点的示例有什么问题?可能它可以在当时添加100个新点,也可以在当时删除100个旧点-因此它可以在当时替换所有点-您只需尝试一下。例如,在更新matplotlib条形图中?
使用了一个事实,即它可以构建在tkinter
GUI上-因此它使用tkinter
函数来更新GUI。但是matplotlit
可能使用不同的GUI,因此此示例将不起作用。如果您从plt
获取ax
,则您应该可以使用绘图中的所有值访问ax.data
,然后可以替换它们。您可能还需要运行update()
来更新屏幕上的绘图。
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")