diff --git a/examples/GLScatterPlotItem.py b/examples/GLScatterPlotItem.py index c279eadf..1d8d5e06 100644 --- a/examples/GLScatterPlotItem.py +++ b/examples/GLScatterPlotItem.py @@ -8,6 +8,7 @@ Demonstrates use of GLScatterPlotItem with rapidly-updating plots. import initExample import pyqtgraph as pg +from pyqtgraph import functions as fn from pyqtgraph.Qt import QtCore, QtGui import pyqtgraph.opengl as gl import numpy as np @@ -84,10 +85,10 @@ def update(): global phase, sp2, d2 s = -np.cos(d2*2+phase) color = np.empty((len(d2),4), dtype=np.float32) - color[:,3] = np.clip(s * 0.1, 0, 1) - color[:,0] = np.clip(s * 3.0, 0, 1) - color[:,1] = np.clip(s * 1.0, 0, 1) - color[:,2] = np.clip(s ** 3, 0, 1) + color[:,3] = fn.clip_array(s * 0.1, 0., 1.) + color[:,0] = fn.clip_array(s * 3.0, 0., 1.) + color[:,1] = fn.clip_array(s * 1.0, 0., 1.) + color[:,2] = fn.clip_array(s ** 3, 0., 1.) sp2.setData(color=color) phase -= 0.1 diff --git a/examples/GLVolumeItem.py b/examples/GLVolumeItem.py index 42350844..99856a00 100644 --- a/examples/GLVolumeItem.py +++ b/examples/GLVolumeItem.py @@ -11,7 +11,7 @@ import numpy as np import pyqtgraph as pg from pyqtgraph.Qt import QtCore, QtGui import pyqtgraph.opengl as gl -from pyqtgraph.functions import clip_array +from pyqtgraph import functions as fn app = pg.mkQApp("GLVolumeItem Example") w = gl.GLViewWidget() @@ -40,8 +40,8 @@ def psi(i, j, k, offset=(50,50,100)): data = np.fromfunction(psi, (100,100,200)) -positive = np.log(clip_array(data, 0, data.max())**2) -negative = np.log(clip_array(-data, 0, -data.min())**2) +positive = np.log(fn.clip_array(data, np.finfo(data.dtype).eps, data.max())**2) +negative = np.log(fn.clip_array(-data, -np.finfo(data.dtype).eps, -data.min())**2) d2 = np.empty(data.shape + (4,), dtype=np.ubyte) d2[..., 0] = positive * (255./positive.max()) diff --git a/pyqtgraph/Point.py b/pyqtgraph/Point.py index 78a3a681..4ad2c7f9 100644 --- a/pyqtgraph/Point.py +++ b/pyqtgraph/Point.py @@ -6,14 +6,9 @@ Distributed under MIT/X11 license. See license.txt for more information. """ from .Qt import QtCore +from . import functions as fn from math import sin, acos, atan2, inf, pi, hypot -def clip(x, mn, mx): - if x > mx: - return mx - if x < mn: - return mn - return x class Point(QtCore.QPointF): """Extension of QPointF which adds a few missing methods.""" @@ -112,7 +107,7 @@ class Point(QtCore.QPointF): if n1 == 0. or n2 == 0.: return None ## Probably this should be done with arctan2 instead.. - ang = acos(clip(self.dot(a) / (n1 * n2), -1.0, 1.0)) ### in radians + ang = acos(fn.clip_scalar(self.dot(a) / (n1 * n2), -1.0, 1.0)) ### in radians c = self.cross(a) if c > 0: ang *= -1. diff --git a/pyqtgraph/Vector.py b/pyqtgraph/Vector.py index a9d28e41..c10a1f91 100644 --- a/pyqtgraph/Vector.py +++ b/pyqtgraph/Vector.py @@ -4,8 +4,9 @@ Vector.py - Extension of QVector3D which adds a few missing methods. Copyright 2010 Luke Campagnola Distributed under MIT/X11 license. See license.txt for more information. """ - +from math import acos from .Qt import QtGui, QtCore, QT_LIB +from . import functions as fn import numpy as np class Vector(QtGui.QVector3D): @@ -88,7 +89,7 @@ class Vector(QtGui.QVector3D): if n1 == 0. or n2 == 0.: return None ## Probably this should be done with arctan2 instead.. - ang = np.arccos(np.clip(QtGui.QVector3D.dotProduct(self, a) / (n1 * n2), -1.0, 1.0)) ### in radians + ang = acos(fn.clip_scalar(QtGui.QVector3D.dotProduct(self, a) / (n1 * n2), -1.0, 1.0)) ### in radians # c = self.crossProduct(a) # if c > 0: # ang *= -1. diff --git a/pyqtgraph/canvas/CanvasItem.py b/pyqtgraph/canvas/CanvasItem.py index 88612055..0cd86d0e 100644 --- a/pyqtgraph/canvas/CanvasItem.py +++ b/pyqtgraph/canvas/CanvasItem.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import numpy as np from ..Qt import QtGui, QtCore, QtSvg, QT_LIB +from .. import functions as fn from ..graphicsItems.ROI import ROI from .. import SRTTransform, ItemGroup import importlib @@ -240,7 +241,7 @@ class CanvasItem(QtCore.QObject): self._graphicsItem.setOpacity(alpha) def setAlpha(self, alpha): - self.alphaSlider.setValue(int(np.clip(alpha * 1023, 0, 1023))) + self.alphaSlider.setValue(int(fn.clip_scalar(alpha * 1023, 0, 1023))) def alpha(self): return self.alphaSlider.value() / 1023. diff --git a/pyqtgraph/graphicsItems/CurvePoint.py b/pyqtgraph/graphicsItems/CurvePoint.py index 9e4d3718..077c6839 100644 --- a/pyqtgraph/graphicsItems/CurvePoint.py +++ b/pyqtgraph/graphicsItems/CurvePoint.py @@ -63,7 +63,7 @@ class CurvePoint(GraphicsObject): pos = self.property('position') if 'QVariant' in repr(pos): ## need to support 2 APIs :( pos = pos.toDouble()[0] - index = (len(x)-1) * np.clip(pos, 0.0, 1.0) + index = (len(x)-1) * clip_scalar(pos, 0.0, 1.0) if index != int(index): ## interpolate floating-point values i1 = int(index) diff --git a/pyqtgraph/graphicsItems/GridItem.py b/pyqtgraph/graphicsItems/GridItem.py index 9004ac94..312d7b62 100644 --- a/pyqtgraph/graphicsItems/GridItem.py +++ b/pyqtgraph/graphicsItems/GridItem.py @@ -147,7 +147,7 @@ class GridItem(UIGraphicsItem): continue ppl = dim[ax] / nl[ax] - c = np.clip(5 * (ppl-3), 0., 50.).astype(int) + c = int(fn.clip_scalar(5 * (ppl-3), 0, 50)) linePen = self.opts['pen'] lineColor = self.opts['pen'].color() diff --git a/pyqtgraph/graphicsItems/InfiniteLine.py b/pyqtgraph/graphicsItems/InfiniteLine.py index ce96d00b..54b2d759 100644 --- a/pyqtgraph/graphicsItems/InfiniteLine.py +++ b/pyqtgraph/graphicsItems/InfiniteLine.py @@ -593,7 +593,7 @@ class InfLineLabel(TextItem): return rel = self._posToRel(ev.pos()) - self.orthoPos = np.clip(self._startPosition + rel - self._cursorOffset, 0, 1) + self.orthoPos = fn.clip_scalar(self._startPosition + rel - self._cursorOffset, 0., 1.) self.updatePosition() if ev.isFinish(): self._moving = False diff --git a/pyqtgraph/graphicsItems/PlotItem/PlotItem.py b/pyqtgraph/graphicsItems/PlotItem/PlotItem.py index a2affcf7..8da9ba39 100644 --- a/pyqtgraph/graphicsItems/PlotItem/PlotItem.py +++ b/pyqtgraph/graphicsItems/PlotItem/PlotItem.py @@ -372,7 +372,7 @@ class PlotItem(GraphicsWidget): if y is not None: self.ctrl.yGridCheck.setChecked(y) if alpha is not None: - v = np.clip(alpha, 0, 1)*self.ctrl.gridAlphaSlider.maximum() + v = fn.clip_scalar(alpha, 0., 1.)*self.ctrl.gridAlphaSlider.maximum() self.ctrl.gridAlphaSlider.setValue(v) def close(self): diff --git a/pyqtgraph/graphicsItems/ScatterPlotItem.py b/pyqtgraph/graphicsItems/ScatterPlotItem.py index 3d35f8fc..c32686dd 100644 --- a/pyqtgraph/graphicsItems/ScatterPlotItem.py +++ b/pyqtgraph/graphicsItems/ScatterPlotItem.py @@ -1073,7 +1073,7 @@ class ScatterPlotItem(GraphicsObject): # Map points using painter's world transform so they are drawn with pixel-valued sizes pts = np.vstack([self.data['x'], self.data['y']]) pts = fn.transformCoordinates(p.transform(), pts) - pts = np.clip(pts, -2 ** 30, 2 ** 30) # prevent Qt segmentation fault. + pts = fn.clip_array(pts, -2 ** 30, 2 ** 30) # prevent Qt segmentation fault. p.resetTransform() if self.opts['useCache'] and self._exportOpts is False: diff --git a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py index 6725d78b..bdfa1bbd 100644 --- a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py +++ b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py @@ -666,7 +666,7 @@ class ViewBox(GraphicsWidget): def suggestPadding(self, axis): l = self.width() if axis==0 else self.height() if l > 0: - padding = np.clip(1./(l**0.5), 0.02, 0.1) + padding = fn.clip_scalar(1./(l**0.5), 0.02, 0.1) else: padding = 0.02 return padding diff --git a/pyqtgraph/imageview/ImageView.py b/pyqtgraph/imageview/ImageView.py index 3e0cb39b..c7f0b66d 100644 --- a/pyqtgraph/imageview/ImageView.py +++ b/pyqtgraph/imageview/ImageView.py @@ -17,10 +17,11 @@ from math import log10 import numpy as np from ..Qt import QtCore, QtGui, QT_LIB +from .. import functions as fn import importlib ui_template = importlib.import_module( f'.ImageViewTemplate_{QT_LIB.lower()}', package=__package__) - + from ..graphicsItems.ImageItem import * from ..graphicsItems.ROI import * from ..graphicsItems.LinearRegionItem import * @@ -513,7 +514,7 @@ class ImageView(QtGui.QWidget): def setCurrentIndex(self, ind): """Set the currently displayed frame index.""" - index = np.clip(ind, 0, self.getProcessedImage().shape[self.axes['t']]-1) + index = fn.clip_scalar(ind, 0, self.getProcessedImage().shape[self.axes['t']]-1) self.ignorePlaying = True # Implicitly call timeLineChanged self.timeLine.setValue(self.tVals[index]) diff --git a/pyqtgraph/opengl/GLViewWidget.py b/pyqtgraph/opengl/GLViewWidget.py index 6dcbf8b1..66daa134 100644 --- a/pyqtgraph/opengl/GLViewWidget.py +++ b/pyqtgraph/opengl/GLViewWidget.py @@ -344,7 +344,7 @@ class GLViewWidget(QtWidgets.QOpenGLWidget): self.opts['rotation'] = q else: # default euler rotation method self.opts['azimuth'] += azim - self.opts['elevation'] = np.clip(self.opts['elevation'] + elev, -90, 90) + self.opts['elevation'] = fn.clip_scalar(self.opts['elevation'] + elev, -90., 90.) self.update() def pan(self, dx, dy, dz, relative='global'): diff --git a/pyqtgraph/opengl/items/GLScatterPlotItem.py b/pyqtgraph/opengl/items/GLScatterPlotItem.py index 09e7ec2f..834ede0b 100644 --- a/pyqtgraph/opengl/items/GLScatterPlotItem.py +++ b/pyqtgraph/opengl/items/GLScatterPlotItem.py @@ -3,7 +3,7 @@ from OpenGL.GL import * from OpenGL.arrays import vbo from .. GLGraphicsItem import GLGraphicsItem from .. import shaders -from ...functions import clip_array +from ... import functions as fn from ...Qt import QtGui import numpy as np @@ -62,12 +62,12 @@ class GLScatterPlotItem(GLGraphicsItem): ## Generate texture for rendering points w = 64 - def fn(x,y): + def genTexture(x,y): r = np.hypot((x-(w-1)/2.), (y-(w-1)/2.)) - return 255 * (w/2. - clip_array(r, w/2.-1.0, w/2.)) + return 255 * (w / 2 - fn.clip_array(r, w / 2 - 1, w / 2)) pData = np.empty((w, w, 4)) pData[:] = 255 - pData[:,:,3] = np.fromfunction(fn, pData.shape[:2]) + pData[:,:,3] = np.fromfunction(genTexture, pData.shape[:2]) pData = pData.astype(np.ubyte) if getattr(self, "pointTexture", None) is None: diff --git a/pyqtgraph/parametertree/SystemSolver.py b/pyqtgraph/parametertree/SystemSolver.py index 71f051e6..de177a37 100644 --- a/pyqtgraph/parametertree/SystemSolver.py +++ b/pyqtgraph/parametertree/SystemSolver.py @@ -2,6 +2,7 @@ from collections import OrderedDict import numpy as np import copy from math import log2 +from .. import functions as fn class SystemSolver(object): @@ -391,7 +392,7 @@ if __name__ == '__main__': sh = self.shutter # this raises RuntimeError if shutter has not # been specified ap = 4.0 * (sh / (1./60.)) * (iso / 100.) * (2 ** exp) * (2 ** light) - ap = np.clip(ap, 2.0, 16.0) + ap = fn.clip_scalar(ap, 2.0, 16.0) except RuntimeError: # program mode; we can select a suitable shutter # value at the same time. diff --git a/pyqtgraph/widgets/ColorMapWidget.py b/pyqtgraph/widgets/ColorMapWidget.py index 5d1e5681..b37fb67c 100644 --- a/pyqtgraph/widgets/ColorMapWidget.py +++ b/pyqtgraph/widgets/ColorMapWidget.py @@ -161,7 +161,7 @@ class ColorMapParameter(ptree.types.GroupParameter): elif op == 'Set': colors[mask] = colors2[mask] - colors = np.clip(colors, 0, 1) + colors = fn.clip_array(colors, 0., 1.) if mode == 'byte': colors = (colors * 255).astype(np.ubyte) @@ -210,7 +210,7 @@ class RangeColorMapItem(ptree.types.SimpleParameter): def map(self, data): data = data[self.fieldName] - scaled = np.clip((data-self['Min']) / (self['Max']-self['Min']), 0, 1) + scaled = fn.clip_array((data-self['Min']) / (self['Max']-self['Min']), 0, 1) cmap = self.value() colors = cmap.map(scaled, mode='float') diff --git a/pyqtgraph/widgets/GraphicsView.py b/pyqtgraph/widgets/GraphicsView.py index 3054f0e7..56304f51 100644 --- a/pyqtgraph/widgets/GraphicsView.py +++ b/pyqtgraph/widgets/GraphicsView.py @@ -378,7 +378,7 @@ class GraphicsView(QtGui.QGraphicsView): return if ev.buttons() == QtCore.Qt.RightButton: - delta = Point(np.clip(delta[0], -50, 50), np.clip(-delta[1], -50, 50)) + delta = Point(fn.clip_scalar(delta[0], -50, 50), fn.clip_scalar(-delta[1], -50, 50)) scale = 1.01 ** delta self.scale(scale[0], scale[1], center=self.mapToScene(self.mousePressPos)) self.sigDeviceRangeChanged.emit(self, self.range)