Растущий / Анимированный гистограмма с предельным значением в виде значения y - PullRequest
0 голосов
/ 13 апреля 2019

Я хочу разработать анимированный / растущий линейный график. Этот график в основном содержит 6 прямоугольных столбцов, и каждый столбец имеет определенное значение.

Проблема, с которой я сталкиваюсь, заключается в том, что график растет до максимального значения по оси Y, вместо этого он должен останавливаться на соответствующем значении бара.

Код, который я пробовал, оживляет столбцы до максимального значения по оси Y. Я нашел некоторую информацию из Растущие гистограммы matplotlib

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()

Анимированный линейный график должен останавливаться на обозначенных значениях y вместо достижения максимального значения на оси y. CurrentResult

Ответы [ 2 ]

0 голосов
/ 13 апреля 2019

Прямо сейчас ваша высота бара получена из min(h+s,1), что означает, что она будет расти с определенной скоростью (или, точнее, размером шага), пока не достигнет значения 1.

Если вы хотите ограничить высоту, вы должны создать соответствующий массив, например max_heights = [0.5, .6, 1.0, 0.6, 0.1, 1.0] и изменить вычисление высоты в случае else на heights = [min(h+s,mh) for h,s,mh in zip(heights,speeds,max_heights)].

В итоге:

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()
0 голосов
/ 13 апреля 2019

Вам нужно немного больше вычислений, например,

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()

enter image description here

...