Как я могу изменить код с подзаговорами в живую анимацию? - PullRequest
0 голосов
/ 03 апреля 2019

Я недавно вернулся к изучению Python для его использования matplotlib и способности красиво отображать данные.

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

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

Пока я справился с этим и достиг хорошего результата, однако я хотел бы анимировать каждый бросок на обоих участках, но этоэто то, с чем у меня до сих пор было много проблем.

В настоящее время мой основной код выглядит следующим образом:

import random 
import matplotlib.pyplot as plt

# Generate a plot displaying two elements:
# One: Display 6 side die roll results
# Two: Plot the order of rolls

numRolls = 100

rollTotals = [0, 0, 0, 0, 0, 0]
rollSeq = []

for roll in range(numRolls):
  currentRoll = random.randint(1, 6)
  rollTotals[currentRoll - 1] += 1
  rollSeq.append(currentRoll)

plt.subplot(2, 1, 1)
plt.bar([1, 2, 3, 4, 5, 6], rollTotals, 1/1.5)
plt.title("Roll Totals")

plt.subplot(2, 1, 2)
plt.plot(rollSeq)
plt.title("Roll Sequence")

plt.show()

numRolls - это константа, позволяющая быстро менять переменную вколичество бросков костей.rollTotals - это список значений из 6 элементов, используемый для представления общего количества бросков для каждой стороны матрицы.rollSeq - это список, показывающий порядок каждого броска.

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

Спасибо за вашу помощь, помогающую мне в дальнейшем моем хобби.

1 Ответ

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

После просмотра лайка, 20 различных постов и перечитывания документации не менее 10 раз, я пришел к следующему:

import random
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

# Generate a plot displaying two elements:
# One: Display 6 side die roll results
# Two: Plot the order of rolls

numRolls = 300

rollTotals = [0, 0, 0, 0, 0, 0]
rollSeq = []

# Create a figure with two subplots
fig = plt.figure()
ax1 = fig.add_subplot(2,1,1)
ax2 = fig.add_subplot(2,1,2)

# Adjust spacing between plots
plt.subplots_adjust(top = 0.93, bottom = 0.07, hspace = 0.3)

#define the function for use in matplotlib.animation.funcAnimation
def animate(i):

    currentRoll = random.randint(1, 6)
    rollTotals[currentRoll - 1] += 1
    rollSeq.append(currentRoll)

    # Set subplot data
    ax1.clear()
    ax1.bar([1, 2, 3, 4, 5, 6], rollTotals, 1/1.5)

    ax2.clear()
    ax2.plot(rollSeq)
    xlim = len(rollSeq)
    ax2.set_xlim(xlim - 30, xlim)

    # Set subplot titles
    ax1.set_title("Roll Totals")
    ax2.set_title("Roll Sequence")


ani = animation.FuncAnimation(fig, animate, frames=numRolls, interval=50, repeat=False)

# Set up formatting for the movie files
Writer = animation.writers['ffmpeg']
writer = Writer(fps=15, metadata=dict(artist='Me'), bitrate=1800)

# Save ani
ani.save(r'D:\_Data\Desktop\AnimationOutput.mp4', writer=writer)

#plt.show()

Это можно оптимизировать с помощью Blitting в animation.FuncAnimation, но это более запутанно. Как это, это, вероятно, может быть дополнительно оптимизировано. ТАКЖЕ, я разобрался, как сохранить анимацию как mp4.

Если вы не хотите экспортировать, раскомментируйте plt.show() и удалите все остальное в ani = animation.FuncAnimation(...)

...