programing

Matplotlib를 사용하여 비블로킹 방식으로 그림 그리기

sourcejob 2023. 1. 27. 21:17
반응형

Matplotlib를 사용하여 비블로킹 방식으로 그림 그리기

실행을 차단하지 않고 matplotlib 플롯을 함수로 만드는 데 문제가 있습니다.

사용해보았습니다.show(block=False)몇몇 사람들이 제안하듯이, 하지만 내가 얻는 건 얼어붙은 창문뿐이에요. ★★★★★★★★★★★★★★★★★★★★★★★★.show()결과는 올바르게 플롯되지만 창이 닫힐 때까지 실행이 차단됩니다.제가 읽은 다른 기사들을 보면show(block=False)이치노거맞 ??Qt4Agg이다제 코드를 보시고 뭔가 잘못된 것이 보이면 말씀해 주시겠습니까?여기 제 코드가 있습니다.

from math import *
from matplotlib import pyplot as plt
print(plt.get_backend())


def main():
    x = range(-50, 51, 1)
    for pow in range(1,5):   # plot x^1, x^2, ..., x^4

        y = [Xi**pow for Xi in x]
        print(y)

        plt.plot(x, y)
        plt.draw()
        #plt.show()             #this plots correctly, but blocks execution.
        plt.show(block=False)   #this creates an empty frozen window.
        _ = raw_input("Press [enter] to continue.")


if __name__ == '__main__':
    main()

추신. 새로운 창을 만들지 않고 플롯할 때마다 기존 창을 업데이트하고 싶다고 말하는 것을 잊었습니다.

나는 오랫동안 해결책을 찾았고, 이 을 찾았다.

내가) 것을 는 '의 할 것 .plt.ion(),plt.show())block=False한 것은 '무엇보다'입니다plt.pause(.001)(또는 당신이 원하는 시간에)그림 그리기를 포함한 메인코드가 sleep 상태일 때 GUI 이벤트가 발생하기 때문에 포즈가 필요합니다.슬립 스레드로부터 시간을 취득하는 것으로 실장될 가능성이 있기 때문에, IDE가 그것을 망치고 있을지도 모릅니다.모르겠습니다.

다음은 python 3.5에서 사용할 수 있는 구현입니다.

import numpy as np
from matplotlib import pyplot as plt

def main():
    plt.axis([-50,50,0,10000])
    plt.ion()
    plt.show()

    x = np.arange(-50, 51)
    for pow in range(1,5):   # plot x^1, x^2, ..., x^4
        y = [Xi**pow for Xi in x]
        plt.plot(x, y)
        plt.draw()
        plt.pause(0.001)
        input("Press [enter] to continue.")

if __name__ == '__main__':
    main()

나에게 효과가 있는 간단한 요령은 다음과 같습니다.

  1. show 내에서 block = False 인수를 사용합니다.plt.show(block = False)
  2. .py 스크립트의 마지막에 다른 plt.show()를 사용합니다.

:

import matplotlib.pyplot as plt

plt.imshow(add_something)
plt.xlabel("x")
plt.ylabel("y")

plt.show(block=False)

#more code here (e.g. do calculations and use print to see them on the screen

plt.show()

주의: 스크립트의 마지막 행입니다.

그래프를 배열에 쓴 다음 배열을 다른 스레드에 표시하여 실행을 차단하지 않도록 할 수 있습니다.다음은 pyformulas 0.2.8에서 pf.screen을 사용하여 플롯을 동시에 생성하고 표시하는 예제입니다.

import pyformulas as pf
import matplotlib.pyplot as plt
import numpy as np
import time

fig = plt.figure()

canvas = np.zeros((480,640))
screen = pf.screen(canvas, 'Sinusoid')

start = time.time()
while True:
    now = time.time() - start

    x = np.linspace(now-2, now, 100)
    y = np.sin(2*np.pi*x) + np.sin(3*np.pi*x)
    plt.xlim(now-2,now+1)
    plt.ylim(-3,3)
    plt.plot(x, y, c='black')

    # If we haven't already shown or saved the plot, then we need to draw the figure first...
    fig.canvas.draw()

    image = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8, sep='')
    image = image.reshape(fig.canvas.get_width_height()[::-1] + (3,))

    screen.update(image)

#screen.close()

결과:

사인 애니메이션

면책사항:난 피포뮬라의 관리인이야

참조: Matplotlib: 그림을 numpy 배열에 저장

라이브 플롯팅

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 100)
# plt.axis([x[0], x[-1], -1, 1])      # disable autoscaling
for point in x:
    plt.plot(point, np.sin(2 * point), '.', color='b')
    plt.draw()
    plt.pause(0.01)
# plt.clf()                           # clear the current figure

데이터 양이 너무 많으면 간단한 카운터를 사용하여 업데이트 속도를 낮출 수 있습니다.

cnt += 1
if (cnt == 10):       # update plot each 10 points
    plt.draw()
    plt.pause(0.01)
    cnt = 0

프로그램 종료 후 플롯 보류

이것은 만족스러운 답을 찾을 수 없는 나의 실제 문제이며, 나는 스크립트가 끝난 후에 닫히지 않는 플롯을 원했다(MATLAB와 같이).

생각해보면 스크립트가 끝나면 프로그램이 종료되고 플롯을 이렇게 유지할 논리적인 방법이 없기 때문에 두 가지 옵션이 있습니다.

  1. 스크립트가 종료되지 않도록 차단합니다(Plt.show()이며 원하는 것은 아닙니다).
  2. 플롯을 다른 줄에 싣다(너무 복잡하다)

이것은 나에게 만족스럽지 못했기 때문에 나는 박스 밖에서 다른 해결책을 찾았다.

외부 뷰어의 Save To File 및 View

이를 위해서는 저장과 보기가 모두 빨라야 하며 뷰어는 파일을 잠그지 않아야 하며 자동으로 콘텐츠를 업데이트해야 합니다.

저장할 형식 선택

벡터 기반 포맷은 작고 빠릅니다.

  • SVG는 좋지만 기본적으로 수동 새로 고침이 필요한 웹 브라우저를 제외하고는 좋은 뷰어를 찾을 수 없습니다.
  • PDF는 벡터 형식을 지원하며 라이브 업데이트를 지원하는 경량 뷰어도 있습니다.

라이브 업데이트 기능이 있는 고속 경량 뷰어

PDF에는 몇 가지 좋은 옵션이 있습니다.

  • Windows 에서는, Sumatra 를 사용합니다.PDF - 무료, 고속, 경량 (1.8만 사용)내 경우 MB RAM)

  • Linux 에서는, Evince(GNOME)나 Occular(KDE)의 옵션이 몇개인가 있습니다.

샘플 코드 및 결과

파일에 플롯을 출력하기 위한 샘플 코드

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(2 * x)
plt.plot(x, y)
plt.savefig("fig.pdf")

첫 번째 실행 후 위에 언급된 뷰어 중 하나에서 출력 파일을 열고 즐깁니다.

SumatraPDF를 함께 레이트를 얻을 수 가까이 수 ) 기 sumatra Sumatra를 사용하시면 .PDF pdf VSCode pdf pdf pdf pdf pdf 。또한 프로세스는 준라이브 업데이트 레이트를 얻을 수 있을 정도로 빠릅니다(셋업으로 10Hz에 가까운 주파수를 얻을 수 있습니다).time.sleep()인터벌 사이

이 답변들 중 많은 부분이 과장되어 있고, 제가 알 수 있는 바로는 그 답변들이 이해하기 어렵지 않습니다.

하시면 됩니다.plt.ion()원하신다면요, 하지만 제가 찾은 바로는plt.draw() 효과적이다

인 에서는 이미지를 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.plot() ★★★★★★★★★★★★★★★★★」scatter() 어떤 이든 상관없습니다.figimage()하지 않다츠요시

plt.figimage(image_to_show)
plt.draw()
plt.pause(0.001)

또는

fig = plt.figure()
...
fig.figimage(image_to_show)
fig.canvas.draw()
plt.pause(0.001)

이치노
@Picture의 했습니다.@krs013 @Default Picture @Default Picture 。
한 한 사람이 실에 모든 하거나, 이 문제를 이 하는 을 피할 수 .

가 알게 된 건 '아, 아, 아,plt.pause(0.001)이치노

plt.show() 및 plt.draw()는 불필요하거나 어떤 방법으로든 차단됩니다.여기 그림을 그리고 업데이트한 후 계속하는 코드가 있습니다.기본적으로 plt.pause(0.001)가 matlab의 드로우에 가장 가까운 것으로 보입니다.

유감스럽게도 이러한 플롯은 input() 명령어를 삽입하는 경우를 제외하고 인터랙티브하지 않습니다(프리즈).그 후 코드는 정지합니다.

plt.pause(interval) 명령어 매뉴얼에는 다음과 같이 기재되어 있습니다.

액티브한 수치가 있는 경우는, 일시정지 전에 갱신되어 표시됩니다...이것은 조잡한 애니메이션에 사용할 수 있습니다.

이게 바로 우리가 원하는 거야다음 코드를 사용해 보십시오.

import numpy as np
from matplotlib import pyplot as plt

x = np.arange(0, 51)               # x coordinates  
         
for z in range(10, 50):

    y = np.power(x, z/10)          # y coordinates of plot for animation

    plt.cla()                      # delete previous plot
    plt.axis([-50, 50, 0, 10000])  # set axis limits, to avoid rescaling
    plt.plot(x, y)                 # generate new plot
    plt.pause(0.1)                 # pause 0.1 sec, to force a plot redraw

Iggy의 답변이 가장 이해하기 쉬웠는데, 그 다음 작업을 할 때 다음과 같은 오류가 발생했습니다.subplot내가 막 할 때는 없었던 명령어show:

MatplotlibDecrecationWarning:이전 축과 동일한 인수를 사용하여 축을 추가하면 현재 이전 인스턴스가 재사용됩니다.이후 버전에서는 항상 새 인스턴스가 생성되어 반환됩니다.한편, 이 경고는 각 축 인스턴스에 고유한 라벨을 전달함으로써 억제할 수 있으며 향후 동작을 보장할 수 있습니다.

이 오류를 방지하려면 사용자가 Enter 키를 누른 후 플롯을 닫거나 클리어합니다.

다음은 나에게 효과가 있었던 코드입니다.

def plt_show():
    '''Text-blocking version of plt.show()
    Use this instead of plt.show()'''
    plt.draw()
    plt.pause(0.001)
    input("Press enter to continue...")
    plt.close()

Python 패키지 드로우에서는 실시간으로 플롯을 비블로킹 방식으로 업데이트할 수 있습니다.
또한 웹캠 및 OpenCV와 함께 작동하여 각 프레임의 측정값을 표시합니다.
원래의 투고를 참조해 주세요.

언급URL : https://stackoverflow.com/questions/28269157/plotting-in-a-non-blocking-way-with-matplotlib

반응형