2017-02-22 7 views
2

У меня есть программа python, которая отображает данные из файла в виде контура для каждой строки в этом текстовом файле. В настоящее время у меня есть 3 отдельных контура в моем интерфейсе. Неважно, читаю ли я данные из файла или загружаю его в память перед выполнением скрипта, я могу получить только ~ 6 кадров в секунду от контурных графиков.Увеличьте скорость перерисовки контура в matplotlib

Я также пробовал использовать только один контур и остальные нормальные сюжеты, но скорость только увеличилась до 7 кадров в секунду. Я не считаю, что это так расчетно облагается налогом, чтобы нарисовать несколько строк. Есть ли способ сделать это значительно быстрее? В идеале было бы неплохо получить как минимум 30 кадров в секунду.

Путь рисую контур является то, что для каждой строки моих данных я удалить предыдущий:

for coll in my_contour[0].collections: 
    coll.remove() 

и добавить новый один

my_contour[0] = ax[0].contour(x, y, my_func, [0]) 

В начале кода, У меня есть plt.ion(), чтобы обновить графики, когда я их добавляю.

Любая помощь будет оценена по достоинству.

Благодаря

+0

Скорость, с которой вы можете обновить график, зависит от двух вещей: (a) времени, которое требуется для вычисления новых данных, и (b) времени, необходимого для рисования осей. В общем, трудно сказать, какой из них занимает больше времени в вашем случае. К сожалению, «контур» должен пересчитывать данные на каждой итерации, поэтому ожидается небольшой выигрыш. Время рисования потенциально может быть уменьшено с помощью blitting, но я сомневаюсь, что это принесет вам от 7 до 30 кадров в секунду. – ImportanceOfBeingErnest

+0

Ну, добавление большего количества контуров не приводит к резкому уменьшению fps. Теперь я попробовал 6 контуров, и я получаю 5.5-6.5 fps, когда с одним я получаю 7-7.5fps, что-то происходит в matplotlib, когда он обновляет графики, которые навсегда ожидают анимации. Кроме того, если я уменьшаю плотность сетки для участка контура, это существенно увеличивает частоту кадров на долю fps. – UN4

+0

Это похоже на [blitting] (http://stackoverflow.com/questions/40126176/fast-live-plotting-in-matplotlib-pyplot), действительно, может дать преимущество. – ImportanceOfBeingErnest

ответ

2

Вот пример того, как использовать contour сюжет в анимации. Он использует matplotlib.animation.FuncAnimation, что позволяет легко включать и выключать blitting. С blit = True он работает на ~ 64 кадра в секунду на моей машине, без blitting ~ 55 fps. Обратите внимание, что interval должен, конечно, предусмотреть быструю анимацию; установка его на interval=10 (миллисекунды) позволит до 100 кадров в секунду, но время рисования ограничивает его чем-то медленнее.

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

x= np.linspace(0,3*np.pi) 
X,Y = np.meshgrid(x,x) 
f = lambda x,y, alpha, beta :(np.sin(X+alpha)+np.sin(Y*(1+np.sin(beta)*.4)+alpha))**2 
alpha=np.linspace(0, 2*np.pi, num=34) 
levels= 10 
cmap=plt.cm.magma 


fig, ax=plt.subplots() 
props = dict(boxstyle='round', facecolor='wheat') 
timelabel = ax.text(0.9,0.9, "", transform=ax.transAxes, ha="right", bbox=props) 
t = np.ones(10)*time.time() 
p = [ax.contour(X,Y,f(X,Y,0,0), levels, cmap=cmap) ] 

def update(i): 
    for tp in p[0].collections: 
     tp.remove() 
    p[0] = ax.contour(X,Y,f(X,Y,alpha[i],alpha[i]), levels, cmap= cmap) 
    t[1:] = t[0:-1] 
    t[0] = time.time() 
    timelabel.set_text("{:.3f} fps".format(-1./np.diff(t).mean())) 
    return p[0].collections+[timelabel] 

ani = matplotlib.animation.FuncAnimation(fig, update, frames=len(alpha), 
             interval=10, blit=True, repeat=True) 
plt.show() 

enter image description here

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

+0

Удивительно, все мои 6 контуров работают со скоростью 50 кадров в секунду! Огромное улучшение! Благодаря! – UN4

+0

Большое спасибо за помощь. Разочарование того, насколько неинтуитивными являются эти анимации, - попытка использовать «set_array» на объекте «QuadContour» потерпела неудачу, пытаясь создать всех художников, а затем использовать «ArtistAnimation».Единственный ответ заключается в том, чтобы ** выполнить процесс, стоящий за ** 'ArtistAnimation' ** и ** сделать эту работу с' FuncAnimation'. matplotlib действительно нуждается в работе здесь. –

+0

@ LukeDavis Мне непонятно, в чем проблема. Я думаю, что 4 строки комментариев действительно слишком короткие для достаточно четкого описания, поэтому вы можете задать новый вопрос о проблеме, которую вы хотите. – ImportanceOfBeingErnest

Смежные вопросы