[PyQt5] 메인창에 Matplotlib 그래프 나타내기


[PyQt5] 메인창에 Matplotlib 그래프 나타내기

이 페이지에서는 PyQt5 어플리케이션 창에서 Matplotlib 그래프를 플롯하는 방법에 대해 설명합니다.

Matplotlib의 다양한 기능을 사용해서 정적인 그래프, 움직이는 그래프를 간편하게 구현할 수 있습니다.



1) 모듈 임포트하기

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
from matplotlib.backends.backend_qt5agg import FigureCanvas as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure

우선 PyQt5 창에 Matplotlib 그래프를 그리기 위해서 필요한 모듈을 임포트합니다.

matplotlib.backends.backend_qt5aggFigureCanvas 클래스는 PyQt5 어플리케이션에서 그림이 그려질 캔버스 (canvas)가 됩니다.

matplotlib.pyplot 모듈을 사용해서 그래프를 화면에 표시할 경우 아래 그림과 같은 툴바가 자동으로 생성됩니다.


[PyQt5] 메인창에 Matplotlib 그래프 나타내기

하지만 직접 유저 인터페이스 코드를 작성한다면 툴바를 수동으로 추가해야 됩니다.

matplotlib.backends.backend_qt5aggNavigationToolbar2QT를 사용해서 툴바를 추가할 수 있습니다.




2) 기본 창 띄우기

class MyApp(QMainWindow):

  def __init__(self):
      super().__init__()

      self.setWindowTitle('Matplotlib in PyQt5')
      self.setGeometry(300, 200, 600, 400)
      self.show()

if __name__ == '__main__':
  app = QApplication(sys.argv)
  ex = MyApp()
  sys.exit(app.exec_())

예제에서는 창의 타이틀과 크기, 위치만 지정했습니다.

아래와 같은 창이 화면에 표시됩니다.


[PyQt5] 메인창에 Matplotlib 그래프 나타내기




3) 캔버스에 그래프 그리기

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
from matplotlib.backends.backend_qt5agg import FigureCanvas as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure


class MyApp(QMainWindow):

  def __init__(self):
      super().__init__()

      self.main_widget = QWidget()
      self.setCentralWidget(self.main_widget)

      canvas = FigureCanvas(Figure(figsize=(4, 3)))
      vbox = QVBoxLayout(self.main_widget)
      vbox.addWidget(canvas)

      self.addToolBar(NavigationToolbar(canvas, self))

      self.ax = canvas.figure.subplots()
      self.ax.plot([0, 1, 2], [1, 5, 3], '-')

      self.setWindowTitle('Matplotlib in PyQt5')
      self.setGeometry(300, 100, 600, 400)
      self.show()

if __name__ == '__main__':
  app = QApplication(sys.argv)
  ex = MyApp()
  sys.exit(app.exec_())

우선 위젯을 하나 만들고, 메인 창의 중심 위젯으로 지정했습니다.

FigureCanvas 객체를 하나 만들면서 matplotlib.figure 객체를 입력합니다.

QVBoxLayout 클래스는 포함하는 위젯들을 수직 방향으로 배치하도록 합니다.

중심 위젯 (self.main_widget)이 포함하는 위젯들이 수직 방향으로 배치됩니다. 캔버스 객체를 이 중심 위젯에 추가했습니다.

addToolBar() 메서드를 사용해서 NavigationToolbar2QT 객체를 메인 창에 추가했습니다.

FigureCanvas 객체의 figure 속성은 Figure 인스턴스입니다. subplots() 메서드로 subplot을 하나 만들고, plot()을 사용해서 데이터를 그래프로 표현했습니다.

결과는 아래와 같습니다.


[PyQt5] 메인창에 Matplotlib 그래프 나타내기




4) 움직이는 그래프 그리기

import sys
import time
import numpy as np
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
from matplotlib.backends.backend_qt5agg import FigureCanvas as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure


class MyApp(QMainWindow):

  def __init__(self):
      super().__init__()

      self.main_widget = QWidget()
      self.setCentralWidget(self.main_widget)

      canvas = FigureCanvas(Figure(figsize=(4, 3)))
      vbox = QVBoxLayout(self.main_widget)
      vbox.addWidget(canvas)

      self.addToolBar(NavigationToolbar(canvas, self))

      self.ax = canvas.figure.subplots()
      self.ax.plot([0, 1, 2], [1, 5, 3], '-')

      dynamic_canvas = FigureCanvas(Figure(figsize=(4, 3)))
      vbox.addWidget(dynamic_canvas)

      self.dynamic_ax = dynamic_canvas.figure.subplots()
      self.timer = dynamic_canvas.new_timer(
          100, [(self.update_canvas, (), {})])
      self.timer.start()

      self.setWindowTitle('Matplotlib in PyQt5')
      self.setGeometry(300, 100, 600, 600)
      self.show()

  def update_canvas(self):
      self.dynamic_ax.clear()
      t = np.linspace(0, 2 * np.pi, 101)
      self.dynamic_ax.plot(t, np.sin(t + time.time()), color='deeppink')
      self.dynamic_ax.figure.canvas.draw()

if __name__ == '__main__':
  app = QApplication(sys.argv)
  ex = MyApp()
  sys.exit(app.exec_())

움직이는 그래프를 나타내기 위해서 새로운 FigureCanvas 객체를 만들었습니다.

new_timer() 함수는 밀리초 (ms) 단위의 주기적인 이벤트를 발생합니다.

예제에서는 0.1초 간격으로 self.update_canvas 메서드가 호출되도록 했습니다.

결과는 아래와 같습니다.


[PyQt5] 메인창에 Matplotlib 그래프 나타내기


이전글/다음글