2012-03-02 02:55:32 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2013-02-25 04:09:03 +00:00
|
|
|
"""
|
|
|
|
Example demonstrating a variety of scatter plot features.
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-03-02 02:55:32 +00:00
|
|
|
## Add path to library (just for examples; you do not need this)
|
2013-01-12 01:21:11 +00:00
|
|
|
import initExample
|
2012-03-02 02:55:32 +00:00
|
|
|
|
2012-03-02 03:53:52 +00:00
|
|
|
from pyqtgraph.Qt import QtGui, QtCore
|
2012-03-02 02:55:32 +00:00
|
|
|
import pyqtgraph as pg
|
|
|
|
import numpy as np
|
2018-01-28 23:14:48 +00:00
|
|
|
from collections import namedtuple
|
Scatter Plot Improvements (#1420)
* Added hovering demo to ScatterPlot example
* Use Qt's serialization for SymbolAtlas.symbolMap keys
Yields significant performance improvements when updating the scatter plot's options. See e.g. the plot hover example.
* Further optimized scatter plot picking
* Fix ScatterPlot example tool tip
* Clean up while I'm here
* Compatibility
* Some simple optimizations for ScatterPlotItem
Speedups for ScatterPlotSpeedTest.py:
~50% without pxMode
~ 0% pxMode with useCache
~30% pxMode without useCache
* ~3x speedup in scatter plot speed test with pxMode
* More optimization low-hanging fruit for the scatter plot
* Removed hover example to lazily pass tests
* Avoid segfault
* Re-add hover example to ScatterPlot.py
* Switch to id-based keying for scatter plot symbol atlas
- Use cases exist where serialization-based keying is a significant bottleneck, e.g. updating without atlas invalidation when a large variety pens or brushes are present.
- To avoid a performance hit, the onus is on the user to carefully reuse pen and brush objects.
* Optimized caching in scatter plot hovering example
* Fixed and optimized scatter plot hovering example
* Minor scatter plot optimization
* Cleanup
* Store hovered points in a set for the hovering example
* Keep a limited number symbol atlas entries around for future reuse
* Added a docstring note to remind the user to reuse QPen and QBrush objects for better performance
* Tidied up hovering example
* Typo
* Avoid unnecessary atlas rebuilds
* Refactored SymbolAtlas
* Efficient appending to SymbolAtlas
* SymbolAtlas rewrite
* Cleanup and profiling
* Add randomized brushes to speed test
* Add loc indexer to ScatterPlotItem
* Profile ScatterPlotItem.paint to identify bottlenecks
* Reuse targetRect to improve paint performance
* Readability improvements (opinionated)
* Only need to set x and y of targetRect
- w and h can stay set to 0 (not entirely sure why)
- this is a bit faster than setting all of x, y, w, h
* Minor renaming
* Strip off API changes and leave to another PR
* Renaming
* Compatibility
* Use drawPixmap(x, y, pm, sx, sy, sw, sh) signature to avoid needing to update QRectFs
* Use different drawing approaches for each Qt binding for performance reasons
* Fix a bug introduced two commits ago
Incidentally, I think there is a similar bug in the main branch currently.
* Minor performance and readability improvements
* Strip out source and target QRectF stuff
* Bring source and target QRectF stuff back in a less coupled way
* Leave deprecating getSpotOpts for another PR
* Compatibility fix
* Added docstrings and use SymbolAtlas__len__ where possible
* Fix export issue
* Add missing import
* Add deprecation warnings
* Avoid using deprecated methods
* Fix and cleanup max spot size measurements
* Make creation of style opts entries explicit
* Add hovering API to ScatterPlotItem
* Compatibility
* Marshal pen and brush lists in setPen and setBrush
* Fixed platform dependent bug
2020-12-16 19:07:39 +00:00
|
|
|
from itertools import chain
|
2012-03-02 02:55:32 +00:00
|
|
|
|
|
|
|
app = QtGui.QApplication([])
|
|
|
|
mw = QtGui.QMainWindow()
|
|
|
|
mw.resize(800,800)
|
|
|
|
view = pg.GraphicsLayoutWidget() ## GraphicsView with GraphicsLayout inserted by default
|
|
|
|
mw.setCentralWidget(view)
|
|
|
|
mw.show()
|
2013-02-25 04:09:03 +00:00
|
|
|
mw.setWindowTitle('pyqtgraph example: ScatterPlot')
|
2012-03-02 02:55:32 +00:00
|
|
|
|
|
|
|
## create four areas to add plots
|
|
|
|
w1 = view.addPlot()
|
|
|
|
w2 = view.addViewBox()
|
|
|
|
w2.setAspectLocked(True)
|
|
|
|
view.nextRow()
|
|
|
|
w3 = view.addPlot()
|
|
|
|
w4 = view.addPlot()
|
2014-01-17 01:34:05 +00:00
|
|
|
print("Generating data, this takes a few seconds...")
|
2012-03-02 02:55:32 +00:00
|
|
|
|
Scatter Plot Improvements (#1420)
* Added hovering demo to ScatterPlot example
* Use Qt's serialization for SymbolAtlas.symbolMap keys
Yields significant performance improvements when updating the scatter plot's options. See e.g. the plot hover example.
* Further optimized scatter plot picking
* Fix ScatterPlot example tool tip
* Clean up while I'm here
* Compatibility
* Some simple optimizations for ScatterPlotItem
Speedups for ScatterPlotSpeedTest.py:
~50% without pxMode
~ 0% pxMode with useCache
~30% pxMode without useCache
* ~3x speedup in scatter plot speed test with pxMode
* More optimization low-hanging fruit for the scatter plot
* Removed hover example to lazily pass tests
* Avoid segfault
* Re-add hover example to ScatterPlot.py
* Switch to id-based keying for scatter plot symbol atlas
- Use cases exist where serialization-based keying is a significant bottleneck, e.g. updating without atlas invalidation when a large variety pens or brushes are present.
- To avoid a performance hit, the onus is on the user to carefully reuse pen and brush objects.
* Optimized caching in scatter plot hovering example
* Fixed and optimized scatter plot hovering example
* Minor scatter plot optimization
* Cleanup
* Store hovered points in a set for the hovering example
* Keep a limited number symbol atlas entries around for future reuse
* Added a docstring note to remind the user to reuse QPen and QBrush objects for better performance
* Tidied up hovering example
* Typo
* Avoid unnecessary atlas rebuilds
* Refactored SymbolAtlas
* Efficient appending to SymbolAtlas
* SymbolAtlas rewrite
* Cleanup and profiling
* Add randomized brushes to speed test
* Add loc indexer to ScatterPlotItem
* Profile ScatterPlotItem.paint to identify bottlenecks
* Reuse targetRect to improve paint performance
* Readability improvements (opinionated)
* Only need to set x and y of targetRect
- w and h can stay set to 0 (not entirely sure why)
- this is a bit faster than setting all of x, y, w, h
* Minor renaming
* Strip off API changes and leave to another PR
* Renaming
* Compatibility
* Use drawPixmap(x, y, pm, sx, sy, sw, sh) signature to avoid needing to update QRectFs
* Use different drawing approaches for each Qt binding for performance reasons
* Fix a bug introduced two commits ago
Incidentally, I think there is a similar bug in the main branch currently.
* Minor performance and readability improvements
* Strip out source and target QRectF stuff
* Bring source and target QRectF stuff back in a less coupled way
* Leave deprecating getSpotOpts for another PR
* Compatibility fix
* Added docstrings and use SymbolAtlas__len__ where possible
* Fix export issue
* Add missing import
* Add deprecation warnings
* Avoid using deprecated methods
* Fix and cleanup max spot size measurements
* Make creation of style opts entries explicit
* Add hovering API to ScatterPlotItem
* Compatibility
* Marshal pen and brush lists in setPen and setBrush
* Fixed platform dependent bug
2020-12-16 19:07:39 +00:00
|
|
|
## 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
|
2012-03-02 02:55:32 +00:00
|
|
|
|
|
|
|
|
Scatter Plot Improvements (#1420)
* Added hovering demo to ScatterPlot example
* Use Qt's serialization for SymbolAtlas.symbolMap keys
Yields significant performance improvements when updating the scatter plot's options. See e.g. the plot hover example.
* Further optimized scatter plot picking
* Fix ScatterPlot example tool tip
* Clean up while I'm here
* Compatibility
* Some simple optimizations for ScatterPlotItem
Speedups for ScatterPlotSpeedTest.py:
~50% without pxMode
~ 0% pxMode with useCache
~30% pxMode without useCache
* ~3x speedup in scatter plot speed test with pxMode
* More optimization low-hanging fruit for the scatter plot
* Removed hover example to lazily pass tests
* Avoid segfault
* Re-add hover example to ScatterPlot.py
* Switch to id-based keying for scatter plot symbol atlas
- Use cases exist where serialization-based keying is a significant bottleneck, e.g. updating without atlas invalidation when a large variety pens or brushes are present.
- To avoid a performance hit, the onus is on the user to carefully reuse pen and brush objects.
* Optimized caching in scatter plot hovering example
* Fixed and optimized scatter plot hovering example
* Minor scatter plot optimization
* Cleanup
* Store hovered points in a set for the hovering example
* Keep a limited number symbol atlas entries around for future reuse
* Added a docstring note to remind the user to reuse QPen and QBrush objects for better performance
* Tidied up hovering example
* Typo
* Avoid unnecessary atlas rebuilds
* Refactored SymbolAtlas
* Efficient appending to SymbolAtlas
* SymbolAtlas rewrite
* Cleanup and profiling
* Add randomized brushes to speed test
* Add loc indexer to ScatterPlotItem
* Profile ScatterPlotItem.paint to identify bottlenecks
* Reuse targetRect to improve paint performance
* Readability improvements (opinionated)
* Only need to set x and y of targetRect
- w and h can stay set to 0 (not entirely sure why)
- this is a bit faster than setting all of x, y, w, h
* Minor renaming
* Strip off API changes and leave to another PR
* Renaming
* Compatibility
* Use drawPixmap(x, y, pm, sx, sy, sw, sh) signature to avoid needing to update QRectFs
* Use different drawing approaches for each Qt binding for performance reasons
* Fix a bug introduced two commits ago
Incidentally, I think there is a similar bug in the main branch currently.
* Minor performance and readability improvements
* Strip out source and target QRectF stuff
* Bring source and target QRectF stuff back in a less coupled way
* Leave deprecating getSpotOpts for another PR
* Compatibility fix
* Added docstrings and use SymbolAtlas__len__ where possible
* Fix export issue
* Add missing import
* Add deprecation warnings
* Avoid using deprecated methods
* Fix and cleanup max spot size measurements
* Make creation of style opts entries explicit
* Add hovering API to ScatterPlotItem
* Compatibility
* Marshal pen and brush lists in setPen and setBrush
* Fixed platform dependent bug
2020-12-16 19:07:39 +00:00
|
|
|
## There are a few different ways we can draw scatter plots; each is optimized for different types of data:
|
|
|
|
|
2018-01-28 23:14:48 +00:00
|
|
|
## 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
|
2012-05-11 03:37:07 +00:00
|
|
|
## image and just drawing that image repeatedly.
|
2012-03-02 02:55:32 +00:00
|
|
|
|
|
|
|
n = 300
|
2012-05-11 03:37:07 +00:00
|
|
|
s1 = pg.ScatterPlotItem(size=10, pen=pg.mkPen(None), brush=pg.mkBrush(255, 255, 255, 120))
|
2012-03-02 02:55:32 +00:00
|
|
|
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)
|
|
|
|
|
|
|
|
|
2018-01-28 23:14:48 +00:00
|
|
|
## 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
|
2013-09-20 08:46:33 +00:00
|
|
|
## image.
|
2012-03-02 02:55:32 +00:00
|
|
|
|
2018-01-28 23:14:48 +00:00
|
|
|
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))
|
|
|
|
|
2012-03-02 02:55:32 +00:00
|
|
|
s2 = pg.ScatterPlotItem(size=10, pen=pg.mkPen('w'), pxMode=True)
|
|
|
|
pos = np.random.normal(size=(2,n), scale=1e-5)
|
2020-06-11 06:03:43 +00:00
|
|
|
spots = [{'pos': pos[:,i], 'data': 1, 'brush':pg.intColor(i, n), 'symbol': i%10, 'size': 5+i/10.} for i in range(n)]
|
2012-03-02 02:55:32 +00:00
|
|
|
s2.addPoints(spots)
|
2018-01-28 23:14:48 +00:00
|
|
|
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)
|
2012-03-02 02:55:32 +00:00
|
|
|
w2.addItem(s2)
|
|
|
|
s2.sigClicked.connect(clicked)
|
|
|
|
|
|
|
|
|
2018-01-28 23:14:48 +00:00
|
|
|
## 3) Spots are not transform-invariant, not identical (bottom-left).
|
|
|
|
## This is the slowest case, since all spots must be completely re-drawn
|
2012-03-02 02:55:32 +00:00
|
|
|
## every time because their apparent transformation may have changed.
|
|
|
|
|
Scatter Plot Improvements (#1420)
* Added hovering demo to ScatterPlot example
* Use Qt's serialization for SymbolAtlas.symbolMap keys
Yields significant performance improvements when updating the scatter plot's options. See e.g. the plot hover example.
* Further optimized scatter plot picking
* Fix ScatterPlot example tool tip
* Clean up while I'm here
* Compatibility
* Some simple optimizations for ScatterPlotItem
Speedups for ScatterPlotSpeedTest.py:
~50% without pxMode
~ 0% pxMode with useCache
~30% pxMode without useCache
* ~3x speedup in scatter plot speed test with pxMode
* More optimization low-hanging fruit for the scatter plot
* Removed hover example to lazily pass tests
* Avoid segfault
* Re-add hover example to ScatterPlot.py
* Switch to id-based keying for scatter plot symbol atlas
- Use cases exist where serialization-based keying is a significant bottleneck, e.g. updating without atlas invalidation when a large variety pens or brushes are present.
- To avoid a performance hit, the onus is on the user to carefully reuse pen and brush objects.
* Optimized caching in scatter plot hovering example
* Fixed and optimized scatter plot hovering example
* Minor scatter plot optimization
* Cleanup
* Store hovered points in a set for the hovering example
* Keep a limited number symbol atlas entries around for future reuse
* Added a docstring note to remind the user to reuse QPen and QBrush objects for better performance
* Tidied up hovering example
* Typo
* Avoid unnecessary atlas rebuilds
* Refactored SymbolAtlas
* Efficient appending to SymbolAtlas
* SymbolAtlas rewrite
* Cleanup and profiling
* Add randomized brushes to speed test
* Add loc indexer to ScatterPlotItem
* Profile ScatterPlotItem.paint to identify bottlenecks
* Reuse targetRect to improve paint performance
* Readability improvements (opinionated)
* Only need to set x and y of targetRect
- w and h can stay set to 0 (not entirely sure why)
- this is a bit faster than setting all of x, y, w, h
* Minor renaming
* Strip off API changes and leave to another PR
* Renaming
* Compatibility
* Use drawPixmap(x, y, pm, sx, sy, sw, sh) signature to avoid needing to update QRectFs
* Use different drawing approaches for each Qt binding for performance reasons
* Fix a bug introduced two commits ago
Incidentally, I think there is a similar bug in the main branch currently.
* Minor performance and readability improvements
* Strip out source and target QRectF stuff
* Bring source and target QRectF stuff back in a less coupled way
* Leave deprecating getSpotOpts for another PR
* Compatibility fix
* Added docstrings and use SymbolAtlas__len__ where possible
* Fix export issue
* Add missing import
* Add deprecation warnings
* Avoid using deprecated methods
* Fix and cleanup max spot size measurements
* Make creation of style opts entries explicit
* Add hovering API to ScatterPlotItem
* Compatibility
* Marshal pen and brush lists in setPen and setBrush
* Fixed platform dependent bug
2020-12-16 19:07:39 +00:00
|
|
|
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
|
|
|
|
)
|
2012-03-02 02:55:32 +00:00
|
|
|
spots3 = []
|
|
|
|
for i in range(10):
|
|
|
|
for j in range(10):
|
2013-02-13 02:44:42 +00:00
|
|
|
spots3.append({'pos': (1e-6*i, 1e-6*j), 'size': 1e-6, 'pen': {'color': 'w', 'width': 2}, 'brush':pg.intColor(i*10+j, 100)})
|
2012-03-02 02:55:32 +00:00
|
|
|
s3.addPoints(spots3)
|
|
|
|
w3.addItem(s3)
|
|
|
|
s3.sigClicked.connect(clicked)
|
|
|
|
|
2012-05-11 03:37:07 +00:00
|
|
|
## Test performance of large scatterplots
|
2012-03-02 02:55:32 +00:00
|
|
|
|
Scatter Plot Improvements (#1420)
* Added hovering demo to ScatterPlot example
* Use Qt's serialization for SymbolAtlas.symbolMap keys
Yields significant performance improvements when updating the scatter plot's options. See e.g. the plot hover example.
* Further optimized scatter plot picking
* Fix ScatterPlot example tool tip
* Clean up while I'm here
* Compatibility
* Some simple optimizations for ScatterPlotItem
Speedups for ScatterPlotSpeedTest.py:
~50% without pxMode
~ 0% pxMode with useCache
~30% pxMode without useCache
* ~3x speedup in scatter plot speed test with pxMode
* More optimization low-hanging fruit for the scatter plot
* Removed hover example to lazily pass tests
* Avoid segfault
* Re-add hover example to ScatterPlot.py
* Switch to id-based keying for scatter plot symbol atlas
- Use cases exist where serialization-based keying is a significant bottleneck, e.g. updating without atlas invalidation when a large variety pens or brushes are present.
- To avoid a performance hit, the onus is on the user to carefully reuse pen and brush objects.
* Optimized caching in scatter plot hovering example
* Fixed and optimized scatter plot hovering example
* Minor scatter plot optimization
* Cleanup
* Store hovered points in a set for the hovering example
* Keep a limited number symbol atlas entries around for future reuse
* Added a docstring note to remind the user to reuse QPen and QBrush objects for better performance
* Tidied up hovering example
* Typo
* Avoid unnecessary atlas rebuilds
* Refactored SymbolAtlas
* Efficient appending to SymbolAtlas
* SymbolAtlas rewrite
* Cleanup and profiling
* Add randomized brushes to speed test
* Add loc indexer to ScatterPlotItem
* Profile ScatterPlotItem.paint to identify bottlenecks
* Reuse targetRect to improve paint performance
* Readability improvements (opinionated)
* Only need to set x and y of targetRect
- w and h can stay set to 0 (not entirely sure why)
- this is a bit faster than setting all of x, y, w, h
* Minor renaming
* Strip off API changes and leave to another PR
* Renaming
* Compatibility
* Use drawPixmap(x, y, pm, sx, sy, sw, sh) signature to avoid needing to update QRectFs
* Use different drawing approaches for each Qt binding for performance reasons
* Fix a bug introduced two commits ago
Incidentally, I think there is a similar bug in the main branch currently.
* Minor performance and readability improvements
* Strip out source and target QRectF stuff
* Bring source and target QRectF stuff back in a less coupled way
* Leave deprecating getSpotOpts for another PR
* Compatibility fix
* Added docstrings and use SymbolAtlas__len__ where possible
* Fix export issue
* Add missing import
* Add deprecation warnings
* Avoid using deprecated methods
* Fix and cleanup max spot size measurements
* Make creation of style opts entries explicit
* Add hovering API to ScatterPlotItem
* Compatibility
* Marshal pen and brush lists in setPen and setBrush
* Fixed platform dependent bug
2020-12-16 19:07:39 +00:00
|
|
|
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)
|
|
|
|
)
|
2012-03-02 02:55:32 +00:00
|
|
|
w4.addItem(s4)
|
2012-05-11 03:37:07 +00:00
|
|
|
s4.sigClicked.connect(clicked)
|
2012-03-02 02:55:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
## Start Qt event loop unless running in interactive mode.
|
2012-12-05 05:25:45 +00:00
|
|
|
if __name__ == '__main__':
|
|
|
|
import sys
|
|
|
|
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
|
|
|
QtGui.QApplication.instance().exec_()
|