Python

색깔 변경하며 그래프 그리기 (PySide6, PyQtGraph)

팁택토 2025. 3. 15. 10:18

그래프를 그릴 때 색깔을 변경하며 그래프를 그려야 할 때가 있다. 

이때 한 두개라면 직접 색깔을 지정해주겠지만, 100개 정도 된다면? 

자동으로 순처적으로 색깔을 변경해가면서 그려주면 좋겠다는 생각을 하게 된다. 

 

한번 해보자. 

아, 왜 PySide6 인가? PyQT도 아니고... 이건 라이센스 때문이다. PySide6가 라이센스에서 더 프리하기 때문이다. PyQT와 PySide 와의 차이는 아래 분이 더 설명을 잘 해주셨다. 

https://dev-overload.tistory.com/44

 

[Python] PyQt와 PySide에 대한 잡설

*본 포스팅에서는 PyQT나 PySide의 사용 방법에 대한 설명을 포함하지 않습니다. PyQT와 PySide 필자는 본 블로그에 따로 포스팅하지는 않지만 종종 취미 겸, 개인 사용 목적으로 윈도 애플리케이션을

dev-overload.tistory.com

 

그 다음으로 왜 pyqtgraph 인가? matplotlib 가 있는데도. 그림이 예쁘게 나오는 것은 matplotlib가 더 예쁜 것 같다. 다만 실시간 그래프를 그리기에 matplotlib는 약간 부족하다 

이것은 아래 글로 대신 한다 .

https://dnai-deny.tistory.com/67

 

[Monitoring System] 4.1 세상에 더 빠른 방법이 - pyqtgraph

[Monitoring System] 3. UDP 통신으로 실시간 진동 데이터 Plotting(feat. matplotlib) 이번 포스팅에서는 이전 mqtt에서 사용한 예제 데이터보다 2만 배 정도 많은 데이터를 DAQ에서 받아오는 UDP 예제를 만들 것

dnai-deny.tistory.com

 

자, 이제 본격적인 내용을 시작하자. 

제일 먼저... 일단 귀찮으니 쳇지피티에게 물어보자. 

 

일단 물어보고 시작하자. 대신 구체적으로 물어봐야 답도 잘 해준다.

 

그러자 아래와 같은 코드를 알려준다. 

import sys
import numpy as np
import pyqtgraph as pg
from pyqtgraph.Qt import QtWidgets

def generate_color(index, total=100):
    """
    그래프의 인덱스에 따라 색상이 점점 진해지도록 HSV 색공간을 활용
    """
    hue = 240  # 파란색 계열 (0=빨강, 120=초록, 240=파랑)
    saturation = 255  # 채도는 최대로
    value = int(50 + (index / total) * 205)  # 점점 밝아지는 효과 (50~255)
    return pg.intColor(value, hues=total)

def main():
    app = QtWidgets.QApplication(sys.argv)
    win = pg.GraphicsLayoutWidget(show=True)
    win.setWindowTitle("100개의 그래프 색상 변화")
    plot = win.addPlot()
    
    for i in range(100):
        x = np.linspace(0, 10, 100)
        y = np.sin(x + i * 0.2)  # 그래프마다 조금씩 다르게 변형
        color = generate_color(i)
        plot.plot(x, y, pen=color)
    
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

 

흠... 살짝 불안한데? 일단 실행해보자. 

오, 한번에? 근데 보기가 좀..

 

100 개의 그래프를 그려서 그런지, 보기가 너무 힘들다. 10개로 줄여서 다시 실행해보면 아래와 같다. 

오, 깔끔하다. 색깔로 어느 것이 먼저 그려진 것인지 대충 알 수 있다.

 

오, 색깔로 어느 것이 먼저 그려지고 어느 것이 나중에 그려진 것인지 대충은 알 수 있다. 그래프가 그려진 순서를 대충은 유추할 수 있게 되었다. 굿굿. 

 

하지만 아직 살짝은 부족한 것 같다. 라벨이나 심볼 등을 그래프 자체에 붙이면 더 확실하겠는데... 

쳇지피티에게 요청해보자. 

쳇지피티님, 심볼을 넣어주세요.

 

그랬더니 알려준 코드는 아래와 같다. 

import pyqtgraph as pg
from pyqtgraph.Qt import QtWidgets
import numpy as np

# PyQt 애플리케이션 생성
app = QtWidgets.QApplication([])

# 그래프 윈도우 생성
win = pg.GraphicsLayoutWidget(show=True)
win.setWindowTitle('PyQtGraph - 색상 및 숫자 심볼')

# Plot 추가
plot = win.addPlot()
plot.setTitle("100개의 그래프 (색상 점진적 변화 & 숫자 심볼)")
plot.addLegend()

# 색상 및 데이터 생성
num_plots = 100
x = np.linspace(0, 10, 100)  # X축 값 (모든 그래프에서 동일)
colors = [pg.intColor(i, hues=num_plots) for i in range(num_plots)]  # 색상 점진적 변화

for i in range(num_plots):
    y = np.sin(x + i * 0.1)  # Y축 값 (각 그래프마다 다르게 설정)
    
    # 그래프 플로팅 (각 그래프에 심볼 추가)
    curve = plot.plot(x, y, pen=pg.mkPen(colors[i], width=2), symbol=str(i), 
    				symbolSize=10, name=f"Graph {i}")
    
    # 숫자 심볼 추가 (각 그래프의 첫 번째 점에 TextItem 추가)
    text = pg.TextItem(text=str(i), color=colors[i], anchor=(0.5, -0.5))
    text.setPos(x[0], y[0])  # 첫 번째 점 위치에 배치
    plot.addItem(text)

# 실행
QtWidgets.QApplication.instance().exec_()

 

응? symbol=str(i) 같은게 가능한가? 내가 몰랐던 것일 수 있으니, 일단 한번 실행해보자. 

야. 에러 나는데? 응? 제대로 안할래?

역시 이상하다고 느낀 부분에서 에러가 난다. 

에러 자체를 쳇지피티에게 물어보자. 

이제야 제대로 알려주는 군. 처음부터 그럴 것이지.

 

그리고 해결방법으로 pg.TextItem을 사용하라고 알려주었다. 역시 해보자. 

흠. 내가 원한게 이게 맞나? 살짝 다른데? 좀 키워보니 그래프 옆에 index가 들어가 있기는 하다.

 

흠. 그래프 색깔은 처음 파란색 계열이 좋은 듯 하고, 그런데 그래프 옆에 index 가 들어있는 것은 이게 더 좋고. 

두가지를 섞어야 겠다. 

오, 그래프 색깔도, 심볼도 다 잘 들어갔다.

 

변경사항은 아래와 같다. 

- 그래프를 10개만 그리게 했고

- 그에 따라 색상을 처음 방식으로 설정하도록 수정했고

- 그래프 name 을 삭제했다. 

 

두가지를 섞은 코드는 아래와 같다.

import pyqtgraph as pg
from pyqtgraph.Qt import QtWidgets
import numpy as np

# PyQt 애플리케이션 생성
app = QtWidgets.QApplication([])

# 그래프 윈도우 생성
win = pg.GraphicsLayoutWidget(show=True)
win.setWindowTitle('PyQtGraph - 색상 및 숫자 심볼')

# Plot 추가
plot = win.addPlot()
plot.setTitle("100개의 그래프 (색상 점진적 변화 & 숫자 심볼)")
plot.addLegend()

# 색상 및 데이터 생성
num_plots = 10
x = np.linspace(0, 10, 100)  # X축 값 (모든 그래프에서 동일)
colors = [pg.intColor((50+(i/100)*205), hues=100) for i in range(num_plots)]  # 색상 점진적 변화

for i in range(num_plots):
    y = np.sin(x + i * 0.1)  # Y축 값 (각 그래프마다 다르게 설정)
    
    # 그래프 플로팅 (선 그래프 추가)
    # curve = plot.plot(x, y, pen=pg.mkPen(colors[i], width=2), name=f"Graph {i}")
    curve = plot.plot(x, y, pen=pg.mkPen(colors[i], width=2))

    # 숫자 심볼 추가 (각 그래프의 첫 번째 점에 숫자를 텍스트로 표시)
    text = pg.TextItem(text=str(i), color=colors[i], anchor=(0.5, -0.5))
    text.setPos(x[0], y[0])  # 첫 번째 점 위치에 배치
    plot.addItem(text)

# 실행
QtWidgets.QApplication.instance().exec_()

 

가만히 생각해보니.. pg.TextItem 으로 심볼을 추가하는 거라면, 꼭 숫자 인덱스가 아니라 글자도 넣을 수 있는 것 아닌가? 

오, 글자도 된다.

 

pg.TextItem 부분만 아래처럼 바꿔주면 된다. 

    # 숫자 심볼 추가 (각 그래프의 첫 번째 점에 숫자를 텍스트로 표시)
    sym_txt = 'Result/day/trial-'+str(i)
    text = pg.TextItem(text=sym_txt, color=colors[i], anchor=(0.5, -0.5))

 

오케. 오늘은 여기까지!!