Matplotlib으로 음모를 꾸미는 것이 왜 그렇게 느립니까?
저는 현재 다른 파이썬 플롯 라이브러리를 평가하고 있습니다.저는 지금 matplotlib을 시도하고 있는데 그 공연에 상당히 실망했습니다.다음 예제는 SciPy 예제에서 수정되었으며 초당 최대 8프레임만 제공합니다!
속도를 높일 수 있는 방법이 있습니까? 아니면 다른 플롯 라이브러리를 선택해야 합니까?
from pylab import *
import time
ion()
fig = figure()
ax1 = fig.add_subplot(611)
ax2 = fig.add_subplot(612)
ax3 = fig.add_subplot(613)
ax4 = fig.add_subplot(614)
ax5 = fig.add_subplot(615)
ax6 = fig.add_subplot(616)
x = arange(0,2*pi,0.01)
y = sin(x)
line1, = ax1.plot(x, y, 'r-')
line2, = ax2.plot(x, y, 'g-')
line3, = ax3.plot(x, y, 'y-')
line4, = ax4.plot(x, y, 'm-')
line5, = ax5.plot(x, y, 'k-')
line6, = ax6.plot(x, y, 'p-')
# turn off interactive plotting - speeds things up by 1 Frame / second
plt.ioff()
tstart = time.time() # for profiling
for i in arange(1, 200):
line1.set_ydata(sin(x+i/10.0)) # update the data
line2.set_ydata(sin(2*x+i/10.0))
line3.set_ydata(sin(3*x+i/10.0))
line4.set_ydata(sin(4*x+i/10.0))
line5.set_ydata(sin(5*x+i/10.0))
line6.set_ydata(sin(6*x+i/10.0))
draw() # redraw the canvas
print 'FPS:' , 200/(time.time()-tstart)
먼저 다음과 같이 코드를 정리하는 것이 좋습니다(성능은 전혀 변하지 않습니다.
import matplotlib.pyplot as plt
import numpy as np
import time
x = np.arange(0, 2*np.pi, 0.01)
y = np.sin(x)
fig, axes = plt.subplots(nrows=6)
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
lines = [ax.plot(x, y, style)[0] for ax, style in zip(axes, styles)]
fig.show()
tstart = time.time()
for i in xrange(1, 20):
for j, line in enumerate(lines, start=1):
line.set_ydata(np.sin(j*x + i/10.0))
fig.canvas.draw()
print 'FPS:' , 20/(time.time()-tstart)
위의 예에서 저는 약 10fps를 받습니다.
사용 사례에 따라 matplotlib은 좋은 선택이 아닐 수 있습니다.실시간 디스플레이가 아닌 출판물 수준의 수치를 지향합니다.
그러나 이 예제의 속도를 높이기 위해 할 수 있는 일은 많습니다.
이것이 이렇게 느린 이유는 크게 두 가지입니다.
링에게 fig.canvas.draw()
모든 것을 다시 그립니다.당신의 병목 현상입니다.이 경우 축 경계, 눈금 레이블 등을 다시 그릴 필요가 없습니다.
이 경우 눈금 레이블이 많은 하위 그림이 많습니다.이것들은 그리는 데 오랜 시간이 걸립니다.
이 두 가지 모두 블리팅을 사용하여 수정할 수 있습니다.
블릿을 효율적으로 수행하려면 백엔드별 코드를 사용해야 합니다.실제로, 만약 여러분이 부드러운 애니메이션에 대해 정말로 걱정한다면, 여러분은 보통 어떤 종류의 GUI 툴킷에 matplotlib 플롯을 내장하고 있기 때문에, 이것은 큰 문제가 되지 않습니다.
하지만, 당신이 하는 일에 대해 조금 더 알지 못한다면, 저는 거기서 당신을 도울 수 없습니다.
그럼에도 불구하고 여전히 상당히 빠른 GUI 중립적인 방법이 있습니다.
import matplotlib.pyplot as plt
import numpy as np
import time
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)
fig, axes = plt.subplots(nrows=6)
fig.show()
# We need to draw the canvas before we start animating...
fig.canvas.draw()
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
return ax.plot(x, y, style, animated=True)[0]
lines = [plot(ax, style) for ax, style in zip(axes, styles)]
# Let's capture the background of the figure
backgrounds = [fig.canvas.copy_from_bbox(ax.bbox) for ax in axes]
tstart = time.time()
for i in xrange(1, 2000):
items = enumerate(zip(lines, axes, backgrounds), start=1)
for j, (line, ax, background) in items:
fig.canvas.restore_region(background)
line.set_ydata(np.sin(j*x + i/10.0))
ax.draw_artist(line)
fig.canvas.blit(ax.bbox)
print 'FPS:' , 2000/(time.time()-tstart)
이것은 나에게 200fps를 줍니다.
이것을 좀 더 편리하게 하기 위해, 다음과 같은 것이 있습니다.animations
모듈이 matplotlib의 최신 버전에 있습니다.
예를 들어,
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)
fig, axes = plt.subplots(nrows=6)
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
return ax.plot(x, y, style, animated=True)[0]
lines = [plot(ax, style) for ax, style in zip(axes, styles)]
def animate(i):
for j, line in enumerate(lines, start=1):
line.set_ydata(np.sin(j*x + i/10.0))
return lines
# We'd normally specify a reasonable "interval" here...
ani = animation.FuncAnimation(fig, animate, xrange(1, 200),
interval=0, blit=True)
plt.show()
Matplotlib은 훌륭한 출판 품질의 그래픽을 만들지만 속도에 매우 최적화되어 있지 않습니다.속도를 염두에 두고 설계된 다양한 파이썬 플로팅 패키지가 있습니다.
- http://vispy.org
- http://pyqtgraph.org/
- http://docs.enthought.com/chaco/
- http://pyqwt..net/http://pyqwt.sourceforge.net/
: 는 더 유지관리되지 ; 유지관리자가 [ edit : pyqttgraph를 추천합니다; pyqtgraph를 추천합니다] - http://code.google.com/p/guiqwt/
먼저, Joe Kington의 답변은 GUI 중립적인 접근 방식을 사용하여 매우 좋은 조언을 제공하며, 당신은 그의 조언(특히 Blitting에 대한)을 확실히 받아들여 실행에 옮겨야 합니다.이 접근 방식에 대한 자세한 내용은 Matplotlib Cookbook을 참조하십시오.
그러나 비GUI 중립적(GUI 편향?) 접근 방식이 플롯 속도를 높이는 핵심입니다.즉, 속도를 플롯하기 위해서는 백엔드가 매우 중요합니다.
matplotlib에서 다른 항목을 가져오기 전에 다음 두 줄을 놓습니다.
import matplotlib
matplotlib.use('GTKAgg')
물론 다양한 옵션을 사용할 수 있습니다.GTKAgg
하지만 전에 언급된 요리책에 따르면, 이것이 가장 빨랐습니다.자세한 옵션은 백엔드에 대한 링크를 참조하십시오.
Joe Kington ( .copy_from_bbox & .draw_artist & canvas.blit)이 제안한 첫 번째 솔루션의 경우, 저는 fig.canvas.draw() 줄 뒤의 배경을 캡처해야 했습니다. 그렇지 않으면 배경은 효과가 없었고 저는 당신이 말한 것과 같은 결과를 얻었습니다.fig.show() 뒤에 붙여도 Michael Brownne이 제안한 대로 작동하지 않습니다.
따라서 canvas.draw() 뒤에 배경 줄을 놓습니다.
[...]
fig.show()
# We need to draw the canvas before we start animating...
fig.canvas.draw()
# Let's capture the background of the figure
backgrounds = [fig.canvas.copy_from_bbox(ax.bbox) for ax in axes]
대부분의 사용자에게는 해당되지 않을 수 있지만, 저는 보통 Linux에서 컴퓨터를 작동하므로 기본적으로 matplotlib 플롯을 PNG 및 SVG로 저장합니다.이것은 Linux에서는 잘 작동하지만 Windows 7 설치[MiKTeX with Python(x,y) or Anaconda]에서는 견딜 수 없을 정도로 느리기 때문에 이 코드를 추가하기 시작했고, 거기서는 다시 정상적으로 작동합니다.
import platform # Don't save as SVG if running under Windows.
#
# Plot code goes here.
#
fig.savefig('figure_name.png', dpi = 200)
if platform.system() != 'Windows':
# In my installations of Windows 7, it takes an inordinate amount of time to save
# graphs as .svg files, so on that platform I've disabled the call that does so.
# The first run of a script is still a little slow while everything is loaded in,
# but execution times of subsequent runs are improved immensely.
fig.savefig('figure_name.svg')
언급URL : https://stackoverflow.com/questions/8955869/why-is-plotting-with-matplotlib-so-slow
'itsource' 카테고리의 다른 글
확인란을 선택한 경우 이 작업을 수행합니다. (0) | 2023.07.31 |
---|---|
페이지에 표시되지 않고 HTML5 비디오 요소를 동적으로 만듭니다. (0) | 2023.07.31 |
도커 이미지의 로그를 보는 방법은 무엇입니까? (0) | 2023.07.31 |
자바스크립트를 시작할 때 세미콜론을 시작하는 목적은 무엇입니까? (0) | 2023.07.31 |
"display:none"이 이미지 로드를 방해합니까? (0) | 2023.07.31 |