merged many new features from ACQ4
This commit is contained in:
parent
0f0a9415af
commit
025f2e5575
@ -187,6 +187,7 @@ from .SRTTransform3D import SRTTransform3D
|
||||
from .functions import *
|
||||
from .graphicsWindows import *
|
||||
from .SignalProxy import *
|
||||
from .colormap import *
|
||||
from .ptime import time
|
||||
|
||||
|
||||
|
109
colormap.py
109
colormap.py
@ -3,6 +3,25 @@ import scipy.interpolate
|
||||
from pyqtgraph.Qt import QtGui, QtCore
|
||||
|
||||
class ColorMap(object):
|
||||
"""
|
||||
A ColorMap defines a relationship between a scalar value and a range of colors.
|
||||
ColorMaps are commonly used for false-coloring monochromatic images, coloring
|
||||
scatter-plot points, and coloring surface plots by height.
|
||||
|
||||
Each color map is defined by a set of colors, each corresponding to a
|
||||
particular scalar value. For example:
|
||||
|
||||
| 0.0 -> black
|
||||
| 0.2 -> red
|
||||
| 0.6 -> yellow
|
||||
| 1.0 -> white
|
||||
|
||||
The colors for intermediate values are determined by interpolating between
|
||||
the two nearest colors in either RGB or HSV color space.
|
||||
|
||||
To provide user-defined color mappings, see :class:`GradientWidget <pyqtgraph.GradientWidget>`.
|
||||
"""
|
||||
|
||||
|
||||
## color interpolation modes
|
||||
RGB = 1
|
||||
@ -54,7 +73,16 @@ class ColorMap(object):
|
||||
|
||||
def map(self, data, mode='byte'):
|
||||
"""
|
||||
Return an array of colors corresponding to the values in *data*.
|
||||
Data must be either a scalar position or an array (any shape) of positions.
|
||||
|
||||
The *mode* argument determines the type of data returned:
|
||||
|
||||
=========== ===============================================================
|
||||
byte (default) Values are returned as 0-255 unsigned bytes.
|
||||
float Values are returned as 0.0-1.0 floats.
|
||||
qcolor Values are returned as an array of QColor objects.
|
||||
=========== ===============================================================
|
||||
"""
|
||||
if isinstance(mode, basestring):
|
||||
mode = self.enumMap[mode.lower()]
|
||||
@ -80,16 +108,19 @@ class ColorMap(object):
|
||||
return interp
|
||||
|
||||
def mapToQColor(self, data):
|
||||
"""Convenience function; see :func:`map() <pyqtgraph.ColorMap.map>`."""
|
||||
return self.map(data, mode=self.QCOLOR)
|
||||
|
||||
def mapToByte(self, data):
|
||||
"""Convenience function; see :func:`map() <pyqtgraph.ColorMap.map>`."""
|
||||
return self.map(data, mode=self.BYTE)
|
||||
|
||||
def mapToFloat(self, data):
|
||||
"""Convenience function; see :func:`map() <pyqtgraph.ColorMap.map>`."""
|
||||
return self.map(data, mode=self.FLOAT)
|
||||
|
||||
def getGradient(self, p1=None, p2=None):
|
||||
"""Return a QLinearGradient object."""
|
||||
"""Return a QLinearGradient object spanning from QPoints p1 to p2."""
|
||||
if p1 == None:
|
||||
p1 = QtCore.QPointF(0,0)
|
||||
if p2 == None:
|
||||
@ -119,7 +150,7 @@ class ColorMap(object):
|
||||
return g
|
||||
|
||||
def getColors(self, mode=None):
|
||||
"""Return list of all colors converted to the specified mode.
|
||||
"""Return list of all color stops converted to the specified mode.
|
||||
If mode is None, then no conversion is done."""
|
||||
if isinstance(mode, basestring):
|
||||
mode = self.enumMap[mode.lower()]
|
||||
@ -158,75 +189,19 @@ class ColorMap(object):
|
||||
self.stopsCache[mode] = (self.pos, color)
|
||||
return self.stopsCache[mode]
|
||||
|
||||
#def getColor(self, x, toQColor=True):
|
||||
#"""
|
||||
#Return a color for a given value.
|
||||
|
||||
#============= ==================================================================
|
||||
#**Arguments**
|
||||
#x Value (position on gradient) of requested color.
|
||||
#toQColor If true, returns a QColor object, else returns a (r,g,b,a) tuple.
|
||||
#============= ==================================================================
|
||||
#"""
|
||||
#ticks = self.listTicks()
|
||||
#if x <= ticks[0][1]:
|
||||
#c = ticks[0][0].color
|
||||
#if toQColor:
|
||||
#return QtGui.QColor(c) # always copy colors before handing them out
|
||||
#else:
|
||||
#return (c.red(), c.green(), c.blue(), c.alpha())
|
||||
#if x >= ticks[-1][1]:
|
||||
#c = ticks[-1][0].color
|
||||
#if toQColor:
|
||||
#return QtGui.QColor(c) # always copy colors before handing them out
|
||||
#else:
|
||||
#return (c.red(), c.green(), c.blue(), c.alpha())
|
||||
|
||||
#x2 = ticks[0][1]
|
||||
#for i in range(1,len(ticks)):
|
||||
#x1 = x2
|
||||
#x2 = ticks[i][1]
|
||||
#if x1 <= x and x2 >= x:
|
||||
#break
|
||||
|
||||
#dx = (x2-x1)
|
||||
#if dx == 0:
|
||||
#f = 0.
|
||||
#else:
|
||||
#f = (x-x1) / dx
|
||||
#c1 = ticks[i-1][0].color
|
||||
#c2 = ticks[i][0].color
|
||||
#if self.colorMode == 'rgb':
|
||||
#r = c1.red() * (1.-f) + c2.red() * f
|
||||
#g = c1.green() * (1.-f) + c2.green() * f
|
||||
#b = c1.blue() * (1.-f) + c2.blue() * f
|
||||
#a = c1.alpha() * (1.-f) + c2.alpha() * f
|
||||
#if toQColor:
|
||||
#return QtGui.QColor(int(r), int(g), int(b), int(a))
|
||||
#else:
|
||||
#return (r,g,b,a)
|
||||
#elif self.colorMode == 'hsv':
|
||||
#h1,s1,v1,_ = c1.getHsv()
|
||||
#h2,s2,v2,_ = c2.getHsv()
|
||||
#h = h1 * (1.-f) + h2 * f
|
||||
#s = s1 * (1.-f) + s2 * f
|
||||
#v = v1 * (1.-f) + v2 * f
|
||||
#c = QtGui.QColor()
|
||||
#c.setHsv(h,s,v)
|
||||
#if toQColor:
|
||||
#return c
|
||||
#else:
|
||||
#return (c.red(), c.green(), c.blue(), c.alpha())
|
||||
|
||||
def getLookupTable(self, start=0.0, stop=1.0, nPts=512, alpha=None, mode='byte'):
|
||||
"""
|
||||
Return an RGB(A) lookup table (ndarray).
|
||||
|
||||
============= ============================================================================
|
||||
**Arguments**
|
||||
nPts The number of points in the returned lookup table.
|
||||
alpha True, False, or None - Specifies whether or not alpha values are included
|
||||
in the table. If alpha is None, it will be automatically determined.
|
||||
start The starting value in the lookup table (default=0.0)
|
||||
stop The final value in the lookup table (default=1.0)
|
||||
nPts The number of points in the returned lookup table.
|
||||
alpha True, False, or None - Specifies whether or not alpha values are included
|
||||
in the table. If alpha is None, it will be automatically determined.
|
||||
mode Determines return type: 'byte' (0-255), 'float' (0.0-1.0), or 'qcolor'.
|
||||
See :func:`map() <pyqtgraph.ColorMap.map>`.
|
||||
============= ============================================================================
|
||||
"""
|
||||
if isinstance(mode, basestring):
|
||||
@ -249,7 +224,9 @@ class ColorMap(object):
|
||||
return np.any(self.color[:,3] != max)
|
||||
|
||||
def isMapTrivial(self):
|
||||
"""Return True if the gradient has exactly two stops in it: black at 0.0 and white at 1.0"""
|
||||
"""
|
||||
Return True if the gradient has exactly two stops in it: black at 0.0 and white at 1.0.
|
||||
"""
|
||||
if len(self.pos) != 2:
|
||||
return False
|
||||
if self.pos[0] != 0.0 or self.pos[1] != 1.0:
|
||||
|
@ -566,8 +566,8 @@ def transformCoordinates(tr, coords, transpose=False):
|
||||
|
||||
def solve3DTransform(points1, points2):
|
||||
"""
|
||||
Find a 3D transformation matrix that maps points1 onto points2
|
||||
points must be specified as a list of 4 Vectors.
|
||||
Find a 3D transformation matrix that maps points1 onto points2.
|
||||
Points must be specified as a list of 4 Vectors.
|
||||
"""
|
||||
if not HAVE_SCIPY:
|
||||
raise Exception("This function depends on the scipy library, but it does not appear to be importable.")
|
||||
@ -583,8 +583,8 @@ def solve3DTransform(points1, points2):
|
||||
|
||||
def solveBilinearTransform(points1, points2):
|
||||
"""
|
||||
Find a bilinear transformation matrix (2x4) that maps points1 onto points2
|
||||
points must be specified as a list of 4 Vector, Point, QPointF, etc.
|
||||
Find a bilinear transformation matrix (2x4) that maps points1 onto points2.
|
||||
Points must be specified as a list of 4 Vector, Point, QPointF, etc.
|
||||
|
||||
To use this matrix to map a point [x,y]::
|
||||
|
||||
|
@ -8,8 +8,9 @@ __all__ = ['GraphItem']
|
||||
|
||||
|
||||
class GraphItem(GraphicsObject):
|
||||
"""A GraphItem displays graph information (as in 'graph theory', not 'graphics') as
|
||||
a set of nodes connected by lines.
|
||||
"""A GraphItem displays graph information as
|
||||
a set of nodes connected by lines (as in 'graph theory', not 'graphics').
|
||||
Useful for drawing networks, trees, etc.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwds):
|
||||
@ -28,19 +29,24 @@ class GraphItem(GraphicsObject):
|
||||
|
||||
============ =========================================================
|
||||
Arguments
|
||||
pos (N,2) array of the positions of each node in the graph
|
||||
pos (N,2) array of the positions of each node in the graph.
|
||||
adj (M,2) array of connection data. Each row contains indexes
|
||||
of two nodes that are connected.
|
||||
pen The pen to use when drawing lines between connected
|
||||
nodes. May be one of:
|
||||
|
||||
* QPen
|
||||
* a single argument to pass to pg.mkPen
|
||||
* a record array of length M
|
||||
with fields (red, green, blue, alpha, width).
|
||||
with fields (red, green, blue, alpha, width). Note
|
||||
that using this option may have a significant performance
|
||||
cost.
|
||||
* None (to disable connection drawing)
|
||||
* 'default' to use the default foreground color.
|
||||
|
||||
symbolPen The pen used for drawing nodes.
|
||||
**opts All other keyword arguments are given to ScatterPlotItem
|
||||
``**opts`` All other keyword arguments are given to
|
||||
:func:`ScatterPlotItem.setData() <pyqtgraph.ScatterPlotItem.setData>`
|
||||
to affect the appearance of nodes (symbol, size, brush,
|
||||
etc.)
|
||||
============ =========================================================
|
||||
|
@ -14,10 +14,20 @@ class WidgetParameterItem(ParameterItem):
|
||||
"""
|
||||
ParameterTree item with:
|
||||
|
||||
- label in second column for displaying value
|
||||
- simple widget for editing value (displayed instead of label when item is selected)
|
||||
- button that resets value to default
|
||||
- provides SpinBox, CheckBox, LineEdit, and ColorButton types
|
||||
* label in second column for displaying value
|
||||
* simple widget for editing value (displayed instead of label when item is selected)
|
||||
* button that resets value to default
|
||||
|
||||
================= =============================================================
|
||||
Registered Types:
|
||||
int Displays a :class:`SpinBox <pyqtgraph.SpinBox>` in integer
|
||||
mode.
|
||||
float Displays a :class:`SpinBox <pyqtgraph.SpinBox>`.
|
||||
bool Displays a QCheckBox
|
||||
str Displays a QLineEdit
|
||||
color Displays a :class:`ColorButton <pyqtgraph.ColorButton>`
|
||||
colormap Displays a :class:`GradientWidget <pyqtgraph.GradientWidget>`
|
||||
================= =============================================================
|
||||
|
||||
This class can be subclassed by overriding makeWidget() to provide a custom widget.
|
||||
"""
|
||||
|
@ -9,9 +9,14 @@ __all__ = ['ColorMapWidget']
|
||||
class ColorMapWidget(ptree.ParameterTree):
|
||||
"""
|
||||
This class provides a widget allowing the user to customize color mapping
|
||||
for multi-column data.
|
||||
"""
|
||||
for multi-column data. Given a list of field names, the user may specify
|
||||
multiple criteria for assigning colors to each record in a numpy record array.
|
||||
Multiple criteria are evaluated and combined into a single color for each
|
||||
record by user-defined compositing methods.
|
||||
|
||||
For simpler color mapping using a single gradient editor, see
|
||||
:class:`GradientWidget <pyqtgraph.GradientWidget>`
|
||||
"""
|
||||
sigColorMapChanged = QtCore.Signal(object)
|
||||
|
||||
def __init__(self):
|
||||
@ -51,6 +56,25 @@ class ColorMapParameter(ptree.types.GroupParameter):
|
||||
return self.fields.keys()
|
||||
|
||||
def setFields(self, fields):
|
||||
"""
|
||||
Set the list of fields to be used by the mapper.
|
||||
|
||||
The format of *fields* is::
|
||||
|
||||
[ (fieldName, {options}), ... ]
|
||||
|
||||
============== ============================================================
|
||||
Field Options:
|
||||
mode Either 'range' or 'enum' (default is range). For 'range',
|
||||
The user may specify a gradient of colors to be applied
|
||||
linearly across a specific range of values. For 'enum',
|
||||
the user specifies a single color for each unique value
|
||||
(see *values* option).
|
||||
units String indicating the units of the data for this field.
|
||||
values List of unique values for which the user may assign a
|
||||
color when mode=='enum'.
|
||||
============== ============================================================
|
||||
"""
|
||||
self.fields = OrderedDict(fields)
|
||||
#self.fields = fields
|
||||
#self.fields.sort()
|
||||
@ -58,6 +82,18 @@ class ColorMapParameter(ptree.types.GroupParameter):
|
||||
self.setAddList(names)
|
||||
|
||||
def map(self, data, mode='byte'):
|
||||
"""
|
||||
Return an array of colors corresponding to *data*.
|
||||
|
||||
========= =================================================================
|
||||
Arguments
|
||||
data A numpy record array where the fields in data.dtype match those
|
||||
defined by a prior call to setFields().
|
||||
mode Either 'byte' or 'float'. For 'byte', the method returns an array
|
||||
of dtype ubyte with values scaled 0-255. For 'float', colors are
|
||||
returned as 0.0-1.0 float values.
|
||||
========= =================================================================
|
||||
"""
|
||||
colors = np.zeros((len(data),4))
|
||||
for item in self.children():
|
||||
if not item['Enabled']:
|
||||
|
@ -9,11 +9,27 @@ __all__ = ['TickSlider', 'GradientWidget', 'BlackWhiteSlider']
|
||||
|
||||
|
||||
class GradientWidget(GraphicsView):
|
||||
|
||||
"""
|
||||
Widget displaying an editable color gradient. The user may add, move, recolor,
|
||||
or remove colors from the gradient. Additionally, a context menu allows the
|
||||
user to select from pre-defined gradients.
|
||||
"""
|
||||
sigGradientChanged = QtCore.Signal(object)
|
||||
sigGradientChangeFinished = QtCore.Signal(object)
|
||||
|
||||
def __init__(self, parent=None, orientation='bottom', *args, **kargs):
|
||||
"""
|
||||
The *orientation* argument may be 'bottom', 'top', 'left', or 'right'
|
||||
indicating whether the gradient is displayed horizontally (top, bottom)
|
||||
or vertically (left, right) and on what side of the gradient the editable
|
||||
ticks will appear.
|
||||
|
||||
All other arguments are passed to
|
||||
:func:`GradientEditorItem.__init__ <pyqtgraph.GradientEditorItem.__init__>`.
|
||||
|
||||
Note: For convenience, this class wraps methods from
|
||||
:class:`GradientEditorItem <pyqtgraph.GradientEditorItem>`.
|
||||
"""
|
||||
GraphicsView.__init__(self, parent, useOpenGL=False, background=None)
|
||||
self.maxDim = 31
|
||||
kargs['tickPen'] = 'k'
|
||||
@ -32,6 +48,8 @@ class GradientWidget(GraphicsView):
|
||||
#self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent, True)
|
||||
|
||||
def setOrientation(self, ort):
|
||||
"""Set the orientation of the widget. May be one of 'bottom', 'top',
|
||||
'left', or 'right'."""
|
||||
self.item.setOrientation(ort)
|
||||
self.orientation = ort
|
||||
self.setMaxDim()
|
||||
|
@ -57,7 +57,9 @@ class ScatterPlotWidget(QtGui.QSplitter):
|
||||
def setFields(self, fields):
|
||||
"""
|
||||
Set the list of field names/units to be processed.
|
||||
Format is: [(name, units), ...]
|
||||
|
||||
The format of *fields* is the same as used by
|
||||
:func:`ColorMapWidget.setFields <pyqtgraph.widgets.ColorMapWidget.ColorMapParameter.setFields>`
|
||||
"""
|
||||
self.fields = OrderedDict(fields)
|
||||
self.fieldList.clear()
|
||||
|
Loading…
Reference in New Issue
Block a user