Как создать видео, которое отображает графики рассеяния один за другим, используя python?

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

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

x = random.sample(range(0, 287), 20)
y = random.sample(range(0, 380), 20)
size =  [20 for x in range(20)]
colors = ["r" for x in range(20)]


cm = plt.get_cmap('jet')

fig = plt.figure(figsize=(18,9))

graph = plt.scatter([], [],marker='+')
url = 'https://raw.githubusercontent.com/kornelski/pngquant/master/test/img/test.png'
im = plt.imread(url)
def animate(i):
        
    implot = plt.imshow(im)
    graph.set_offsets(np.vstack((x[:i+1], y[:i+1])).T)
    graph.set_sizes(size[:i])
    graph.set_facecolors(colors[:i+1])
    return graph

ani = FuncAnimation(fig, animate, repeat=False, interval=0.1)
plt.show()

Есть две вещи, с которыми я хотел бы помочь.

  1. Я хотел бы, чтобы цвет моей диаграммы рассеяния менялся в зависимости от третьей переменной, то есть использовал cmap. Однако set_facecolors не принимает такой аргумент.
  2. Когда я пытаюсь сохранить свою анимацию с помощью ani.save('files/animation.gif',writer='imagemagick', fps=60), мой блокнот Jupyter падает.

Кто-нибудь может мне помочь?


person user42    schedule 02.07.2021    source источник


Ответы (1)


Фоновое изображение графика рисуется путем добавления оси. Карта цветов также создается в соответствии с количеством данных, 20, и создается список, чтобы можно было отображать каждый цвет. Так как координаты изображения и координатная основа графика различны, ось y настроена в противоположном направлении.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
from PIL import Image
import urllib.request

random.seed(20210702)
N = 20
x = random.sample(range(0, 380), N)
y = random.sample(range(0, 287), N)
size =  [20 for x in range(N)]
colors = []

cm = plt.get_cmap('jet', N)

fig,ax = plt.subplots(figsize=(9, 4.5))
plt.xlim(0, 380)
plt.ylim(287, 0)
graph = ax.scatter([], [], marker='+')# 

url = 'https://raw.githubusercontent.com/kornelski/pngquant/master/test/img/test.png'
im = Image.open(urllib.request.urlopen(url))
print(im.size)

def animate(i):
    ax.imshow(im)
    graph.set_offsets(np.vstack((x[:i+1], y[:i+1])).T)
    graph.set_sizes(size[:i+1])
    colors.append(cm(i))
    graph.set_facecolors(colors) 
    return graph

ani = FuncAnimation(fig, animate, frames=20, repeat=False, interval=200)
plt.show()

введите здесь описание изображения

person r-beginners    schedule 02.07.2021
comment
Это отлично работает, спасибо. Для массива size я правильно понимаю, что он должен быть размером с количество кадров? - person user42; 04.07.2021
comment
Да все верно. Вы можете изменить размер маркера, изменив значение массива размеров. - person r-beginners; 04.07.2021