Growing/Animated bar plot with ceiling value as y-value

无人久伴 提交于 2020-01-30 11:53:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!