[PyQt5] 메인창에 Matplotlib 그래프 나타내기¶
이 페이지에서는 PyQt5 어플리케이션 창에서 Matplotlib 그래프를 플롯하는 방법에 대해 설명합니다.
Matplotlib의 다양한 기능을 사용해서 정적인 그래프, 움직이는 그래프를 간편하게 구현할 수 있습니다.
■ Table of Contents
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_qt5agg의 FigureCanvas 클래스는 PyQt5 어플리케이션에서 그림이 그려질 캔버스 (canvas)가 됩니다.
matplotlib.pyplot 모듈을 사용해서 그래프를 화면에 표시할 경우 아래 그림과 같은 툴바가 자동으로 생성됩니다.
하지만 직접 유저 인터페이스 코드를 작성한다면 툴바를 수동으로 추가해야 됩니다.
matplotlib.backends.backend_qt5agg의 NavigationToolbar2QT를 사용해서 툴바를 추가할 수 있습니다.
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_())
예제에서는 창의 타이틀과 크기, 위치만 지정했습니다.
아래와 같은 창이 화면에 표시됩니다.
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()을 사용해서 데이터를 그래프로 표현했습니다.
결과는 아래와 같습니다.
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 메서드가 호출되도록 했습니다.
결과는 아래와 같습니다.