MapleStory Finger Point

Development/Graph

PyQt5 PyQtGraph (+ clickEvent, Animation)

吳鍾振 2021. 10. 18. 20:27

최근에 회사에서 그래프를 그려야 할 프로젝트가 있었다

처음에는 예전에 써봐서 익숙했던 matplotlib을 사용했었다

하지만 나중에 exe 실행 파일을 만들어야 했는데, 이 matplotlib 때문에 고생했다. (+ opencv..)

어차피 PyQt5를 사용하여 구현하는데 여기에도 그래프 관련 모듈이 있겠지 해서 봤는데 꽤나 괜찮은 걸 찾았다

바로 PyQtChart 라는 모듈이다

설치법은 그냥 이름 그대로 install 진행

pip install PyQtChart

 

PyQtChart 안에서도 다양한 그래프, 차트들을 만들 수 있는데 난 PieChart를 그려보았다.

import sys

from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtChart import QChart, QChartView, QPieSeries
from PyQt5.QtGui import QPainter
from PyQt5.QtCore import Qt


class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("PyQtChart Pie Chart")
        self.setGeometry(600, 100, 680, 600)

        self.show()

        self.select = 0
        self.slice = None

        self.create_piechart()

    def create_piechart(self):
        self.series = QPieSeries()
        self.series.append("Python", 80)
        self.series.append("C++", 70)
        self.series.append("Java", 50)
        self.series.append("C#", 40)
        self.series.append("PHP", 30)
        self.series.append("Swift", 15)

        # adding slice
        self.series.doubleClicked.connect(self.series_clickEvent)

        self.slice = self.series.slices()[0]

        # self.slice.setExploded(True)
        # self.slice.setLabelVisible(True)
        # self.slice.setPen(QPen(Qt.darkGreen, 2))
        # self.slice.setBrush(Qt.green)

        chart = QChart()
        chart.legend().hide()
        chart.addSeries(self.series)
        chart.createDefaultAxes()
        chart.setAnimationOptions(QChart.SeriesAnimations)
        chart.setTitle("Pie Chart Example")

        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)

        chartview = QChartView(chart)
        chartview.setRenderHint(QPainter.Antialiasing)

        self.setCentralWidget(chartview)

    def series_clickEvent(self, slice):

        self.slice.setExploded(False)
        self.slice.setLabelVisible(False)

        self.slice = self.series.slices()[self.select]
        # for i in self.series.slices():
        #     print(self.series.slices()[i])

        self.slice.setExploded(True)
        self.slice.setLabelVisible(True)
        # self.slice.setPen(QPen(Qt.darkGreen, 2))
        # self.slice.setBrush(Qt.green)

        self.select = self.select + 1
        # self.slice = self.series.slices()[self.select]
        print(self.select)
        print(slice.label(), slice.value())

        self.series.slices().clear()


if __name__ == "__main__":
    App = QApplication(sys.argv)
    window = Window()
    sys.exit(App.exec_())

    # [23번 줄]
    def create_piechart(self):
        self.series = QPieSeries()
        self.series.append("Python", 80)
        self.series.append("C++", 70)
        self.series.append("Java", 50)
        self.series.append("C#", 40)
        self.series.append("PHP", 30)
        self.series.append("Swift", 15)

create_piechart 함수에서 series에 QPieSeries를 할당하고 append로 삽입하고 싶은 데이터를 입력한다
append의 첫번째 인자는 데이터의 이름, 두번째 인자는 데이터의 할당량이다.

할당량은 어차피 총 합 100%으로 계산되어 자동으로 할당되어진다.
ex) ~.append("Python", 80) == ~.append("Python", 8)

 

        # [33번 줄]
        self.series.doubleClicked.connect(self.series_clickEvent)

마우스 이벤트로 clicked 와 doubleClicked 중 뭔가 누르는 맛이 있도록 더블 클릭을 사용했다
차트 데이터를 더블 클릭하면 series_clickEvent 함수에 연결됨

 

        # [48번 줄]
        chart = QChart()
        ...
        chart.setAnimationOptions(QChart.SeriesAnimations)

여기서는 차트의 애니메이션을 설정한다
애니메이션 설정은 아래와 같이 4가지가 있는데 SeriesAnimations를 써야 '아 이게 애니메이션이지' 라고 생각해서 사용했다

 

    self.slice = self.series.slices()[0]
    ...

    # [59번 줄]
    def series_clickEvent(self, slice):
        self.slice.setExploded(False)
        self.slice.setLabelVisible(False)
        self.slice = self.series.slices()[self.select]
        self.slice.setExploded(True)
        self.slice.setLabelVisible(True)

        self.select = self.select + 1
        if self.select == self.series.count():
            self.select = 0

더블 클릭하면 실행되어지는 함수 series_clickEvent 이다
self.slice의 setExploded는 데이터 분리 여부를 설정해주고, setLabelVisible은 데이터 이름 표시를 설정해준다

클릭 시 self.slice를 다시 한번 더 선언해주는데 초기값은 0번 값, 즉 첫 번째 데이터부터 시작되며
self.select 변수를 1씩 증가시켜 한 바퀴 돌린다.
self.series.count()는 현재 차트의 데이터 개수를 반환해줘서 위 코드에서 self.select가 6이 되면 다시 0으로 돌아가도록 한다

 

참고로 선택한 데이터를 애니메이션 처리가 아닌 그냥 차트 아무곳을 눌러도 되는데, 아직 마우스로 누른 데이터만 띄우는 건 찾지 못했다
다음에 찾으면 추가로 올리겠다

반응형

'Development > Graph' 카테고리의 다른 글

Polar Plot (자유자재로) 그리기  (0) 2020.09.09