본문 바로가기
Python/Matplotlib

대화형 모드(interactive mode) - matplotlib(4)

by 콩돌 2019. 4. 5.
반응형

파이썬 버전 3.7 기준

matplotlib 버전 3.0.3 기준



  Matplotlib의 대화형 모드(interactive mode)


본 포스팅에서는 Matplotlib의 대화형 모드와 이에 관련된 백엔드에 대한 설명 및 예제를 다룬다.


  대화형 모드(interactive mode)


명령을 tty에서 읽어와 처리할 때, 인터프리터가 대화형 모드로 동작한다고 한다.

파이썬에서는 기본 프롬프트를 표시(>>>, In[xx] 등)하여 사용자가 명령을 할 때까지 대기한다. 

한줄로 끝나지 않고 이어지는 줄의 입력을 요청할 경우에는 보조 프롬프트(...)가 사용된다.


tty(teletyewriter): 텍스트 입력을 받는 터미널을 나타낸다.

프롬프트: 사용자의 명령을 입력받을 준비가 되었음을 나타내주는 표시이다.



  대화형 Backend(백엔드)


대화형 백엔드(backend)를 사용하여 플로팅을 화면에 띄우는 것이 가능하지만, 이것만으로는 플로팅을 화면에 띄워지지 않을 수도 있다.

플로팅을 화면에 띄울지 말지, 그리고 플롯이 그려진 이후 스크립트 혹은 쉘을 계속 사용할지 말지에 대한 여부는 불러와진 함수 혹은 메서드에 의존하고, matplotlib가 대화형 모드에 있는지 설정해주는 상태변수에 의존한다.


  기본 설정

설정에 대한 기본 값들은 matplotlibrc 파일에 의해 셋팅되며, 다른 구성매개변수에 따라 사용자 입맛에 맞춰 바꿀 수 있다(Customizing Matplotlib with style sheets and rcParams). 

설정은 matplotlib.interactive()에 의해 세팅될 수 있으며, 설정 값은 matplotlib.is_interactive()을 통해 확인할 수 있다. 

플로팅 명령을 하는 중간에 대화형 모드를 키거나 끄는 것(스크립트건 쉘이건 간에)은 거의 필요로 하지 않고 알게모르게 혼동스럽게 만드므로 일관적으로 하는 것이 중요하다. 


  대화형 모드와 비대화형 모드의 전환 

대화형 모드는 matplotlib.pyplot.ion() 의해 켜질 수 있으며, matplotlib.pyplot.ioff()의해 꺼진다. 


참고사항
  대화식 이용과 관련된 주요 변화 그리고 show의 특정 역할과 거동에서의 주요 변화는 matplotlib 1.0 버전에서 이루어졌으며, 버그는 1.0.1에서 수정되었다. 특별한 macosx의 예외를 사용하여 주요 대화형 백엔드에 대한 1.0.1 버전의 거동에 대해 설명하였다.

참고사항
  대화형 모드는 ipython과 일반적인 파이썬 쉘에서 적합한 백엔드를 사용하여 작동한다. 그러나 IDLE IDE에서는 작동하지 않는다. 만약 기본 값으로 입력되있는 백엔드가 대화형 모드를 지원하지 않는다면, 백엔드와 관련된 이전 포스팅(링크)을 참고하길 바란다.

  대화형 백엔드의 종류 

Matplotlib를 사용하기 위해 사용하는 대화형 백엔드들은 Qt5Agg, ipympl, GTK3Agg, macosx, TkAgg, nbAgg, WebAgg, GTK3Cairo, Qt4Agg, WXAgg 가 있다.

각 백엔드에 대한 설명은 이전 포스팅(링크)을 참고하기 바란다.



  예제 실습


  대화형 Backend(백엔드)의 예제

일반적인 파이썬 대화형 인터프리터에서 혹은 아무 옵션없는 ipython을 이용하여 아래 명령어를 실행하여보자.


# matplotlib의 import

In[6]: import matplotlib.pyplot as plt

Backend Qt5Agg is interactive backend. Turning interactive mode on.

 

In[7]: plt.ion()                # 대화형 모드 켬

In[8]: plt.plot([1, 50])       # plot 입력

Out[8]: [<matplotlib.lines.Line2D at 0xf0da090>]


사용자의 matplotlib 버전이 1.0.1이거나 혹은 그 이상의 버전이라고 가정한다. 그리고 대화형 백엔드가 이미 설치되어져 있고 디폴트로 설정되어 있어야 한다. 그러면 위의 명령어를 입력하였을때, 플롯을 볼 수 있고 터미널 프롬프트는 활성화 되어있을 것이다. 이 상황에서 추가적으로 아래의 명령어를 타이핑 할 수 있다.


In[9]: plt.title("interactive ex")       # plot 타이틀 설정

Out[9]: Text(0.5,1,'interactive ex')

In[10]: plt.xlabel("index")             # x축 제목 설정 

Out[10]: Text(0.5,23.4122,'index')


그리고 업데이트된 플롯을 확인할 수 있다. 1.5 버전 이래로는, 대부분 백엔드에서 다른 방법에 의해 플롯이 수정되는 것은 자동으로 디스플레이를 업데이트 시킨다. Axes 인스턴스에 대한 레퍼런스를 확인할 수 있다. 


In[11]: ax = plt.gca()             # 데이터플롯을 만들기 위해, 현재 쓰고 있는 축을 기준으로 삼는다.

In[12]: ax.plot([3.1, 2.2])         #  또 한번 입력할 plot 입력

Out[12]: [<matplotlib.lines.Line2D at 0xf281510>]


만약 macosx와 같은 백엔드를 사용하는 경우 혹은 matplotlib의 오래된 버전을 사용하는 경우에는, 새로운 라인을 추가하는 것만으로는 그림이 업데이트 되지 않을 수도 있다. 이런 경우에는 draw()를 불러오면 된다.


plt.draw()



  비대화형 Backend(백엔드)의 예제

비대화형 백엔드를 실행하고자 할때에는 위의 예제에서 실행했던 대화형 모드를 꺼야한다.

  

import matplotlib.pyplot as plt

Backend Qt5Agg is interactive backend. Turning interactive mode on.

import matplotlib


matplotlib.is_interactive()

Out[6]: False

plt.plot([1.6, 2.7])

Out[11]: [<matplotlib.lines.Line2D at 0x1055fe90>]


아마 아무것도 일어나지 않을 것이며, 화면에 아무것도 보여지지 않을 것이다(macosx 백엔드를 사용하지 않는한 이것은 약간 다를 수도 있다.). 플롯을 만들기 위해서는 아래와 같은 명령어를 입력해야한다.

  

plt.show()


위의 명령어를 입력하면 플롯이 화면에 뜬다. 그러나 터미널커멘드라인은 반응이 없어진다. 

show() 커맨드는 추가적인 커맨드의 임력을 막으며, 이런 상황은 플롯 윈도우가 꺼지기 전까지 유지된다.


※ 만일 커맨드 입력이 가능하더라도 대화형 예제처럼 추가적으로 입력하여 그래프를 변경시킬 수 없을 것이다.


  비대화형 모드의 필요성

이렇게 강제로 함수 입력을 막는것에 대해 장점이 무엇일까? 화면에 스크립트 파일을 이용하여 플롯을 띄울 경우를 가정해보자. 이런 경우 사용자는 플롯을 보고나서 스크립트를 끝내길 원한다. show()와 같이 입력을 막지 않는 경우에는 스크립트는 플롯을 잠깐 나타나게하고 그 이후 즉시 끝낼 것이며, 화면상에 남는 것은 아무 것도 없게된다.

추가적으로 비대화형 모드는 모든 그림을 화면상에 띄우는 것을 show()가 불러와지기 전까지 지연시킨다. 이것은 스크립트 상에서 새로운 feature들을 추가하기 위해 다시 그림을 그리는 것에 시간을 소비하는 것에 비해 더욱 효율적으로 만든다.


1.0 버전 이전에는 show()는 일반적으로 하나의 스크립트 상에서는 한 번을 초과하여 불러와질 수 없었다. 

1.0.1일 버전 혹은 그 이상의 버전에서는 이 제한이 풀리게되었고, 다음과 같은 스크립트를 작성하는 것이 가능해졌다.

 

스크립트 예제)

import numpy as np

import matplotlib.pyplot as plt


plt.ioff()

for i in range(3):

    plt.plot(np.random.rand(10))

    plt.show()


이는 3개의 플롯을 만들 수 있으며, 하나의 플롯이 꺼질 경우 그 다음 플롯이 형성되는 형태로 진행된다.


  요약


대화형 모드에서 pyplot 함수는 자동적으로 화면에 그래프를 출력할 수 있다.

 

대화형으로 플롯팅을 할때, 추가적으로 pyplot 함수를 불러올 때 오브젝트 메서드를 사용한다면, 플롯을 refresh를 하기위해 draw() 함수를 사용할 수 있다.


새로운 figure의 세트를 만들거나 끝내기 전에 하나 혹은 그 이상의 figure를 만들고 그것들을 화면상으로 출력하는 스크립트 상에서는 비대화형 모드(스크립트 사용)를 사용하는 것이 권장된다. 

이 경우에는 figure를 사용하고 사용자가 직접 이것을 끄기 전까지 다음 줄을 실행하는 것을 막기 위해 show() 함수를 이용하는 것이 좋다.


 

 

 

 

 참고자료

 https://matplotlib.org/tutorials/introductory/usage.html#sphx-glr-tutorials-introductory-usage-py

 https://docs.python.org/ko/3/tutorial/interpreter.html

 

 

 

 


반응형

댓글