如何在不保留前一个条形图的情况下重新绘制条形图?

How do I redraw my bar plot without keeping the previous one?

我制作了一个动画,其中的蓝条逐帧更新。问题是上一次迭代的条形图保留在 canvas 上而没有被删除。如何使迭代绘图成为非累加的(非重叠帧,就像在帧与帧之间更新所有内容的 gif 中一样)?

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.ticker import AutoMinorLocator, MaxNLocator


def count_elements(iterable):

    val_dict = {}

    val_list = list(iterable)

    for i in set(val_list):
        val_dict.update({i:val_list.count(i)})

    return np.array(list(val_dict.keys())),np.array(list(val_dict.values()))


# Generate n rolls for a probability distribution of two spins of a wheel of fortune that has 4 equally large wedges. The wedges have numbers from one to 4 on them.
p = 0.25
prob_dist = np.array([[2,3,4,5,6,7,8],[p*p,2*p*p,3*p*p,4*p*p,3*p*p,2*p*p,p*p]])
mu = sum([prob_dist[0,i]*prob_dist[1,i] for i in range(prob_dist.shape[1])])
sig = sum([prob_dist[1,i]*(prob_dist[0,i]-mu)*(prob_dist[0,i]-mu) for i in range(prob_dist.shape[1])])

# true distribution
fig, ax = plt.subplots(figsize=(7,4)) 
ax.bar(prob_dist[0], prob_dist[1], width=0.5, align="center", ec=None, color='red', alpha=0.5)

# Experimental data
n = 10
rolls = np.random.randint(1,5,n) + np.random.randint(1,5,n)
exp_vals, exp_count = count_elements(rolls)
ax.bar(exp_vals,exp_count/n, width=0.3, align="center", ec=None, color='blue', alpha=0.5)



def update(frame):

    n = int(10 *1**frame)
    rolls = np.random.randint(1,5,n) + np.random.randint(1,5,n)
    exp_vals, exp_count = count_elements(rolls)

    ax.bar(exp_vals,exp_count/n, width=0.3, align="center", ec=None, color='blue', alpha=0.5)

    

ani = FuncAnimation(fig, update, frames=range(1,10),repeat=False,blit=False,interval=1000)
plt.show()

您似乎只更新了条形的高度,所以您应该完全这样做 - 更新条形的高度:

...    
# true distribution
fig, ax = plt.subplots(figsize=(7,4)) 
ax.bar(prob_dist[0], prob_dist[1], width=0.5, align="center", ec=None, color='red', alpha=0.5)
#store the x-values
all_x_vals = prob_dist[0]

#catch the bar container for the update in the animation loop
bc = ax.bar(all_x_vals, 0, width=0.3, align="center", ec=None, color='blue', alpha=0.5)

def update(frame):
    #not sure what this is as it will always be 10
    n = int(10 *1**frame)
    rolls = np.random.randint(1,5,n) + np.random.randint(1,5,n)
    exp_vals, exp_count = count_elements(rolls)
        
    heights = np.zeros_like(all_x_vals)
    heights[np.in1d(all_x_vals, exp_vals).nonzero()[0]] = exp_count/n

    for b, h in zip(bc, heights):
        b.set_height(h) 
    
    #sanity check, should be 1
    #print(sum(b.get_height() for b in bc))
  
ani = FuncAnimation(fig, update, frames=range(0,10),repeat=False,blit=False,interval=1000)
plt.show()