"""
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()
コメント