Как выполнить анимацию в Matplotlib вместе с потоком?

#python #multithreading #matplotlib #animation

#python #многопоточность #matplotlib #Анимация

Вопрос:

Я хотел бы менять цвет круга каждые 0,25 секунды в потоке и показывать результат в реальном времени через matplotlib анимацию. Вот мой код (я даже не понимаю, почему анимация не выполняется):

 import threading
import time

import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.animation import FuncAnimation

def apply_color_shift(fig, circle):

    def func():
        for i in range(100):
            circle.set_fc((i/100, 0, 0, 1))
            time.sleep(0.25)
            print("something")
    anim = threading.Thread(target = func)

    def do_nothing(frame):
        print("ANIM")
        fig.show()
    FuncAnimation(fig, do_nothing, frames = [0.1*i for i in range(100)])

    anim.start()
    plt.show()

fig, ax = plt.subplots()
ax.axis('square')

c = Circle(xy = (0, 0), color = "red")
ax.add_patch(c)
ax.set_xlim([-50, 50])
ax.set_ylim([-50, 50])

fig.show()
apply_color_shift(fig, c)
  

В чем здесь проблема и как ее решить?

Комментарии:

1. Вы запускаете это в интерактивном режиме? В этом случае проблема заключалась бы в том, что, поскольку plt.show() не блокируется, функция возвращает и не оставляет ссылки на FuncAnimation , так что это собранный мусор. Вне интерактивного режима код сам по себе выполняется нормально. Не уверен, для чего используется потоковая обработка.

2. @ImportanceOfBeingErnest пробовали обходиться без потоков и использовать только анимацию, проблема в том, что она медленная

Ответ №1:

Если вы хотите менять цвет каждые 0,25 секунды, это должен быть интервал анимации:

 import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()
ax.axis('square')

c = Circle(xy = (0, 0), color = "red")
ax.add_patch(c)
ax.set_xlim([-50, 50])
ax.set_ylim([-50, 50])

def change_color(i):
    c.set_fc((i/100, 0, 0, 1))

ani = FuncAnimation(fig, change_color, frames = range(100), interval=250)

plt.show()
  

Комментарии:

1. Спасибо. Я пробовал это. Но почему это очень медленно? (Не гладко)

2. Скорость определяется interval . Как я понял, вы хотите, чтобы она менялась каждую четверть секунды (= 250 мс); но, конечно, вы можете установить меньший интервал, чтобы анимация выполнялась более плавно.

3. Проблема также в том, что если я устанавливаю interval = 0.5 etc (меньше 1), то анимация ничего не делает.

4. Я подумал, что использование Thread поможет сгладить анимацию

5. Вы не можете использовать интервал меньше 1 мс.