- Fixed issue with numpy.concatenate wrapper

- ConsoleWidget now correctly catches its own exceptions
- Fixed ViewBox auto-scaling bug
- Fixed functions.siEval not parsing units correctly
- Fixed bug caused when opengl GL_VERSION_STR is None
This commit is contained in:
Luke Campagnola 2012-10-09 20:40:48 -04:00
parent 844dbb20a5
commit 1d05656a73
6 changed files with 88 additions and 57 deletions

View File

@ -217,6 +217,7 @@ class ConsoleWidget(QtGui.QWidget):
for l in tb.split('\n'):
lines.append(" "*indent + prefix + l)
self.write('\n'.join(lines))
self.exceptionHandler(*sys.exc_info())
def cmdSelected(self, item):
index = -(self.ui.historyList.row(item)+1)
@ -314,6 +315,8 @@ class ConsoleWidget(QtGui.QWidget):
def exceptionHandler(self, excType, exc, tb):
if self.ui.catchNextExceptionBtn.isChecked():
self.ui.catchNextExceptionBtn.setChecked(False)
elif not self.ui.catchAllExceptionsBtn.isChecked():
return
self.ui.clearExceptionBtn.setEnabled(True)
self.currentTraceback = tb

View File

@ -1,5 +1,6 @@
import initExample ## Add path to library (just for examples; you do not need this)
import numpy as np
import scipy.ndimage as ndi
import pyqtgraph as pg
from pyqtgraph.Qt import QtGui, QtCore
from pyqtgraph.Point import Point
@ -11,22 +12,38 @@ label = pg.LabelItem(justify='right')
win.addItem(label)
p1 = win.addPlot(row=1, col=0)
p2 = win.addPlot(row=2, col=0)
region = pg.LinearRegionItem()
region.setZValue(10)
p2.addItem(region)
#pg.dbg()
p1.setAutoVisible(y=True)
#create numpy arrays
#make the numbers large to show that the xrange shows data from 10000 to all the way 0
data1 = 10000 + 3000 * np.random.random(size=10000)
data2 = 15000 + 3000 * np.random.random(size=10000)
data1 = 10000 + 15000 * ndi.gaussian_filter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)
data2 = 15000 + 15000 * ndi.gaussian_filter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)
p1.plot(data1, pen="r")
p1.plot(data2, pen="g")
p2.plot(data1, pen="w")
def update():
p1.setXRange(*region.getRegion())
region.setZValue(10)
minX, maxX = region.getRegion()
p1.setXRange(minX, maxX, padding=0)
region.sigRegionChanged.connect(update)
def updateRegion(window, viewRange):
rgn = viewRange[0]
region.setRegion(rgn)
p1.sigRangeChanged.connect(updateRegion)
region.setRegion([1000, 2000])
#cross hair
@ -34,6 +51,8 @@ vLine = pg.InfiniteLine(angle=90, movable=False)
hLine = pg.InfiniteLine(angle=0, movable=False)
p1.addItem(vLine, ignoreBounds=True)
p1.addItem(hLine, ignoreBounds=True)
vb = p1.vb
def mouseMoved(evt):
@ -45,6 +64,9 @@ def mouseMoved(evt):
label.setText("<span style='font-size: 12pt'>x=%0.1f, <span style='color: red'>y1=%0.1f</span>, <span style='color: green'>y2=%0.1f</span>" % (mousePoint.x(), data1[index], data2[index]))
vLine.setPos(mousePoint.x())
hLine.setPos(mousePoint.y())
proxy = pg.SignalProxy(p1.scene().sigMouseMoved, rateLimit=60, slot=mouseMoved)
#p1.scene().sigMouseMoved.connect(mouseMoved)
@ -52,4 +74,4 @@ proxy = pg.SignalProxy(p1.scene().sigMouseMoved, rateLimit=60, slot=mouseMoved)
## Start Qt event loop unless running in interactive mode or using pyside.
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
app.exec_()
app.exec_()

View File

@ -116,7 +116,7 @@ def siEval(s):
"""
s = asUnicode(s)
m = re.match(r'(-?((\d+(\.\d*)?)|(\.\d+))([eE]-?\d+)?)\s*([u' + SI_PREFIXES + r']?)$', s)
m = re.match(r'(-?((\d+(\.\d*)?)|(\.\d+))([eE]-?\d+)?)\s*([u' + SI_PREFIXES + r']?).*$', s)
if m is None:
raise Exception("Can't convert string '%s' to number." % s)
v = float(m.groups()[0])

View File

@ -532,7 +532,7 @@ class ViewBox(GraphicsWidget):
if type(fractionVisible[i]) is bool:
fractionVisible[i] = 1.0
childRect = None
childRange = None
order = [0,1]
if self.state['autoVisibleOnly'][0] is True:
@ -545,40 +545,48 @@ class ViewBox(GraphicsWidget):
if self.state['autoVisibleOnly'][ax]:
oRange = [None, None]
oRange[ax] = targetRect[1-ax]
childRect = self.childrenBoundingRect(frac=fractionVisible, orthoRange=oRange)
childRange = self.childrenBounds(frac=fractionVisible, orthoRange=oRange)
else:
if childRect is None:
childRect = self.childrenBoundingRect(frac=fractionVisible)
if ax == 0:
## Make corrections to X range
if childRange is None:
childRange = self.childrenBounds(frac=fractionVisible)
## Make corrections to range
xr = childRange[ax]
if xr is not None:
if self.state['autoPan'][0]:
x = childRect.center().x()
x = sum(xr) * 0.5
#x = childRect.center().x()
w2 = (targetRect[0][1]-targetRect[0][0]) / 2.
childRect.setLeft(x-w2)
childRect.setRight(x+w2)
#childRect.setLeft(x-w2)
#childRect.setRight(x+w2)
childRange[ax] = [x-w2, x+w2]
else:
wp = childRect.width() * 0.02
childRect = childRect.adjusted(-wp, 0, wp, 0)
#wp = childRect.width() * 0.02
wp = (xr[1] - xr[0]) * 0.02
#childRect = childRect.adjusted(-wp, 0, wp, 0)
childRange[ax][0] -= wp
childRange[ax][1] += wp
#targetRect[ax][0] = childRect.left()
#targetRect[ax][1] = childRect.right()
targetRect[ax] = childRange[ax]
args['xRange' if ax == 0 else 'yRange'] = targetRect[ax]
#else:
### Make corrections to Y range
#if self.state['autoPan'][1]:
#y = childRect.center().y()
#h2 = (targetRect[1][1]-targetRect[1][0]) / 2.
#childRect.setTop(y-h2)
#childRect.setBottom(y+h2)
#else:
#hp = childRect.height() * 0.02
#childRect = childRect.adjusted(0, -hp, 0, hp)
targetRect[0][0] = childRect.left()
targetRect[0][1] = childRect.right()
args['xRange'] = targetRect[0]
else:
## Make corrections to Y range
if self.state['autoPan'][1]:
y = childRect.center().y()
h2 = (targetRect[1][1]-targetRect[1][0]) / 2.
childRect.setTop(y-h2)
childRect.setBottom(y+h2)
else:
hp = childRect.height() * 0.02
childRect = childRect.adjusted(0, -hp, 0, hp)
targetRect[1][0] = childRect.top()
targetRect[1][1] = childRect.bottom()
args['yRange'] = targetRect[1]
#targetRect[1][0] = childRect.top()
#targetRect[1][1] = childRect.bottom()
#args['yRange'] = targetRect[1]
if len(args) == 0:
return
args['padding'] = 0
args['disableAutoRange'] = False
#self.setRange(xRange=targetRect[0], yRange=targetRect[1], padding=0, disableAutoRange=False)
@ -689,14 +697,14 @@ class ViewBox(GraphicsWidget):
overlap = min(sg.bottom(), vg.bottom()) - max(sg.top(), vg.top())
if overlap < min(vg.height()/3, sg.height()/3): ## if less than 1/3 of views overlap,
## then just replicate the view
x1 = vr.top()
x2 = vr.bottom()
y1 = vr.top()
y2 = vr.bottom()
else: ## views overlap; line them up
upp = float(vr.height()) / vg.height()
x1 = vr.top() + (sg.y()-vg.y()) * upp
x2 = x1 + sg.height() * upp
y2 = vr.bottom() - (sg.y()-vg.y()) * upp
y1 = y2 - sg.height() * upp
self.enableAutoRange(ViewBox.YAxis, False)
self.setYRange(x1, x2, padding=0)
self.setYRange(y1, y2, padding=0)
finally:
view.blockLink(False)
@ -984,8 +992,8 @@ class ViewBox(GraphicsWidget):
return children
def childrenBoundingRect(self, frac=None, orthoRange=(None,None)):
def childrenBounds(self, frac=None, orthoRange=(None,None)):
"""Return the bounding range of all children.
[[xmin, xmax], [ymin, ymax]]
Values may be None if there are no specific bounds for an axis.
@ -1052,22 +1060,18 @@ class ViewBox(GraphicsWidget):
if useY:
if range[1] is not None:
range[1] = [min(bounds.top(), range[1][0]), max(bounds.bottom(), range[1][1])]
#bounds.setTop(min(bounds.top(), chb.top()))
#bounds.setBottom(max(bounds.bottom(), chb.bottom()))
else:
range[1] = [bounds.top(), bounds.bottom()]
#bounds.setTop(chb.top())
#bounds.setBottom(chb.bottom())
if useX:
if range[0] is not None:
range[0] = [min(bounds.left(), range[0][0]), max(bounds.right(), range[0][1])]
#bounds.setLeft(min(bounds.left(), chb.left()))
#bounds.setRight(max(bounds.right(), chb.right()))
else:
range[0] = [bounds.left(), bounds.right()]
#bounds.setLeft(chb.left())
#bounds.setRight(chb.right())
return range
def childrenBoundingRect(self, *args, **kwds):
range = self.childrenBounds(*args, **kwds)
tr = self.targetRange()
if range[0] is None:
range[0] = tr[0]

View File

@ -5,15 +5,15 @@ try:
## (numpy trac issue #2084)
if not hasattr(np, 'concatenate_orig'):
np.concatenate_orig = np.concatenate
def concatenate(vals, **kwds):
def concatenate(vals, *args, **kwds):
"""Wrapper around numpy.concatenate (see pyqtgraph/numpy_fix.py)"""
dtypes = [getattr(v, 'dtype', None) for v in vals]
names = [getattr(dt, 'names', None) for dt in dtypes]
if len(dtypes) < 2 or all([n is None for n in names]):
return np.concatenate_orig(vals, **kwds)
return np.concatenate_orig(vals, *args, **kwds)
if any([dt != dtypes[0] for dt in dtypes[1:]]):
raise TypeError("Cannot concatenate structured arrays of different dtype.")
return np.concatenate_orig(vals, **kwds)
return np.concatenate_orig(vals, *args, **kwds)
np.concatenate = concatenate

View File

@ -109,11 +109,13 @@ class GLViewWidget(QtOpenGL.QGLWidget):
import pyqtgraph.debug
pyqtgraph.debug.printExc()
msg = "Error while drawing item %s." % str(item)
ver = glGetString(GL_VERSION).split()[0]
if int(ver.split('.')[0]) < 2:
print(msg + " The original exception is printed above; however, pyqtgraph requires OpenGL version 2.0 or greater for many of its 3D features and your OpenGL version is %s. Installing updated display drivers may resolve this issue." % ver)
else:
print(msg)
ver = glGetString(GL_VERSION)
if ver is not None:
ver = ver.split()[0]
if int(ver.split('.')[0]) < 2:
print(msg + " The original exception is printed above; however, pyqtgraph requires OpenGL version 2.0 or greater for many of its 3D features and your OpenGL version is %s. Installing updated display drivers may resolve this issue." % ver)
else:
print(msg)
finally:
glPopAttrib()