Python | PyQtGraph 公式サンプルを実行する方法

PyQtGraph

GraphicsItems

Scatter Plot

"""
Example demonstrating a variety of scatter plot features.
"""

from collections import namedtuple

import numpy as np

import pyqtgraph as pg
from pyqtgraph.Qt import QtGui, QtWidgets

app = pg.mkQApp("Scatter Plot Item Example") 
mw = QtWidgets.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__':
    pg.exec()

InfiniteLine

"""
This example demonstrates some of the plotting items available in pyqtgraph.
"""

import numpy as np

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore

app = pg.mkQApp("InfiniteLine Example")
win = pg.GraphicsLayoutWidget(show=True, title="Plotting items examples")
win.resize(1000,600)

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

# Create a plot with some random data
p1 = win.addPlot(title="Plot Items example", y=np.random.normal(size=100, scale=10), pen=0.5)
p1.setYRange(-40, 40)

# Add three infinite lines with labels
inf1 = pg.InfiniteLine(movable=True, angle=90, label='x={value:0.2f}', 
                       labelOpts={'position':0.1, 'color': (200,200,100), 'fill': (200,200,200,50), 'movable': True})
inf2 = pg.InfiniteLine(movable=True, angle=0, pen=(0, 0, 200), bounds = [-20, 20], hoverPen=(0,200,0), label='y={value:0.2f}mm', 
                       labelOpts={'color': (200,0,0), 'movable': True, 'fill': (0, 0, 200, 100)})
inf3 = pg.InfiniteLine(movable=True, angle=45, pen='g', label='diagonal',
                       labelOpts={'rotateAxis': [1, 0], 'fill': (0, 200, 0, 100), 'movable': True})
inf1.setPos([2,2])
p1.addItem(inf1)
p1.addItem(inf2)
p1.addItem(inf3)

targetItem1 = pg.TargetItem()

targetItem2 = pg.TargetItem(
    pos=(30, 5),
    size=20,
    symbol="star",
    pen="#F4511E",
    label="vert={1:0.2f}",
    labelOpts={
        "offset": QtCore.QPoint(15, 15)
    }
)
targetItem2.label().setAngle(45)

targetItem3 = pg.TargetItem(
    pos=(10, 10),
    size=10,
    symbol="x",
    pen="#00ACC1",
)
targetItem3.setLabel(
    "Third Label",
    {
        "anchor": QtCore.QPointF(0.5, 0.5),
        "offset": QtCore.QPointF(30, 0),
        "color": "#558B2F",
        "rotateAxis": (0, 1)
    }
)


def callableFunction(x, y):
    return f"Square Values: ({x**2:.4f}, {y**2:.4f})"

targetItem4 = pg.TargetItem(
    pos=(10, -10),
    label=callableFunction
)

p1.addItem(targetItem1)
p1.addItem(targetItem2)
p1.addItem(targetItem3)
p1.addItem(targetItem4)

# Add a linear region with a label
lr = pg.LinearRegionItem(values=[70, 80])
p1.addItem(lr)
label = pg.InfLineLabel(lr.lines[1], "region 1", position=0.95, rotateAxis=(1,0), anchor=(1, 1))

if __name__ == '__main__':
    pg.exec()

IsocurveItem

"""
Tests use of IsoCurve item displayed with image
"""

import numpy as np

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore

app = pg.mkQApp("Isocurve Example")

## make pretty looping data
frames = 200
data = np.random.normal(size=(frames,30,30), loc=0, scale=100)
data = np.concatenate([data, data], axis=0)
data = pg.gaussianFilter(data, (10, 10, 10))[frames//2:frames + frames//2]
data[:, 15:16, 15:17] += 1

win = pg.GraphicsLayoutWidget(show=True)
win.setWindowTitle('pyqtgraph example: Isocurve')
vb = win.addViewBox()
img = pg.ImageItem(data[0])
vb.addItem(img)
vb.setAspectLocked()

## generate empty curves
curves = []
levels = np.linspace(data.min(), data.max(), 10)
for i in range(len(levels)):
    v = levels[i]
    ## generate isocurve with automatic color selection
    c = pg.IsocurveItem(level=v, pen=(i, len(levels)*1.5))
    c.setParentItem(img)  ## make sure isocurve is always correctly displayed over image
    c.setZValue(10)
    curves.append(c)

## animate!
ptr = 0
imgLevels = (data.min(), data.max() * 2)
def update():
    global data, curves, img, ptr, imgLevels
    ptr = (ptr + 1) % data.shape[0]
    data[ptr]
    img.setImage(data[ptr], levels=imgLevels)
    for c in curves:
        c.setData(data[ptr])

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)
    
if __name__ == '__main__':
    pg.exec()

GraphItem

"""
Simple example of GraphItem use.
"""

import numpy as np

import pyqtgraph as pg

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

w = pg.GraphicsLayoutWidget(show=True)
w.setWindowTitle('pyqtgraph example: GraphItem')
v = w.addViewBox()
v.setAspectLocked()

g = pg.GraphItem()
v.addItem(g)

## Define positions of nodes
pos = np.array([
    [0,0],
    [10,0],
    [0,10],
    [10,10],
    [5,5],
    [15,5]
    ])
    
## Define the set of connections in the graph
adj = np.array([
    [0,1],
    [1,3],
    [3,2],
    [2,0],
    [1,5],
    [3,5],
    ])
    
## Define the symbol to use for each node (this is optional)
symbols = ['o','o','o','o','t','+']

## Define the line style for each connection (this is optional)
lines = np.array([
    (255,0,0,255,1),
    (255,0,255,255,2),
    (255,0,255,255,3),
    (255,255,0,255,2),
    (255,0,0,255,1),
    (255,255,255,255,4),
    ], dtype=[('red',np.ubyte),('green',np.ubyte),('blue',np.ubyte),('alpha',np.ubyte),('width',float)])

## Update the graph
g.setData(pos=pos, adj=adj, pen=lines, size=1, symbol=symbols, pxMode=False)

if __name__ == '__main__':
    pg.exec()

ErrorBarItem

"""
Demonstrates basic use of ErrorBarItem
"""

import numpy as np

import pyqtgraph as pg

pg.setConfigOptions(antialias=True)

x = np.arange(10)
y = np.arange(10) %3
top = np.linspace(1.0, 3.0, 10)
bottom = np.linspace(2, 0.5, 10)

plt = pg.plot()
plt.setWindowTitle('pyqtgraph example: ErrorBarItem')
err = pg.ErrorBarItem(x=x, y=y, top=top, bottom=bottom, beam=0.5)
plt.addItem(err)
plt.plot(x, y, symbol='o', pen={'color': 0.8, 'width': 2})

if __name__ == '__main__':
    pg.exec()

FillBetweenItem

"""
Demonstrates use of FillBetweenItem to fill the space between two plot curves.
"""

import numpy as np

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore

#FIXME: When running on Qt5, not as perfect as on Qt4

win = pg.plot()
win.setWindowTitle('pyqtgraph example: FillBetweenItem')
win.setXRange(-10, 10)
win.setYRange(-10, 10)

N = 200
x = np.linspace(-10, 10, N)
gauss = np.exp(-x**2 / 20.)
mn = mx = np.zeros(len(x))
curves = [win.plot(x=x, y=np.zeros(len(x)), pen='k') for i in range(4)]
brushes = [0.5, (100, 100, 255), 0.5]
fills = [pg.FillBetweenItem(curves[i], curves[i+1], brushes[i]) for i in range(3)]
for f in fills:
    win.addItem(f)

def update():
    global mx, mn, curves, gauss, x
    a = 5 / abs(np.random.normal(loc=1, scale=0.2))
    y1 = -np.abs(a*gauss + np.random.normal(size=len(x)))
    y2 =  np.abs(a*gauss + np.random.normal(size=len(x)))
    
    s = 0.01
    mn = np.where(y1<mn, y1, mn) * (1-s) + y1 * s
    mx = np.where(y2>mx, y2, mx) * (1-s) + y2 * s
    curves[0].setData(x, mn)
    curves[1].setData(x, y1)
    curves[2].setData(x, y2)
    curves[3].setData(x, mx)
    

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(30)


if __name__ == '__main__':
    pg.exec()

ImageItem – video

"""
Demonstrates very basic use of ImageItem to display image data inside a ViewBox.
"""

from time import perf_counter

import numpy as np

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore

app = pg.mkQApp("ImageItem Example")

## Create window with GraphicsView widget
win = pg.GraphicsLayoutWidget()
win.show()  ## show widget alone in its own window
win.setWindowTitle('pyqtgraph example: ImageItem')
view = win.addViewBox()

## lock the aspect ratio so pixels are always square
view.setAspectLocked(True)

## Create image item
img = pg.ImageItem(border='w')
view.addItem(img)

## Set initial view bounds
view.setRange(QtCore.QRectF(0, 0, 600, 600))

## Create random image
data = np.random.normal(size=(15, 600, 600), loc=1024, scale=64).astype(np.uint16)
i = 0

updateTime = perf_counter()
elapsed = 0

timer = QtCore.QTimer()
timer.setSingleShot(True)
# not using QTimer.singleShot() because of persistence on PyQt. see PR #1605

def updateData():
    global img, data, i, updateTime, elapsed

    ## Display the data
    img.setImage(data[i])
    i = (i+1) % data.shape[0]

    timer.start(1)
    now = perf_counter()
    elapsed_now = now - updateTime
    updateTime = now
    elapsed = elapsed * 0.9 + elapsed_now * 0.1

    # print(f"{1 / elapsed:.1f} fps")
    
timer.timeout.connect(updateData)
updateData()

if __name__ == '__main__':
    pg.exec()

ImageItem – draw

"""
Demonstrate ability of ImageItem to be used as a canvas for painting with
the mouse.
"""

import numpy as np

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore

app = pg.mkQApp("Draw Example")

## Create window with GraphicsView widget
w = pg.GraphicsView()
w.show()
w.resize(800,800)
w.setWindowTitle('pyqtgraph example: Draw')

view = pg.ViewBox()
w.setCentralItem(view)

## lock the aspect ratio
view.setAspectLocked(True)

## Create image item
img = pg.ImageItem(np.zeros((200,200)))
view.addItem(img)

## Set initial view bounds
view.setRange(QtCore.QRectF(0, 0, 200, 200))

## start drawing with 3x3 brush
kern = np.array([
    [0.0, 0.5, 0.0],
    [0.5, 1.0, 0.5],
    [0.0, 0.5, 0.0]
])
img.setDrawKernel(kern, mask=kern, center=(1,1), mode='add')
img.setLevels([0, 10])

if __name__ == '__main__':
    pg.exec()

ColorBarItem

"""
This example demonstrates the use of ColorBarItem, which displays a simple interactive color bar.
"""

import numpy as np

import pyqtgraph as pg
from pyqtgraph.Qt import QtWidgets, mkQApp


class MainWindow(QtWidgets.QMainWindow):
    """ example application main window """
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        gr_wid = pg.GraphicsLayoutWidget(show=True)
        self.setCentralWidget(gr_wid)
        self.setWindowTitle('pyqtgraph example: Interactive color bar')
        self.resize(800,700)
        self.show()

        ## Create image items
        data = np.fromfunction(lambda i, j: (1+0.3*np.sin(i)) * (i)**2 + (j)**2, (100, 100))
        noisy_data = data * (1 + 0.2 * np.random.random(data.shape) )
        noisy_transposed = noisy_data.transpose()

        #--- add non-interactive image with integrated color ------------------
        p1 = gr_wid.addPlot(title="non-interactive")
        # Basic steps to create a false color image with color bar:
        i1 = pg.ImageItem(image=data)
        p1.addItem( i1 )
        p1.addColorBar( i1, colorMap='CET-L9', values=(0, 30_000)) # , interactive=False)
        #
        p1.setMouseEnabled( x=False, y=False)
        p1.disableAutoRange()
        p1.hideButtons()
        p1.setRange(xRange=(0,100), yRange=(0,100), padding=0)
        p1.showAxes(True, showValues=(True,False,False,True) )

        #--- add interactive image with integrated horizontal color bar -------
        i2 = pg.ImageItem(image=noisy_data)
        p2 = gr_wid.addPlot(1,0, 1,1, title="interactive")
        p2.addItem( i2, title='' )
        # inserted color bar also works with labels on the right.
        p2.showAxis('right')
        p2.getAxis('left').setStyle( showValues=False )
        p2.getAxis('bottom').setLabel('bottom axis label')
        p2.getAxis('right').setLabel('right axis label')

        bar = pg.ColorBarItem(
            values = (0, 30_000),
            colorMap='CET-L4',
            label='horizontal color bar',
            limits = (0, None),
            rounding=1000,
            orientation = 'h',
            pen='#8888FF', hoverPen='#EEEEFF', hoverBrush='#EEEEFF80'
        )
        bar.setImageItem( i2, insert_in=p2 )

        #--- multiple images adjusted by a separate color bar ------------------------
        i3 = pg.ImageItem(image=noisy_data)
        p3 = gr_wid.addPlot(0,1, 1,1, title="shared 1")
        p3.addItem( i3 )

        i4 = pg.ImageItem(image=noisy_transposed)
        p4 = gr_wid.addPlot(1,1, 1,1, title="shared 2")
        p4.addItem( i4 )

        cmap = pg.colormap.get('CET-L8')
        bar = pg.ColorBarItem(
            # values = (-15_000, 15_000),
            limits = (-30_000, 30_000), # start with full range...
            rounding=1000,
            width = 10,
            colorMap=cmap )
        bar.setImageItem( [i3, i4] )
        bar.setLevels( low=-5_000, high=15_000) # ... then adjust to retro sunset.

        # manually adjust reserved space at top and bottom to align with plot
        bar.getAxis('bottom').setHeight(21)
        bar.getAxis('top').setHeight(31)
        gr_wid.addItem(bar, 0,2, 2,1) # large bar spanning both rows

mkQApp("ColorBarItem Example")
main_window = MainWindow()

## Start Qt event loop
if __name__ == '__main__':
    pg.exec()

Non-uniform Image

"""
Display a non-uniform image.
This example displays 2-d data as an image with non-uniformly
distributed sample points.
"""

import numpy as np

import pyqtgraph as pg
from pyqtgraph.graphicsItems.GradientEditorItem import Gradients
from pyqtgraph.graphicsItems.NonUniformImage import NonUniformImage
from pyqtgraph.Qt import QtWidgets

RPM2RADS = 2 * np.pi / 60
RADS2RPM = 1 / RPM2RADS

kfric  = 1       # [Ws/rad] angular damping coefficient [0;100]
kfric3 = 1.5e-6  # [Ws3/rad3] angular damping coefficient (3rd order) [0;10-3]
psi    = 0.2     # [Vs] flux linkage [0.001;10]
res    = 5e-3    # [Ohm] resistance [0;100]
v_ref  = 200     # [V] reference DC voltage [0;1000]
k_v    = 5       # linear voltage coefficient [-100;100]

# create the (non-uniform) scales
tau = np.array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 220], dtype=np.float32)
w = np.array([0, 250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000], dtype=np.float32) * RPM2RADS
v = 380

# calculate the power losses
TAU, W = np.meshgrid(tau, w, indexing='ij')
V = np.ones_like(TAU) * v

P_loss = kfric * W + kfric3 * W ** 3 + (res * (TAU / psi) ** 2) + k_v * (V - v_ref)

P_mech = TAU * W
P_loss[P_mech > 1.5e5] = np.NaN

# green - orange - red
Gradients['gor'] = {'ticks': [(0.0, (74, 158, 71)), (0.5, (255, 230, 0)), (1, (191, 79, 76))], 'mode': 'rgb'}

app = pg.mkQApp("NonUniform Image Example")

win = QtWidgets.QMainWindow()
cw = pg.GraphicsLayoutWidget()
win.show()
win.resize(600, 400)
win.setCentralWidget(cw)
win.setWindowTitle('pyqtgraph example: Non-uniform Image')

p = cw.addPlot(title="Power Losses [W]", row=0, col=0)

lut = pg.HistogramLUTItem(orientation="horizontal")

p.setMouseEnabled(x=False, y=False)

cw.nextRow()
cw.addItem(lut)

# load the gradient
lut.gradient.loadPreset('gor')

image = NonUniformImage(w * RADS2RPM, tau, P_loss.T)
image.setLookupTable(lut, autoLevel=True)
image.setZValue(-1)
p.addItem(image)

h = image.getHistogram()
lut.plot.setData(*h)

p.showGrid(x=True, y=True)

p.setLabel(axis='bottom', text='Speed [rpm]')
p.setLabel(axis='left', text='Torque [Nm]')

# elevate the grid lines
p.axes['bottom']['item'].setZValue(1000)
p.axes['left']['item'].setZValue(1000)

if __name__ == '__main__':
    pg.exec()

コメント