# -*- coding: utf-8 -*-
"""
From main library's example, ScatterPlot.py, 
I will take out one of chart to make it for Lidar data display.
"""
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import numpy as np
from collections import namedtuple
from itertools import chain

app = QtGui.QApplication([])
mw = QtGui.QMainWindow()
mw.resize(530,500)
view = pg.GraphicsLayoutWidget()  ## GraphicsView with GraphicsLayout inserted by default
mw.setCentralWidget(view)
mw.show()
mw.setWindowTitle('Lidar Test')

## create four areas to add plots
w1 = view.addPlot()

# Add polar grid lines
w1.addLine(x=0, pen=0.3)
w1.addLine(y=0, pen=0.3)
for r in range(2, 2000, 200):   # Draw 10 circles
   # Adding circle (x, y, width, height)
   cwidth = r * 2
   cheight = r * 2
   circle = pg.QtGui.QGraphicsEllipseItem(-r, -r, cwidth, cheight)
   circle.setPen(pg.mkPen(0.3))
   w1.addItem(circle)  

###### 이제 여기 아래만 집중적으로 공략하면 라이다 데이타를 적을수 있게 될 듯 하다.  #######
n = 360
s1 = pg.ScatterPlotItem(size=5, pen=pg.mkPen(None), brush=pg.mkBrush(255, 255, 255, 120))
# Make 2 Dimension (X,Y) points array of 360 dots on scale of 500 for 500 mm.
pos = np.random.normal(size=(2,n), scale=500)
spots = [{'pos': pos[:,i], 'data': 1} for i in range(n)] + [{'pos': [0,0], 'data': 1}]
s1.addPoints(spots)
w1.addItem(s1)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

 

 

원래 프로그램에서 기초 점찍는 부분들만 뽑아낸 기둥.

(my local file name :  ~/py/pyqtgraph/l-01_basic_dots.py

 

# -*- coding: utf-8 -*-
"""
From main library's example, ScatterPlot.py, 
I will take out one of chart to make it for Lidar data display.
"""
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import numpy as np
from collections import namedtuple
from itertools import chain

app = QtGui.QApplication([])
mw = QtGui.QMainWindow()
mw.resize(500,800)
view = pg.GraphicsLayoutWidget()  ## GraphicsView with GraphicsLayout inserted by default
mw.setCentralWidget(view)
mw.show()
mw.setWindowTitle('Lidar Test')

## create four areas to add plots
w1 = view.addPlot()
view.nextRow()
w4 = view.addPlot()
print("Generating data, this takes a few seconds...")

## There are a few different ways we can draw scatter plots; each is optimized for different types of data:

## 1) All spots identical and transform-invariant (top-left plot).
## In this case we can get a huge performance boost by pre-rendering the spot
## image and just drawing that image repeatedly.

n = 360
s1 = pg.ScatterPlotItem(size=5, pen=pg.mkPen(None), brush=pg.mkBrush(255, 255, 255, 120))
pos = np.random.normal(size=(2,n), scale=1e-5)
spots = [{'pos': pos[:,i], 'data': 1} for i in range(n)] + [{'pos': [0,0], 'data': 1}]
s1.addPoints(spots)
w1.addItem(s1)

## Test performance of large scatterplots

s4 = pg.ScatterPlotItem(
    size=10,
    pen=pg.mkPen(None),
    brush=pg.mkBrush(255, 255, 255, 20),
    hoverable=True,
    hoverSymbol='s',
    hoverSize=15,
    hoverPen=pg.mkPen('r', width=2),
    hoverBrush=pg.mkBrush('g'),
)
n = 10000
pos = np.random.normal(size=(2, n), scale=1e-9)
s4.addPoints(
    x=pos[0],
    y=pos[1],
    #size=(np.random.random(n) * 20.).astype(int),
    #brush=[pg.mkBrush(x) for x in np.random.randint(0, 256, (n, 3))],
    data=np.arange(n)
)
w4.addItem(s4)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

원래 따라오는 데모를 혼자 돌게 고친 내용.   그 과정에서 2줄을 블락을 시켰는데 전체 과정에 큰 차이가 없어서 다행입니다.

 

 

# -*- coding: utf-8 -*-
"""
Example demonstrating a variety of scatter plot features.
"""


from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import numpy as np
from collections import namedtuple
from itertools import chain

app = QtGui.QApplication([])
mw = QtGui.QMainWindow()
mw.resize(800,800)
view = pg.GraphicsLayoutWidget()  ## GraphicsView with GraphicsLayout inserted by default
mw.setCentralWidget(view)
mw.show()
mw.setWindowTitle('pyqtgraph example: ScatterPlot')

## create four areas to add plots
w1 = view.addPlot()
w2 = view.addViewBox()
w2.setAspectLocked(True)
view.nextRow()
w3 = view.addPlot()
w4 = view.addPlot()
print("Generating data, this takes a few seconds...")

## Make all plots clickable
clickedPen = pg.mkPen('b', width=2)
lastClicked = []
def clicked(plot, points):
    global lastClicked
    for p in lastClicked:
        p.resetPen()
    print("clicked points", points)
    for p in points:
        p.setPen(clickedPen)
    lastClicked = points


## There are a few different ways we can draw scatter plots; each is optimized for different types of data:

## 1) All spots identical and transform-invariant (top-left plot).
## In this case we can get a huge performance boost by pre-rendering the spot
## image and just drawing that image repeatedly.

n = 300
s1 = pg.ScatterPlotItem(size=10, pen=pg.mkPen(None), brush=pg.mkBrush(255, 255, 255, 120))
pos = np.random.normal(size=(2,n), scale=1e-5)
spots = [{'pos': pos[:,i], 'data': 1} for i in range(n)] + [{'pos': [0,0], 'data': 1}]
s1.addPoints(spots)
w1.addItem(s1)
s1.sigClicked.connect(clicked)


## 2) Spots are transform-invariant, but not identical (top-right plot).
## In this case, drawing is almsot as fast as 1), but there is more startup
## overhead and memory usage since each spot generates its own pre-rendered
## image.

TextSymbol = namedtuple("TextSymbol", "label symbol scale")

def createLabel(label, angle):
    symbol = QtGui.QPainterPath()
    #symbol.addText(0, 0, QFont("San Serif", 10), label)
    f = QtGui.QFont()
    f.setPointSize(10)
    symbol.addText(0, 0, f, label)
    br = symbol.boundingRect()
    scale = min(1. / br.width(), 1. / br.height())
    tr = QtGui.QTransform()
    tr.scale(scale, scale)
    tr.rotate(angle)
    tr.translate(-br.x() - br.width()/2., -br.y() - br.height()/2.)
    return TextSymbol(label, tr.map(symbol), 0.1 / scale)

random_str = lambda : (''.join([chr(np.random.randint(ord('A'),ord('z'))) for i in range(np.random.randint(1,5))]), np.random.randint(0, 360))

s2 = pg.ScatterPlotItem(size=10, pen=pg.mkPen('w'), pxMode=True)
pos = np.random.normal(size=(2,n), scale=1e-5)
spots = [{'pos': pos[:,i], 'data': 1, 'brush':pg.intColor(i, n), 'symbol': i%10, 'size': 5+i/10.} for i in range(n)]
s2.addPoints(spots)
spots = [{'pos': pos[:,i], 'data': 1, 'brush':pg.intColor(i, n), 'symbol': label[1], 'size': label[2]*(5+i/10.)} for (i, label) in [(i, createLabel(*random_str())) for i in range(n)]]
s2.addPoints(spots)
w2.addItem(s2)
s2.sigClicked.connect(clicked)


## 3) Spots are not transform-invariant, not identical (bottom-left).
## This is the slowest case, since all spots must be completely re-drawn
## every time because their apparent transformation may have changed.

s3 = pg.ScatterPlotItem(
    pxMode=False,  # Set pxMode=False to allow spots to transform with the view
    hoverable=True,
    hoverPen=pg.mkPen('g'),
    hoverSize=1e-6
)
spots3 = []
for i in range(10):
    for j in range(10):
        spots3.append({'pos': (1e-6*i, 1e-6*j), 'size': 1e-6, 'pen': {'color': 'w', 'width': 2}, 'brush':pg.intColor(i*10+j, 100)})
s3.addPoints(spots3)
w3.addItem(s3)
s3.sigClicked.connect(clicked)

## Test performance of large scatterplots

s4 = pg.ScatterPlotItem(
    size=10,
    pen=pg.mkPen(None),
    brush=pg.mkBrush(255, 255, 255, 20),
    hoverable=True,
    hoverSymbol='s',
    hoverSize=15,
    hoverPen=pg.mkPen('r', width=2),
    hoverBrush=pg.mkBrush('g'),
)
n = 10000
pos = np.random.normal(size=(2, n), scale=1e-9)
s4.addPoints(
    x=pos[0],
    y=pos[1],
    # size=(np.random.random(n) * 20.).astype(int),
    # brush=[pg.mkBrush(x) for x in np.random.randint(0, 256, (n, 3))],
    data=np.arange(n)
)
w4.addItem(s4)
s4.sigClicked.connect(clicked)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

원래 따라오는 데모를 혼자서도 돌게 고친 내용.

 

# -*- coding: utf-8 -*-
"""
Demonstrates a variety of uses for ROI. This class provides a user-adjustable
region of interest marker. It is possible to customize the layout and 
function of the scale/rotate handles in very flexible ways. 
"""

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np

pg.setConfigOptions(imageAxisOrder='row-major')

## Create image to display
arr = np.ones((100, 100), dtype=float)
arr[45:55, 45:55] = 0
arr[25, :] = 5
arr[:, 25] = 5
arr[75, :] = 5
arr[:, 75] = 5
arr[50, :] = 10
arr[:, 50] = 10
arr += np.sin(np.linspace(0, 20, 100)).reshape(1, 100)
arr += np.random.normal(size=(100,100))

# add an arrow for asymmetry
arr[10, :50] = 10
arr[9:12, 44:48] = 10
arr[8:13, 44:46] = 10


## create GUI
QtGui.QApplication([])
w = pg.GraphicsLayoutWidget(show=True, size=(1000,800), border=True)
w.setWindowTitle('pyqtgraph example: ROI Examples')

text = """Data Selection From Image.<br>\n
Drag an ROI or its handles to update the selected image.<br>
Hold CTRL while dragging to snap to pixel boundaries<br>
and 15-degree rotation angles.
"""
w1 = w.addLayout(row=0, col=0)
label1 = w1.addLabel(text, row=0, col=0)
v1a = w1.addViewBox(row=1, col=0, lockAspect=True)
v1b = w1.addViewBox(row=2, col=0, lockAspect=True)
img1a = pg.ImageItem(arr)
v1a.addItem(img1a)
img1b = pg.ImageItem()
v1b.addItem(img1b)
v1a.disableAutoRange('xy')
v1b.disableAutoRange('xy')
v1a.autoRange()
v1b.autoRange()

rois = []
rois.append(pg.RectROI([20, 20], [20, 20], pen=(0,9)))
rois[-1].addRotateHandle([1,0], [0.5, 0.5])
rois.append(pg.LineROI([0, 60], [20, 80], width=5, pen=(1,9)))
#rois.append(pg.TriangleROI([80, 75], 20, pen=(5, 9)))
rois.append(pg.MultiRectROI([[20, 90], [50, 60], [60, 90]], width=5, pen=(2,9)))
rois.append(pg.EllipseROI([60, 10], [30, 20], pen=(3,9)))
rois.append(pg.CircleROI([80, 50], [20, 20], pen=(4,9)))
#rois.append(pg.LineSegmentROI([[110, 50], [20, 20]], pen=(5,9)))
rois.append(pg.PolyLineROI([[80, 60], [90, 30], [60, 40]], pen=(6,9), closed=True))

def update(roi):
    img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max()))
    v1b.autoRange()
    
for roi in rois:
    roi.sigRegionChanged.connect(update)
    v1a.addItem(roi)

update(rois[-1])
    


text = """User-Modifiable ROIs<br>
Click on a line segment to add a new handle.
Right click on a handle to remove.
"""
w2 = w.addLayout(row=0, col=1)
label2 = w2.addLabel(text, row=0, col=0)
v2a = w2.addViewBox(row=1, col=0, lockAspect=True)
r2a = pg.PolyLineROI([[0,0], [10,10], [10,30], [30,10]], closed=True)
v2a.addItem(r2a)
r2b = pg.PolyLineROI([[0,-20], [10,-10], [10,-30]], closed=False)
v2a.addItem(r2b)
v2a.disableAutoRange('xy')
#v2b.disableAutoRange('xy')
v2a.autoRange()
#v2b.autoRange()

text = """Building custom ROI types<Br>
ROIs can be built with a variety of different handle types<br>
that scale and rotate the roi around an arbitrary center location
"""
w3 = w.addLayout(row=1, col=0)
label3 = w3.addLabel(text, row=0, col=0)
v3 = w3.addViewBox(row=1, col=0, lockAspect=True)

r3a = pg.ROI([0,0], [10,10])
v3.addItem(r3a)
## handles scaling horizontally around center
r3a.addScaleHandle([1, 0.5], [0.5, 0.5])
r3a.addScaleHandle([0, 0.5], [0.5, 0.5])

## handles scaling vertically from opposite edge
r3a.addScaleHandle([0.5, 0], [0.5, 1])
r3a.addScaleHandle([0.5, 1], [0.5, 0])

## handles scaling both vertically and horizontally
r3a.addScaleHandle([1, 1], [0, 0])
r3a.addScaleHandle([0, 0], [1, 1])

r3b = pg.ROI([20,0], [10,10])
v3.addItem(r3b)
## handles rotating around center
r3b.addRotateHandle([1, 1], [0.5, 0.5])
r3b.addRotateHandle([0, 0], [0.5, 0.5])

## handles rotating around opposite corner
r3b.addRotateHandle([1, 0], [0, 1])
r3b.addRotateHandle([0, 1], [1, 0])

## handles rotating/scaling around center
r3b.addScaleRotateHandle([0, 0.5], [0.5, 0.5])

# handles rotating/scaling around arbitrary point
#r3b.addScaleRotateHandle([0.3, 0], [0.9, 0.7])

v3.disableAutoRange('xy')
v3.autoRange()


text = """Transforming objects with ROI"""
w4 = w.addLayout(row=1, col=1)
label4 = w4.addLabel(text, row=0, col=0)
v4 = w4.addViewBox(row=1, col=0, lockAspect=True)
g = pg.GridItem()
v4.addItem(g)
r4 = pg.ROI([0,0], [100,100], resizable=False, removable=True)
r4.addRotateHandle([1,0], [0.5, 0.5])
r4.addRotateHandle([0,1], [0.5, 0.5])
img4 = pg.ImageItem(arr)
v4.addItem(r4)
img4.setParentItem(r4)

v4.disableAutoRange('xy')
v4.autoRange()

# Provide a callback to remove the ROI (and its children) when
# "remove" is selected from the context menu.
def remove():
    v4.removeItem(r4)
r4.sigRemoveRequested.connect(remove)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

SetRange, Items, AutoRange : To keep only latest certain number of data on graph.   

출처 : ????

 

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg

QtGui.QApplication([])

win = pg.GraphicsLayoutWidget(show=True, title="Plot auto-range examples")
win.resize(800,600)
win.setWindowTitle('pyqtgraph example: PlotAutoRange')

d = np.random.normal(size=100)
d[50:54] += 10
p1 = win.addPlot(title="95th percentile range", y=d)
p1.enableAutoRange('y', 0.95)


p2 = win.addPlot(title="Auto Pan Only")
p2.setAutoPan(y=True)
curve = p2.plot()
def update():
    t = pg.time()
    
    data = np.ones(100) * np.sin(t)
    data[50:60] += np.sin(t)
    global curve
    curve.setData(data)
    
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

 

 

# 출처: https://mc10sw.tistory.com/10 [Make it possible]

# -*- coding: utf-8 -*-
"""
This example demonstrates many of the 2D plotting capabilities
in pyqtgraph. All of the plots may be panned/scaled by dragging with
the left/right mouse buttons. Right click on any plot to show a context menu.
"""
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg



#QtGui.QApplication.setGraphicsSystem('raster')
app = QtGui.QApplication([])

#mw = QtGui.QMainWindow()
#mw.resize(800,800)



win = pg.GraphicsWindow(title="Basic plotting examples")    # PyQtGraph grahical window
win.resize(1000,600)
win.setWindowTitle('pyqtgraph example: Plotting')           # Title of python window



# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)


# Basic Array Plotting
p1 = win.addPlot(title="Basic array plotting", y=np.random.normal(size=100))


# Multiple Curves
p2 = win.addPlot(title="Multiple curves")
p2.plot(np.random.normal(size=100), pen=(255,0,0), name="Red curve")
p2.plot(np.random.normal(size=110)+5, pen=(0,255,0), name="Green curve")
p2.plot(np.random.normal(size=120)+10, pen=(0,0,255), name="Blue curve")


# Drawing with Points
p3 = win.addPlot(title="Drawing with points")
p3.plot(np.random.normal(size=100), pen=(200,200,200), symbolBrush=(255,0,0), symbolPen='w')


# Next Row
win.nextRow()


# Parametric, Grid Enabled
p4 = win.addPlot(title="Parametric, grid enabled")
x = np.cos(np.linspace(0, 2*np.pi, 1000))
y = np.sin(np.linspace(0, 4*np.pi, 1000))
p4.plot(x, y)
p4.showGrid(x=True, y=True)


# Scatter Plot, Axis Labels, Log Scale
p5 = win.addPlot(title="Scatter plot, axis labels, log scale")
x = np.random.normal(size=1000) * 1e-5
y = x*1000 + 0.005 * np.random.normal(size=1000)
y -= y.min()-1.0
mask = x > 1e-15
x = x[mask]
y = y[mask]
p5.plot(x, y, pen=None, symbol='t', symbolPen=None, symbolSize=10, symbolBrush=(100, 100, 255, 50))
p5.setLabel('left', "Y Axis", units='A')
p5.setLabel('bottom', "Y Axis", units='s')
p5.setLogMode(x=True, y=False)


# Updating Plot
p6 = win.addPlot(title="Updating plot")
curve = p6.plot(pen='y')
data = np.random.normal(size=(10,1000))
ptr = 0
def update():
    global curve, data, ptr, p6
    curve.setData(data[ptr%10])
    if ptr == 0:
        p6.enableAutoRange('xy', False)  ## stop auto-scaling after the first data set is plotted
    ptr += 1
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)


# Next Row
win.nextRow()


# Filled Plot, Axis Disabled
p7 = win.addPlot(title="Filled plot, axis disabled")
y = np.sin(np.linspace(0, 10, 1000)) + np.random.normal(size=1000, scale=0.1)
p7.plot(y, fillLevel=-0.3, brush=(50,50,200,100))
p7.showAxis('bottom', False)


# Region Selection
x2 = np.linspace(-100, 100, 1000)
data2 = np.sin(x2) / x2
p8 = win.addPlot(title="Region Selection")
p8.plot(data2, pen=(255,255,255,200))
lr = pg.LinearRegionItem([400,700])
lr.setZValue(-10)
p8.addItem(lr)


# Zoom on Selected Region
p9 = win.addPlot(title="Zoom on selected region")
p9.plot(data2)
def updatePlot():
    p9.setXRange(*lr.getRegion(), padding=0)
def updateRegion():
    lr.setRegion(p9.getViewBox().viewRange()[0])
lr.sigRegionChanged.connect(updatePlot)
p9.sigXRangeChanged.connect(updateRegion)
updatePlot()


## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

 

** AxisItem class 를 subclass 하여, 원하는 axis 만들수 있다. 

    --> 특히, tickStrings( ) 메소드를 override 하여, tick 에 원하는 양식으로 출력 변경가능하다.

 

 

** 최근 시간만 보여주기

  --> setData( ) 로 실시간 chart 그리기전에, setXRange( ) 이용하여, 최근 시간만 설정하면 ok!!!

# https://freeprog.tistory.com/373?category=716617

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import *

import pyqtgraph as pg

import time


class TimeAxisItem(pg.AxisItem):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setLabel(text='Time(초)', units=None)
        self.enableAutoSIPrefix(False)

    def tickStrings(self, values, scale, spacing):
        """ override 하여, tick 옆에 써지는 문자를 원하는대로 수정함.
            values --> x축 값들   ; 숫자로 이루어진 Itarable data --> ex) List[int]
        """
        # print("--tickStrings valuse ==>", values)
        return [time.strftime("%H:%M:%S", time.localtime(local_time)) for local_time in values]


class ExampleWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.pw = pg.PlotWidget(
            title="Example plot",
            labels={'left': 'y 축'},
            axisItems={'bottom': TimeAxisItem(orientation='bottom')}
        )

        hbox = QHBoxLayout()
        hbox.addWidget(self.pw)
        self.setLayout(hbox)

        self.pw.setYRange(0, 70, padding=0)

        time_data = int(time.time())
        self.pw.setXRange(time_data - 10, time_data + 1)  # 생략 가능.

        self.pw.showGrid(x=True, y=True)
        # self.pw.enableAutoRange()

        self.pdi = self.pw.plot(pen='y')   # PlotDataItem obj 반환.

        self.plotData = {'x': [], 'y': []}

    def update_plot(self, new_time_data: int):
        data_sec = time.strftime("%S", time.localtime(new_time_data))
        self.plotData['y'].append(int(data_sec))
        self.plotData['x'].append(new_time_data)

        self.pw.setXRange(new_time_data - 10, new_time_data + 1, padding=0)   # 항상 x축 시간을 최근 범위만 보여줌.

        self.pdi.setData(self.plotData['x'], self.plotData['y'])


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)

    ex = ExampleWidget()

    def get_data():
        new_time_data = int(time.time())
        ex.update_plot(new_time_data)

    mytimer = QTimer()
    mytimer.start(1000)  # 1초마다 갱신 위함...
    mytimer.timeout.connect(get_data)

    ex.show()
    sys.exit(app.exec_())

 

 

** PlotItem.enableAutoScale() 사용하면, 항상 전체 그래프 영역 모두 보여줌.

 

   -- PlotItem.enableAutoScale() 는 나중에 사라지므로, 대신에 PlotItem.enableAutoRange( ) 사용 권장함. 

 

 

** setXRange( ), setYRange( ) 로 차트의 x축, y축 가시영역을 지정해도...

   enableAutoRange( ) 사용하면, 자동으로 가시영역 변경된다..

 

 

 

** 대부분의 차트는 realtime update 시에 setData( ) 를 사용하면, 자동으로 이전차트 지우고, 새로운 data로 차트를 그린다.

    --> but, BarGraphItem 차트는 clear( ) 를 사용해서, 이전 차트 item 지우고, 새로 그려야함.

# https://freeprog.tistory.com/372?category=716617

import pyqtgraph as pg

from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject, Qt, QThread, QTimer

import time, random


class ExMain(QWidget):
    def __init__(self):
        super().__init__()

        hbox = QHBoxLayout()
        self.pw1 = pg.PlotWidget(title="line chart")
        self.pw2 = pg.PlotWidget(title="이전 차트 제거 안됨")
        self.pw3 = pg.PlotWidget(title="clear 로 이전 차트 제거함")

        hbox.addWidget(self.pw1)
        hbox.addWidget(self.pw2)
        hbox.addWidget(self.pw3)
        self.setLayout(hbox)

        # self.setGeometry(300, 100, 800, 500)  # x, y, width, height
        self.setWindowTitle("pyqtgraph 예제 - realtime")

        self.x = [1, 2, 3]
        self.y = [4, 5, 6]
        # self.pw1.setXRange(1, 10)
        # self.pw1.setYRange(1, 10)
        # self.pw1.enableAutoScale()
        # self.pw1.enableAutoRange()  # x,y축 모두 autorange..
        # self.pw1.enableAutoRange(axis='x', enable=True)
        # self.pw1.enableAutoRange(axis='x')
        # self.pw1.enableAutoRange(axis='y')
        # self.pw1.enableAutoRange(axis='xy')

        # self.pw2.enableAutoRange()
        self.pl = self.pw1.plot(pen='g')

        self.mytimer = QTimer()
        self.mytimer.start(1000)  # 1초마다 차트 갱신 위함...
        self.mytimer.timeout.connect(self.get_data)

        self.draw_chart(self.x, self.y)
        self.show()

    def draw_chart(self, x, y):
        self.pl.setData(x=x, y=y)  # line chart 그리기

        cnt = len(y)
        new_y = []
        for i in range(cnt):
            new_y.append(random.random()*60)  # 0 이상 ~ 60 미만 random 숫자 만들기

        """ 이전에 그린 차트 잔상 남아있다 """
        bar_chart = pg.BarGraphItem(x=x, height=new_y, width=1, brush='y', pen='r', title="잔상남음")
        self.pw2.addItem(bar_chart)

        """ clear() 로 이전에 그린 차트 제거함. """
        self.pw3.clear()  # remove all items --> 이전 그래프 제거함.
        bar_chart2 = pg.BarGraphItem(x=x, height=new_y, width=1, brush='y', pen='r')
        self.pw3.addItem(bar_chart2)

    @pyqtSlot()
    def get_data(self):
        # print(time.localtime())
        # print(time.strftime("%H%M%S", time.localtime()))
        data: str = time.strftime("%S", time.localtime())  # 초 단위만 구함.

        last_x = self.x[-1]
        self.x.append(last_x + 1)

        self.y.append(int(data))
        self.draw_chart(self.x, self.y)


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)

    ex = ExMain()

    sys.exit(app.exec_())

** bar char 그리기

    -- BarGraphItem( ) 사용하면됨.

       --> pyqtgraph 문서에는 설명 안나옴.  소스 주석에 사용법 있음.

 

 

 ** x축, y축 과  (0, 0) 사이 여백 제거하기

 

    setXRange(0, 22, padding=0)   # padding=0  --> 공백 제거함.

 



출처: https://freeprog.tistory.com/368?category=716617 [취미로 하는 프로그래밍 !!!]

 

 

#https://freeprog.tistory.com/368?category=716617

import pyqtgraph as pg
import numpy as np
from PyQt5.QtWidgets import *


class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        pg.setConfigOptions(background='w', foreground='b')  # 배경 흰색으로.. ; global configuration options

        x = np.arange(20)
        y = np.linspace(0, 20, num=20)

        pw = pg.PlotWidget()
        pw.showGrid(x=True, y=True)

        pw.setXRange(0, 22, padding=0)   # padding=0  --> y축 공백 제거함.
        # pw.setYRange(0, 22, padding=0)   # padding=0  --> x축 공백 제거함.

        barchar = pg.BarGraphItem(x=x, height=y, width=0.6, brush='r')  # width = 막대 넓이
        # bar_chart = pg.BarGraphItem(x=x, width=0.9, height=y,  brush='r', pen='g')  
        pw.addItem(barchar)

        layout = QHBoxLayout()
        layout.addWidget(pw)
        self.setLayout(layout)

        self.setGeometry(300, 100, 550, 500)  # x, y, width, height
        self.setWindowTitle("pyqtgraph 예제 - bar chart")
        self.show()


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    ex = MyWidget()
    sys.exit(app.exec_())

** pyqtgraph.plot( ) 

   --> 소스코드 보면, PlotWindow 객체 생성하여, plot( ) 실행함.

   --> PlotWindow ; graphicsWindows.py 내부에 정의됨.

          --> 소스코드보면, 내부적으로 QMainWindow 에 PlotWidget 을 사용하여 만들었다.

 

  ==> 결론적으로,  pyqtgraph.plot( ) 은 내부적으로 PlotWidget.plot( ) 을 실행하고,

                      GUI window는 pyqt의 QMainWindow 사용함.

 

 

 

 

** pyqt5 내에 pyqtgraph를 통합할때.  PlotWidget() 을 사용하자.

      -- PlotWidget() 은 내부적으로 GraphicWidget 을 상속받고, PlotItem() 의 메소드를 사용한다. 

 

      -- 즉,  PlotWidget() 초기화시에, parent 와 background 매개변수는 GraphicWidget 에서 사욯하고, 

             나머지 매개변수는 PlotItem() 으로 넘겨 사용됨. 

 

 

 

 

** pyqtgraph 에서 global configuration options 사용 예.   http://www.pyqtgraph.org/documentation/config_options.html

 

        ex1)  pg.setConfigOption('background', 'y')  # global configuration options

 

        ex2)  pg.setConfigOptions(background='w', foreground='b')  # key-value 형태로 여러개 인자 사용 가능. 

 

 

 

** numpy 를 사용하지 않아도, 간단한 그래프를 그릴수 있다.

 

 

 

** plot( ) 에 관하여...

    -- PlotWidget.plot( ) 사용시...

        --> 내부적으로 PlotItem.plot( ) 메소드를 사용함.

        ---> PlotItem.plot( ) 는 PlotDataItem 객체를 반환한다.

 

     ; plot( data ) 에서 사용하는 data 값은 list 혹은 numpy array 를 사용한다.

 

 

 

 

** 실제 차트 그리는 명령어는 아래 2가지 중 하나 사용하면됨.

 

pw.plot(x, y, pen='r') 

 

또는 

 

pdi = pw.plot()  # PlotDataItem obj 반환

pdi.setData(x, y, pen='g')

 

  ---> plot( ) 으로 차트그릴때, 내부적으로 setData( ) 를 사용하므로, 그냥 setData( ) 사용하는 습관이 좋을듯..... 

 

 



출처: https://freeprog.tistory.com/366?category=716617 [취미로 하는 프로그래밍 !!!]

 

 

 

# https://freeprog.tistory.com/366?category=716617

import pyqtgraph as pg
# import pyqtgraph.exporters
# import numpy as np

from PyQt5.QtWidgets import *


class MyMainWindow(QMainWindow):
    """
    QMainWindow 의 central widget 으로 pyqtgraph의 PlotWidget() 사용함.
    """
    def __init__(self):
        super().__init__()
        # pg.setConfigOption('background', 'y')  # global configuration options
        # pg.setConfigOptions(background='w')  # global configuration options
        # pg.setConfigOptions(background='w', foreground='b')  # key-value 형태로 여러개 인자 사용 가능.

        y = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
        x = range(0, 10)

        # pw = pg.PlotWidget(background='w', title="aaaa")
        pw = pg.PlotWidget(title="기본예제")  # title 매개변수는 내부적으로 PlotItem() 에서 사용됨.
        # pw = pg.PlotWidget()

        """
        ** 실제 차트 그리는 명령어는 아래 2가지 중 하나 사용하면됨.
        
        pw.plot(x, y, pen='r') 
        
        또는 
        
        pdi = pw.plot()  # PlotDataItem obj 반환
        pdi.setData(x, y, pen='g')
        """
        # pw.plot(x, y)
        # pw.plot(x, y, pen='r')  # plot() 메소드는 내부적으로 PlotItem 의 plot() 을 사용함.
        
        pdi = pw.plot()  # PlotDataItem obj 반환
        pdi.setData(x, y, pen='g')

        self.setCentralWidget(pw)  # pyqt5 와 pyqtgraph 연결.

        # self.setGeometry(300, 700, 350, 500)
        self.show()


if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)

    mywin = MyMainWindow()

    sys.exit(app.exec_())

+ Recent posts