问题
I am looking to develop an animated/growing bar plot.The plot basically contains of 6 rectangular bars and each bar has a particular value.
The problem I'm facing is that the plot is growing up to the maximum value on Y-axis instead it should stop at the bar's corresponding value.
The code I have tried makes the bars animate up to the maximum value on Y-Axis.I have found some information from Growing matplotlib bar charts
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
%matplotlib notebook
fig = plt.figure()
position = np.arange(6) + .5
plt.tick_params(axis = 'x', colors = '#072b57')
plt.tick_params(axis = 'y', colors = '#072b57')
speeds = [.01, .02, .03, .04, .01, .02]
heights = [0, 0, 0, 0, 0, 0]
# Bar plot should animate up to these values
# Adding this portion is making the plot static
#heights = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
rects = plt.bar(position, heights, align = 'center', color=['red', 'orange', 'blue', 'pink', 'green','purple'])
plt.xticks(position, ('Anger', 'Sadness', 'Disgust', 'Fear', 'Happy', 'Surprise'))
plt.xlabel('Emotion', color = '#072b57')
plt.ylabel('Probabilities', color = '#072b57')
plt.title('Emotion - Ally', color = '#072b57')
plt.ylim((0,1))
plt.xlim((0,6))
plt.grid(True)
rs = [r for r in rects]
def init():
return rs
def animate(i):
global rs, heights
if all(map(lambda x: x==1, heights)):
heights = [0, 0, 0, 0, 0, 0]
else:
heights = [min(h+s,1) for h,s in zip(heights,speeds)]
# Bar plot should animate up to these values
# Adding this portion is making the plot static
#heights = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
for h,r in zip(heights,rs):
r.set_height(h)
return rs
anim = animation.FuncAnimation(fig, animate, init_func=init,frames=200, interval=20, blit=True)
plt.show()
The animated bar plot should stop at designated y-values instead of hitting the maximum value on y-axis.
回答1:
Right now, your bar height is derived from min(h+s,1)
, which means it will grow with a certain speed (or rather step size) until it hits the value of 1
.
If you want to limit the height, you should create a respective array, like max_heights = [0.5, .6, 1.0, 0.6, 0.1, 1.0]
and change the heights calculation within the else
case to heights = [min(h+s,mh) for h,s,mh in zip(heights,speeds,max_heights)]
.
In summary:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
# %matplotlib notebook
fig = plt.figure()
position = np.arange(6) + .5
plt.tick_params(axis = 'x', colors = '#072b57')
plt.tick_params(axis = 'y', colors = '#072b57')
speeds = [.01, .02, .03, .04, .01, .02]
heights = [0, 0, 0, 0, 0, 0]
# Bar plot should animate up to these values
# Adding this portion is making the plot static
max_heights = [0.5, .6, 1.0, 1.6, 0.1, 1.0]
rects = plt.bar(position, heights, align = 'center', color=['red', 'orange', 'blue', 'pink', 'green','purple'])
plt.xticks(position, ('Anger', 'Sadness', 'Disgust', 'Fear', 'Happy', 'Surprise'))
plt.xlabel('Emotion', color = '#072b57')
plt.ylabel('Probabilities', color = '#072b57')
plt.title('Emotion - Ally', color = '#072b57')
plt.ylim((0,1))
plt.xlim((0,6))
plt.grid(True)
rs = [r for r in rects]
def init():
return rs
def animate(i):
global rs, heights
if all(map(lambda x: x==1, heights)):
heights = [0, 0, 0, 0, 0, 0]
else:
heights = [min(h+s,mh) for h,s,mh in zip(heights,speeds,max_heights)]
# Bar plot should animate up to these values
# Adding this portion is making the plot static
#heights = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
print heights
for h,r in zip(heights,rs):
r.set_height(h)
return rs
anim = animation.FuncAnimation(fig, animate, init_func=init,frames=200, interval=20, blit=True)
plt.show()
回答2:
You needs a little bit more calculation, e.g.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
fig = plt.figure()
position = np.arange(6) + .5
plt.tick_params(axis = 'x', colors = '#072b57')
plt.tick_params(axis = 'y', colors = '#072b57')
speeds = [.01, .02, .03, .04, .01, .02]
heights = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
rects = plt.bar(position, np.zeros_like(heights), align = 'center',
color=['red', 'orange', 'blue', 'pink', 'green','purple'])
plt.xticks(position, ('Anger', 'Sadness', 'Disgust', 'Fear', 'Happy', 'Surprise'))
plt.xlabel('Emotion', color = '#072b57')
plt.ylabel('Probabilities', color = '#072b57')
plt.title('Emotion - Ally', color = '#072b57')
plt.ylim((0,1))
plt.xlim((0,6))
plt.grid(True)
frames = 200
min_speed = np.min(speeds)
def init():
return rects
def animate(i):
for h,r,s in zip(heights,rects, speeds):
new_height = i / (frames-1) * h * s / min_speed
new_height= min(new_height, h)
r.set_height(new_height)
return rects
anim = animation.FuncAnimation(fig, animate, init_func=init,frames=frames, interval=20, blit=True, repeat=False)
plt.show()
来源:https://stackoverflow.com/questions/55664075/growing-animated-bar-plot-with-ceiling-value-as-y-value