Merge branch 'develop' into scatterplotwidget-updates
This commit is contained in:
commit
434d2b8c71
@ -12,32 +12,27 @@ from pyqtgraph.Qt import QtGui, QtCore
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
from pyqtgraph.ptime import time
|
from pyqtgraph.ptime import time
|
||||||
#QtGui.QApplication.setGraphicsSystem('raster')
|
|
||||||
app = QtGui.QApplication([])
|
app = QtGui.QApplication([])
|
||||||
#mw = QtGui.QMainWindow()
|
|
||||||
#mw.resize(800,800)
|
|
||||||
|
|
||||||
p = pg.plot()
|
plot = pg.plot()
|
||||||
p.setWindowTitle('pyqtgraph example: MultiPlotSpeedTest')
|
plot.setWindowTitle('pyqtgraph example: MultiPlotSpeedTest')
|
||||||
#p.setRange(QtCore.QRectF(0, -10, 5000, 20))
|
plot.setLabel('bottom', 'Index', units='B')
|
||||||
p.setLabel('bottom', 'Index', units='B')
|
|
||||||
|
|
||||||
nPlots = 100
|
nPlots = 100
|
||||||
nSamples = 500
|
nSamples = 500
|
||||||
#curves = [p.plot(pen=(i,nPlots*1.3)) for i in range(nPlots)]
|
|
||||||
curves = []
|
curves = []
|
||||||
for i in range(nPlots):
|
for idx in range(nPlots):
|
||||||
c = pg.PlotCurveItem(pen=(i,nPlots*1.3))
|
curve = pg.PlotCurveItem(pen=(idx,nPlots*1.3))
|
||||||
p.addItem(c)
|
plot.addItem(curve)
|
||||||
c.setPos(0,i*6)
|
curve.setPos(0,idx*6)
|
||||||
curves.append(c)
|
curves.append(curve)
|
||||||
|
|
||||||
p.setYRange(0, nPlots*6)
|
plot.setYRange(0, nPlots*6)
|
||||||
p.setXRange(0, nSamples)
|
plot.setXRange(0, nSamples)
|
||||||
p.resize(600,900)
|
plot.resize(600,900)
|
||||||
|
|
||||||
rgn = pg.LinearRegionItem([nSamples/5.,nSamples/3.])
|
rgn = pg.LinearRegionItem([nSamples/5.,nSamples/3.])
|
||||||
p.addItem(rgn)
|
plot.addItem(rgn)
|
||||||
|
|
||||||
|
|
||||||
data = np.random.normal(size=(nPlots*23,nSamples))
|
data = np.random.normal(size=(nPlots*23,nSamples))
|
||||||
@ -46,13 +41,12 @@ lastTime = time()
|
|||||||
fps = None
|
fps = None
|
||||||
count = 0
|
count = 0
|
||||||
def update():
|
def update():
|
||||||
global curve, data, ptr, p, lastTime, fps, nPlots, count
|
global curve, data, ptr, plot, lastTime, fps, nPlots, count
|
||||||
count += 1
|
count += 1
|
||||||
#print "---------", count
|
|
||||||
for i in range(nPlots):
|
for i in range(nPlots):
|
||||||
curves[i].setData(data[(ptr+i)%data.shape[0]])
|
curves[i].setData(data[(ptr+i)%data.shape[0]])
|
||||||
|
|
||||||
#print " setData done."
|
|
||||||
ptr += nPlots
|
ptr += nPlots
|
||||||
now = time()
|
now = time()
|
||||||
dt = now - lastTime
|
dt = now - lastTime
|
||||||
@ -62,13 +56,11 @@ def update():
|
|||||||
else:
|
else:
|
||||||
s = np.clip(dt*3., 0, 1)
|
s = np.clip(dt*3., 0, 1)
|
||||||
fps = fps * (1-s) + (1.0/dt) * s
|
fps = fps * (1-s) + (1.0/dt) * s
|
||||||
p.setTitle('%0.2f fps' % fps)
|
plot.setTitle('%0.2f fps' % fps)
|
||||||
#app.processEvents() ## force complete redraw for every plot
|
#app.processEvents() ## force complete redraw for every plot
|
||||||
timer = QtCore.QTimer()
|
timer = QtCore.QTimer()
|
||||||
timer.timeout.connect(update)
|
timer.timeout.connect(update)
|
||||||
timer.start(0)
|
timer.start(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Start Qt event loop unless running in interactive mode.
|
## Start Qt event loop unless running in interactive mode.
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -26,6 +26,7 @@ class ExampleLoader(QtGui.QMainWindow):
|
|||||||
self.cw = QtGui.QWidget()
|
self.cw = QtGui.QWidget()
|
||||||
self.setCentralWidget(self.cw)
|
self.setCentralWidget(self.cw)
|
||||||
self.ui.setupUi(self.cw)
|
self.ui.setupUi(self.cw)
|
||||||
|
self.setWindowTitle("PyQtGraph Examples")
|
||||||
|
|
||||||
self.codeBtn = QtGui.QPushButton('Run Edited Code')
|
self.codeBtn = QtGui.QPushButton('Run Edited Code')
|
||||||
self.codeLayout = QtGui.QGridLayout()
|
self.codeLayout = QtGui.QGridLayout()
|
||||||
|
@ -4,6 +4,7 @@ Displays an interactive Koch fractal
|
|||||||
"""
|
"""
|
||||||
import initExample ## Add path to library (just for examples; you do not need this)
|
import initExample ## Add path to library (just for examples; you do not need this)
|
||||||
|
|
||||||
|
from functools import reduce
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
from pyqtgraph.Qt import QtCore, QtGui
|
from pyqtgraph.Qt import QtCore, QtGui
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -111,12 +112,4 @@ if __name__ == '__main__':
|
|||||||
import sys
|
import sys
|
||||||
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
|
||||||
QtGui.QApplication.instance().exec_()
|
QtGui.QApplication.instance().exec_()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -359,7 +359,6 @@ class ConsoleWidget(QtGui.QWidget):
|
|||||||
for index, line in enumerate(traceback.extract_stack(frame)):
|
for index, line in enumerate(traceback.extract_stack(frame)):
|
||||||
# extract_stack return value changed in python 3.5
|
# extract_stack return value changed in python 3.5
|
||||||
if 'FrameSummary' in str(type(line)):
|
if 'FrameSummary' in str(type(line)):
|
||||||
print(dir(line))
|
|
||||||
line = (line.filename, line.lineno, line.name, line._line)
|
line = (line.filename, line.lineno, line.name, line._line)
|
||||||
|
|
||||||
self.ui.exceptionStackList.addItem('File "%s", line %s, in %s()\n %s' % line)
|
self.ui.exceptionStackList.addItem('File "%s", line %s, in %s()\n %s' % line)
|
||||||
@ -380,7 +379,6 @@ class ConsoleWidget(QtGui.QWidget):
|
|||||||
for index, line in enumerate(traceback.extract_tb(tb)):
|
for index, line in enumerate(traceback.extract_tb(tb)):
|
||||||
# extract_stack return value changed in python 3.5
|
# extract_stack return value changed in python 3.5
|
||||||
if 'FrameSummary' in str(type(line)):
|
if 'FrameSummary' in str(type(line)):
|
||||||
print(dir(line))
|
|
||||||
line = (line.filename, line.lineno, line.name, line._line)
|
line = (line.filename, line.lineno, line.name, line._line)
|
||||||
|
|
||||||
self.ui.exceptionStackList.addItem('File "%s", line %s, in %s()\n %s' % line)
|
self.ui.exceptionStackList.addItem('File "%s", line %s, in %s()\n %s' % line)
|
||||||
|
@ -169,7 +169,7 @@ def _generateItemSvg(item, nodes=None, root=None):
|
|||||||
buf = QtCore.QBuffer(arr)
|
buf = QtCore.QBuffer(arr)
|
||||||
svg = QtSvg.QSvgGenerator()
|
svg = QtSvg.QSvgGenerator()
|
||||||
svg.setOutputDevice(buf)
|
svg.setOutputDevice(buf)
|
||||||
dpi = QtGui.QDesktopWidget().physicalDpiX()
|
dpi = QtGui.QDesktopWidget().logicalDpiX()
|
||||||
svg.setResolution(dpi)
|
svg.setResolution(dpi)
|
||||||
|
|
||||||
p = QtGui.QPainter()
|
p = QtGui.QPainter()
|
||||||
@ -372,7 +372,7 @@ def correctCoordinates(node, defs, item):
|
|||||||
ch.setAttribute('font-family', ', '.join([f if ' ' not in f else '"%s"'%f for f in families]))
|
ch.setAttribute('font-family', ', '.join([f if ' ' not in f else '"%s"'%f for f in families]))
|
||||||
|
|
||||||
## correct line widths if needed
|
## correct line widths if needed
|
||||||
if removeTransform and ch.getAttribute('vector-effect') != 'non-scaling-stroke':
|
if removeTransform and ch.getAttribute('vector-effect') != 'non-scaling-stroke' and grp.getAttribute('stroke-width') != '':
|
||||||
w = float(grp.getAttribute('stroke-width'))
|
w = float(grp.getAttribute('stroke-width'))
|
||||||
s = fn.transformCoordinates(tr, np.array([[w,0], [0,0]]), transpose=True)
|
s = fn.transformCoordinates(tr, np.array([[w,0], [0,0]]), transpose=True)
|
||||||
w = ((s[0]-s[1])**2).sum()**0.5
|
w = ((s[0]-s[1])**2).sum()**0.5
|
||||||
|
@ -110,7 +110,8 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
|
|||||||
#print("-------")
|
#print("-------")
|
||||||
for sample, label in self.items:
|
for sample, label in self.items:
|
||||||
height += max(sample.height(), label.height()) + 3
|
height += max(sample.height(), label.height()) + 3
|
||||||
width = max(width, sample.width()+label.width())
|
width = max(width, (sample.sizeHint(QtCore.Qt.MinimumSize, sample.size()).width() +
|
||||||
|
label.sizeHint(QtCore.Qt.MinimumSize, label.size()).width()))
|
||||||
#print(width, height)
|
#print(width, height)
|
||||||
#print width, height
|
#print width, height
|
||||||
self.setGeometry(0, 0, width+25, height)
|
self.setGeometry(0, 0, width+25, height)
|
||||||
|
@ -849,8 +849,15 @@ class SpotItem(object):
|
|||||||
|
|
||||||
def __init__(self, data, plot, index):
|
def __init__(self, data, plot, index):
|
||||||
self._data = data
|
self._data = data
|
||||||
self._plot = plot
|
|
||||||
self._index = index
|
self._index = index
|
||||||
|
# SpotItems are kept in plot.data["items"] numpy object array which
|
||||||
|
# does not support cyclic garbage collection (numpy issue 6581).
|
||||||
|
# Keeping a strong ref to plot here would leak the cycle
|
||||||
|
self.__plot_ref = weakref.ref(plot)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _plot(self):
|
||||||
|
return self.__plot_ref()
|
||||||
|
|
||||||
def data(self):
|
def data(self):
|
||||||
"""Return the user data associated with this spot."""
|
"""Return the user data associated with this spot."""
|
||||||
|
@ -16,9 +16,13 @@ class GLViewWidget(QtOpenGL.QGLWidget):
|
|||||||
- Axis/grid display
|
- Axis/grid display
|
||||||
- Export options
|
- Export options
|
||||||
|
|
||||||
|
|
||||||
|
High-DPI displays: Qt5 should automatically detect the correct resolution.
|
||||||
|
For Qt4, specify the ``devicePixelRatio`` argument when initializing the
|
||||||
|
widget (usually this value is 1-2).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None, devicePixelRatio=None):
|
||||||
global ShareWidget
|
global ShareWidget
|
||||||
|
|
||||||
if ShareWidget is None:
|
if ShareWidget is None:
|
||||||
@ -37,6 +41,7 @@ class GLViewWidget(QtOpenGL.QGLWidget):
|
|||||||
'azimuth': 45, ## camera's azimuthal angle in degrees
|
'azimuth': 45, ## camera's azimuthal angle in degrees
|
||||||
## (rotation around z-axis 0 points along x-axis)
|
## (rotation around z-axis 0 points along x-axis)
|
||||||
'viewport': None, ## glViewport params; None == whole widget
|
'viewport': None, ## glViewport params; None == whole widget
|
||||||
|
'devicePixelRatio': devicePixelRatio,
|
||||||
}
|
}
|
||||||
self.setBackgroundColor('k')
|
self.setBackgroundColor('k')
|
||||||
self.items = []
|
self.items = []
|
||||||
@ -79,10 +84,21 @@ class GLViewWidget(QtOpenGL.QGLWidget):
|
|||||||
|
|
||||||
def getViewport(self):
|
def getViewport(self):
|
||||||
vp = self.opts['viewport']
|
vp = self.opts['viewport']
|
||||||
|
dpr = self.devicePixelRatio()
|
||||||
if vp is None:
|
if vp is None:
|
||||||
return (0, 0, self.width(), self.height())
|
return (0, 0, int(self.width() * dpr), int(self.height() * dpr))
|
||||||
else:
|
else:
|
||||||
return vp
|
return tuple([int(x * dpr) for x in vp])
|
||||||
|
|
||||||
|
def devicePixelRatio(self):
|
||||||
|
dpr = self.opts['devicePixelRatio']
|
||||||
|
if dpr is not None:
|
||||||
|
return dpr
|
||||||
|
|
||||||
|
if hasattr(QtOpenGL.QGLWidget, 'devicePixelRatio'):
|
||||||
|
return QtOpenGL.QGLWidget.devicePixelRatio(self)
|
||||||
|
else:
|
||||||
|
return 1.0
|
||||||
|
|
||||||
def resizeGL(self, w, h):
|
def resizeGL(self, w, h):
|
||||||
pass
|
pass
|
||||||
@ -99,7 +115,8 @@ class GLViewWidget(QtOpenGL.QGLWidget):
|
|||||||
def projectionMatrix(self, region=None):
|
def projectionMatrix(self, region=None):
|
||||||
# Xw = (Xnd + 1) * width/2 + X
|
# Xw = (Xnd + 1) * width/2 + X
|
||||||
if region is None:
|
if region is None:
|
||||||
region = (0, 0, self.width(), self.height())
|
dpr = self.devicePixelRatio()
|
||||||
|
region = (0, 0, self.width() * dpr, self.height() * dpr)
|
||||||
|
|
||||||
x0, y0, w, h = self.getViewport()
|
x0, y0, w, h = self.getViewport()
|
||||||
dist = self.opts['distance']
|
dist = self.opts['distance']
|
||||||
|
@ -485,7 +485,7 @@ class MeshData(object):
|
|||||||
if isinstance(radius, int):
|
if isinstance(radius, int):
|
||||||
radius = [radius, radius] # convert to list
|
radius = [radius, radius] # convert to list
|
||||||
## compute vertexes
|
## compute vertexes
|
||||||
th = np.linspace(2 * np.pi, 0, cols).reshape(1, cols)
|
th = np.linspace(2 * np.pi, (2 * np.pi)/cols, cols).reshape(1, cols)
|
||||||
r = np.linspace(radius[0],radius[1],num=rows+1, endpoint=True).reshape(rows+1, 1) # radius as a function of z
|
r = np.linspace(radius[0],radius[1],num=rows+1, endpoint=True).reshape(rows+1, 1) # radius as a function of z
|
||||||
verts[...,2] = np.linspace(0, length, num=rows+1, endpoint=True).reshape(rows+1, 1) # z
|
verts[...,2] = np.linspace(0, length, num=rows+1, endpoint=True).reshape(rows+1, 1) # z
|
||||||
if offset:
|
if offset:
|
||||||
|
@ -10,10 +10,10 @@ class GLGridItem(GLGraphicsItem):
|
|||||||
"""
|
"""
|
||||||
**Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`
|
**Bases:** :class:`GLGraphicsItem <pyqtgraph.opengl.GLGraphicsItem>`
|
||||||
|
|
||||||
Displays a wire-grame grid.
|
Displays a wire-frame grid.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, size=None, color=None, antialias=True, glOptions='translucent'):
|
def __init__(self, size=None, color=(1, 1, 1, .3), antialias=True, glOptions='translucent'):
|
||||||
GLGraphicsItem.__init__(self)
|
GLGraphicsItem.__init__(self)
|
||||||
self.setGLOptions(glOptions)
|
self.setGLOptions(glOptions)
|
||||||
self.antialias = antialias
|
self.antialias = antialias
|
||||||
@ -21,6 +21,7 @@ class GLGridItem(GLGraphicsItem):
|
|||||||
size = QtGui.QVector3D(20,20,1)
|
size = QtGui.QVector3D(20,20,1)
|
||||||
self.setSize(size=size)
|
self.setSize(size=size)
|
||||||
self.setSpacing(1, 1, 1)
|
self.setSpacing(1, 1, 1)
|
||||||
|
self.color = color
|
||||||
|
|
||||||
def setSize(self, x=None, y=None, z=None, size=None):
|
def setSize(self, x=None, y=None, z=None, size=None):
|
||||||
"""
|
"""
|
||||||
@ -66,8 +67,8 @@ class GLGridItem(GLGraphicsItem):
|
|||||||
x,y,z = self.size()
|
x,y,z = self.size()
|
||||||
xs,ys,zs = self.spacing()
|
xs,ys,zs = self.spacing()
|
||||||
xvals = np.arange(-x/2., x/2. + xs*0.001, xs)
|
xvals = np.arange(-x/2., x/2. + xs*0.001, xs)
|
||||||
yvals = np.arange(-y/2., y/2. + ys*0.001, ys)
|
yvals = np.arange(-y/2., y/2. + ys*0.001, ys)
|
||||||
glColor4f(1, 1, 1, .3)
|
glColor4f(*self.color)
|
||||||
for x in xvals:
|
for x in xvals:
|
||||||
glVertex3f(x, yvals[0], 0)
|
glVertex3f(x, yvals[0], 0)
|
||||||
glVertex3f(x, yvals[-1], 0)
|
glVertex3f(x, yvals[-1], 0)
|
||||||
|
@ -122,7 +122,7 @@ if HAVE_OPENGL:
|
|||||||
if not self.uploaded:
|
if not self.uploaded:
|
||||||
self.uploadTexture()
|
self.uploadTexture()
|
||||||
|
|
||||||
glViewport(0, 0, self.width(), self.height())
|
glViewport(0, 0, self.width() * self.devicePixelRatio(), self.height() * self.devicePixelRatio())
|
||||||
glEnable(GL_TEXTURE_2D)
|
glEnable(GL_TEXTURE_2D)
|
||||||
glBindTexture(GL_TEXTURE_2D, self.texture)
|
glBindTexture(GL_TEXTURE_2D, self.texture)
|
||||||
glColor4f(1,1,1,1)
|
glColor4f(1,1,1,1)
|
||||||
|
Loading…
Reference in New Issue
Block a user