Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Benjamin Jakimow
EO Time Series Viewer
Commits
8c13a3e7
Commit
8c13a3e7
authored
Jul 03, 2013
by
Luke Campagnola
Browse files
copy from acq4
parent
008ca76d
Changes
19
Hide whitespace changes
Inline
Side-by-side
pyqtgraph/Point.py
View file @
8c13a3e7
...
...
@@ -80,6 +80,12 @@ class Point(QtCore.QPointF):
def
__div__
(
self
,
a
):
return
self
.
_math_
(
'__div__'
,
a
)
def
__truediv__
(
self
,
a
):
return
self
.
_math_
(
'__truediv__'
,
a
)
def
__rtruediv__
(
self
,
a
):
return
self
.
_math_
(
'__rtruediv__'
,
a
)
def
__rpow__
(
self
,
a
):
return
self
.
_math_
(
'__rpow__'
,
a
)
...
...
pyqtgraph/SRTTransform.py
View file @
8c13a3e7
...
...
@@ -130,11 +130,14 @@ class SRTTransform(QtGui.QTransform):
self
.
_state
[
'angle'
]
=
angle
self
.
update
()
def
__div__
(
self
,
t
):
def
__
true
div__
(
self
,
t
):
"""A / B == B^-1 * A"""
dt
=
t
.
inverted
()[
0
]
*
self
return
SRTTransform
(
dt
)
def
__div__
(
self
,
t
):
return
self
.
__truediv__
(
t
)
def
__mul__
(
self
,
t
):
return
SRTTransform
(
QtGui
.
QTransform
.
__mul__
(
self
,
t
))
...
...
pyqtgraph/SRTTransform3D.py
View file @
8c13a3e7
...
...
@@ -123,7 +123,6 @@ class SRTTransform3D(pg.Transform3D):
m
=
self
.
matrix
().
reshape
(
4
,
4
)
## translation is 4th column
self
.
_state
[
'pos'
]
=
m
[:
3
,
3
]
## scale is vector-length of first three columns
scale
=
(
m
[:
3
,:
3
]
**
2
).
sum
(
axis
=
0
)
**
0.5
## see whether there is an inversion
...
...
@@ -141,18 +140,30 @@ class SRTTransform3D(pg.Transform3D):
print
(
"Scale: %s"
%
str
(
scale
))
print
(
"Original matrix: %s"
%
str
(
m
))
raise
eigIndex
=
np
.
argwhere
(
np
.
abs
(
evals
-
1
)
<
1e-
7
)
eigIndex
=
np
.
argwhere
(
np
.
abs
(
evals
-
1
)
<
1e-
6
)
if
len
(
eigIndex
)
<
1
:
print
(
"eigenvalues: %s"
%
str
(
evals
))
print
(
"eigenvectors: %s"
%
str
(
evecs
))
print
(
"index: %s, %s"
%
(
str
(
eigIndex
),
str
(
evals
-
1
)))
raise
Exception
(
"Could not determine rotation axis."
)
axis
=
evecs
[
eigIndex
[
0
,
0
]].
real
axis
=
evecs
[
:,
eigIndex
[
0
,
0
]].
real
axis
/=
((
axis
**
2
).
sum
())
**
0.5
self
.
_state
[
'axis'
]
=
axis
## trace(r) == 2 cos(angle) + 1, so:
self
.
_state
[
'angle'
]
=
np
.
arccos
((
r
.
trace
()
-
1
)
*
0.5
)
*
180
/
np
.
pi
cos
=
(
r
.
trace
()
-
1
)
*
0.5
## this only gets us abs(angle)
## The off-diagonal values can be used to correct the angle ambiguity,
## but we need to figure out which element to use:
axisInd
=
np
.
argmax
(
np
.
abs
(
axis
))
rInd
,
sign
=
[((
1
,
2
),
-
1
),
((
0
,
2
),
1
),
((
0
,
1
),
-
1
)][
axisInd
]
## Then we have r-r.T = sin(angle) * 2 * sign * axis[axisInd];
## solve for sin(angle)
sin
=
(
r
-
r
.
T
)[
rInd
]
/
(
2.
*
sign
*
axis
[
axisInd
])
## finally, we get the complete angle from arctan(sin/cos)
self
.
_state
[
'angle'
]
=
np
.
arctan2
(
sin
,
cos
)
*
180
/
np
.
pi
if
self
.
_state
[
'angle'
]
==
0
:
self
.
_state
[
'axis'
]
=
(
0
,
0
,
1
)
...
...
pyqtgraph/debug.py
View file @
8c13a3e7
...
...
@@ -28,6 +28,15 @@ def ftrace(func):
return
rv
return
w
def
warnOnException
(
func
):
"""Decorator which catches/ignores exceptions and prints a stack trace."""
def
w
(
*
args
,
**
kwds
):
try
:
func
(
*
args
,
**
kwds
)
except
:
printExc
(
'Ignored exception:'
)
return
w
def
getExc
(
indent
=
4
,
prefix
=
'| '
):
tb
=
traceback
.
format_exc
()
lines
=
[]
...
...
pyqtgraph/flowchart/library/Operators.py
View file @
8c13a3e7
...
...
@@ -24,7 +24,15 @@ class BinOpNode(Node):
})
def
process
(
self
,
**
args
):
fn
=
getattr
(
args
[
'A'
],
self
.
fn
)
if
isinstance
(
self
.
fn
,
tuple
):
for
name
in
self
.
fn
:
try
:
fn
=
getattr
(
args
[
'A'
],
name
)
break
except
AttributeError
:
pass
else
:
fn
=
getattr
(
args
[
'A'
],
self
.
fn
)
out
=
fn
(
args
[
'B'
])
if
out
is
NotImplemented
:
raise
Exception
(
"Operation %s not implemented between %s and %s"
%
(
fn
,
str
(
type
(
args
[
'A'
])),
str
(
type
(
args
[
'B'
]))))
...
...
@@ -60,5 +68,7 @@ class DivideNode(BinOpNode):
"""Returns A / B. Does not check input types."""
nodeName
=
'Divide'
def
__init__
(
self
,
name
):
BinOpNode
.
__init__
(
self
,
name
,
'__div__'
)
# try truediv first, followed by div
BinOpNode
.
__init__
(
self
,
name
,
(
'__truediv__'
,
'__div__'
))
pyqtgraph/functions.py
View file @
8c13a3e7
...
...
@@ -264,6 +264,7 @@ def mkPen(*args, **kargs):
color
=
kargs
.
get
(
'color'
,
None
)
width
=
kargs
.
get
(
'width'
,
1
)
style
=
kargs
.
get
(
'style'
,
None
)
dash
=
kargs
.
get
(
'dash'
,
None
)
cosmetic
=
kargs
.
get
(
'cosmetic'
,
True
)
hsv
=
kargs
.
get
(
'hsv'
,
None
)
...
...
@@ -291,6 +292,8 @@ def mkPen(*args, **kargs):
pen
.
setCosmetic
(
cosmetic
)
if
style
is
not
None
:
pen
.
setStyle
(
style
)
if
dash
is
not
None
:
pen
.
setDashPattern
(
dash
)
return
pen
def
hsvColor
(
hue
,
sat
=
1.0
,
val
=
1.0
,
alpha
=
1.0
):
...
...
@@ -1948,6 +1951,8 @@ def pseudoScatter(data, spacing=None, shuffle=True, bidir=False):
s2
=
spacing
**
2
yvals
=
np
.
empty
(
len
(
data
))
if
len
(
data
)
==
0
:
return
yvals
yvals
[
0
]
=
0
for
i
in
range
(
1
,
len
(
data
)):
x
=
data
[
i
]
# current x value to be placed
...
...
pyqtgraph/graphicsItems/AxisItem.py
View file @
8c13a3e7
...
...
@@ -42,12 +42,18 @@ class AxisItem(GraphicsWidget):
self
.
label
.
rotate
(
-
90
)
self
.
style
=
{
'tickTextOffset'
:
3
,
##
spacing between text and axis
'tickTextOffset'
:
(
5
,
2
),
## (horizontal, vertical)
spacing between text and axis
'tickTextWidth'
:
30
,
## space reserved for tick text
'tickTextHeight'
:
18
,
'autoExpandTextSpace'
:
True
,
## automatically expand text space if needed
'tickFont'
:
None
,
'stopAxisAtTick'
:
(
False
,
False
),
## whether axis is drawn to edge of box or to last tick
'textFillLimits'
:
[
## how much of the axis to fill up with tick text, maximally.
(
0
,
0.8
),
## never fill more than 80% of the axis
(
2
,
0.6
),
## If we already have 2 ticks with text, fill no more than 60% of the axis
(
4
,
0.4
),
## If we already have 4 ticks with text, fill no more than 40% of the axis
(
6
,
0.2
),
## If we already have 6 ticks with text, fill no more than 20% of the axis
]
}
self
.
textWidth
=
30
## Keeps track of maximum width / height of tick text
...
...
@@ -209,14 +215,14 @@ class AxisItem(GraphicsWidget):
## to accomodate.
if
self
.
orientation
in
[
'left'
,
'right'
]:
mx
=
max
(
self
.
textWidth
,
x
)
if
mx
>
self
.
textWidth
:
if
mx
>
self
.
textWidth
or
mx
<
self
.
textWidth
-
10
:
self
.
textWidth
=
mx
if
self
.
style
[
'autoExpandTextSpace'
]
is
True
:
self
.
setWidth
()
#return True ## size has changed
else
:
mx
=
max
(
self
.
textHeight
,
x
)
if
mx
>
self
.
textHeight
:
if
mx
>
self
.
textHeight
or
mx
<
self
.
textHeight
-
10
:
self
.
textHeight
=
mx
if
self
.
style
[
'autoExpandTextSpace'
]
is
True
:
self
.
setHeight
()
...
...
@@ -236,7 +242,7 @@ class AxisItem(GraphicsWidget):
h
=
self
.
textHeight
else
:
h
=
self
.
style
[
'tickTextHeight'
]
h
+=
max
(
0
,
self
.
tickLength
)
+
self
.
style
[
'tickTextOffset'
]
h
+=
max
(
0
,
self
.
tickLength
)
+
self
.
style
[
'tickTextOffset'
]
[
1
]
if
self
.
label
.
isVisible
():
h
+=
self
.
label
.
boundingRect
().
height
()
*
0.8
self
.
setMaximumHeight
(
h
)
...
...
@@ -252,7 +258,7 @@ class AxisItem(GraphicsWidget):
w
=
self
.
textWidth
else
:
w
=
self
.
style
[
'tickTextWidth'
]
w
+=
max
(
0
,
self
.
tickLength
)
+
self
.
style
[
'tickTextOffset'
]
w
+=
max
(
0
,
self
.
tickLength
)
+
self
.
style
[
'tickTextOffset'
]
[
0
]
if
self
.
label
.
isVisible
():
w
+=
self
.
label
.
boundingRect
().
height
()
*
0.8
## bounding rect is usually an overestimate
self
.
setMaximumWidth
(
w
)
...
...
@@ -430,7 +436,7 @@ class AxisItem(GraphicsWidget):
return
[]
## decide optimal minor tick spacing in pixels (this is just aesthetics)
pixelSpacing
=
np
.
log
(
size
+
10
)
*
5
pixelSpacing
=
size
/
np
.
log
(
size
)
optimalTickCount
=
max
(
2.
,
size
/
pixelSpacing
)
## optimal minor tick spacing
...
...
@@ -720,7 +726,7 @@ class AxisItem(GraphicsWidget):
textOffset
=
self
.
style
[
'tickTextOffset'
]
## spacing between axis and text
textOffset
=
self
.
style
[
'tickTextOffset'
]
[
axis
]
## spacing between axis and text
#if self.style['autoExpandTextSpace'] is True:
#textWidth = self.textWidth
#textHeight = self.textHeight
...
...
@@ -728,7 +734,7 @@ class AxisItem(GraphicsWidget):
#textWidth = self.style['tickTextWidth'] ## space allocated for horizontal text
#textHeight = self.style['tickTextHeight'] ## space allocated for horizontal text
textSize2
=
0
textRects
=
[]
textSpecs
=
[]
## list of draw
for
i
in
range
(
len
(
tickLevels
)):
...
...
@@ -770,9 +776,16 @@ class AxisItem(GraphicsWidget):
textSize
=
np
.
sum
([
r
.
width
()
for
r
in
textRects
])
textSize2
=
np
.
max
([
r
.
height
()
for
r
in
textRects
])
## If the strings are too crowded, stop drawing text now
## If the strings are too crowded, stop drawing text now.
## We use three different crowding limits based on the number
## of texts drawn so far.
textFillRatio
=
float
(
textSize
)
/
lengthInPixels
if
textFillRatio
>
0.7
:
finished
=
False
for
nTexts
,
limit
in
self
.
style
[
'textFillLimits'
]:
if
len
(
textSpecs
)
>=
nTexts
and
textFillRatio
>=
limit
:
finished
=
True
break
if
finished
:
break
#spacing, values = tickLevels[best]
...
...
pyqtgraph/graphicsItems/GraphicsItem.py
View file @
8c13a3e7
...
...
@@ -533,6 +533,7 @@ class GraphicsItem(object):
def
viewTransformChanged
(
self
):
"""
Called whenever the transformation matrix of the view has changed.
(eg, the view range has changed or the view was resized)
"""
pass
...
...
pyqtgraph/graphicsItems/PlotCurveItem.py
View file @
8c13a3e7
...
...
@@ -375,6 +375,7 @@ class PlotCurveItem(GraphicsObject):
return
QtGui
.
QPainterPath
()
return
self
.
path
@
pg
.
debug
.
warnOnException
## raising an exception here causes crash
def
paint
(
self
,
p
,
opt
,
widget
):
prof
=
debug
.
Profiler
(
'PlotCurveItem.paint '
+
str
(
id
(
self
)),
disabled
=
True
)
if
self
.
xData
is
None
:
...
...
pyqtgraph/graphicsItems/PlotDataItem.py
View file @
8c13a3e7
...
...
@@ -84,24 +84,28 @@ class PlotDataItem(GraphicsObject):
**Optimization keyword arguments:**
============ =====================================================================
antialias (bool) By default, antialiasing is disabled to improve performance.
Note that in some cases (in particluar, when pxMode=True), points
will be rendered antialiased even if this is set to False.
decimate (int) Sub-sample data by selecting every nth sample before plotting
onlyVisible (bool) If True, only plot data that is visible within the X range of
the containing ViewBox. This can improve performance when plotting
very large data sets where only a fraction of the data is visible
at any time.
autoResample (bool) If True, resample the data before plotting to avoid plotting
multiple line segments per pixel. This can improve performance when
viewing very high-density data, but increases the initial overhead
and memory usage.
sampleRate (float) The sample rate of the data along the X axis (for data with
a fixed sample rate). Providing this value improves performance of
the *onlyVisible* and *autoResample* options.
identical *deprecated*
============ =====================================================================
================ =====================================================================
antialias (bool) By default, antialiasing is disabled to improve performance.
Note that in some cases (in particluar, when pxMode=True), points
will be rendered antialiased even if this is set to False.
decimate deprecated.
downsample (int) Reduce the number of samples displayed by this value
downsampleMethod 'subsample': Downsample by taking the first of N samples.
This method is fastest and least accurate.
'mean': Downsample by taking the mean of N samples.
'peak': Downsample by drawing a saw wave that follows the min
and max of the original data. This method produces the best
visual representation of the data but is slower.
autoDownsample (bool) If True, resample the data before plotting to avoid plotting
multiple line segments per pixel. This can improve performance when
viewing very high-density data, but increases the initial overhead
and memory usage.
clipToView (bool) If True, only plot data that is visible within the X range of
the containing ViewBox. This can improve performance when plotting
very large data sets where only a fraction of the data is visible
at any time.
identical *deprecated*
================ =====================================================================
**Meta-info keyword arguments:**
...
...
@@ -131,7 +135,6 @@ class PlotDataItem(GraphicsObject):
self
.
opts
=
{
'fftMode'
:
False
,
'logMode'
:
[
False
,
False
],
'downsample'
:
False
,
'alphaHint'
:
1.0
,
'alphaMode'
:
False
,
...
...
@@ -149,6 +152,11 @@ class PlotDataItem(GraphicsObject):
'antialias'
:
pg
.
getConfigOption
(
'antialias'
),
'pointMode'
:
None
,
'downsample'
:
1
,
'autoDownsample'
:
False
,
'downsampleMethod'
:
'peak'
,
'clipToView'
:
False
,
'data'
:
None
,
}
self
.
setData
(
*
args
,
**
kargs
)
...
...
@@ -175,6 +183,7 @@ class PlotDataItem(GraphicsObject):
return
self
.
opts
[
'fftMode'
]
=
mode
self
.
xDisp
=
self
.
yDisp
=
None
self
.
xClean
=
self
.
yClean
=
None
self
.
updateItems
()
self
.
informViewBoundsChanged
()
...
...
@@ -183,6 +192,7 @@ class PlotDataItem(GraphicsObject):
return
self
.
opts
[
'logMode'
]
=
[
xMode
,
yMode
]
self
.
xDisp
=
self
.
yDisp
=
None
self
.
xClean
=
self
.
yClean
=
None
self
.
updateItems
()
self
.
informViewBoundsChanged
()
...
...
@@ -269,13 +279,51 @@ class PlotDataItem(GraphicsObject):
#self.scatter.setSymbolSize(symbolSize)
self
.
updateItems
()
def
setDownsampling
(
self
,
ds
):
if
self
.
opts
[
'downsample'
]
==
ds
:
def
setDownsampling
(
self
,
ds
=
None
,
auto
=
None
,
method
=
None
):
"""
Set the downsampling mode of this item. Downsampling reduces the number
of samples drawn to increase performance.
=========== =================================================================
Arguments
ds (int) Reduce visible plot samples by this factor. To disable,
set ds=1.
auto (bool) If True, automatically pick *ds* based on visible range
mode 'subsample': Downsample by taking the first of N samples.
This method is fastest and least accurate.
'mean': Downsample by taking the mean of N samples.
'peak': Downsample by drawing a saw wave that follows the min
and max of the original data. This method produces the best
visual representation of the data but is slower.
=========== =================================================================
"""
changed
=
False
if
ds
is
not
None
:
if
self
.
opts
[
'downsample'
]
!=
ds
:
changed
=
True
self
.
opts
[
'downsample'
]
=
ds
if
auto
is
not
None
and
self
.
opts
[
'autoDownsample'
]
!=
auto
:
self
.
opts
[
'autoDownsample'
]
=
auto
changed
=
True
if
method
is
not
None
:
if
self
.
opts
[
'downsampleMethod'
]
!=
method
:
changed
=
True
self
.
opts
[
'downsampleMethod'
]
=
method
if
changed
:
self
.
xDisp
=
self
.
yDisp
=
None
self
.
updateItems
()
def
setClipToView
(
self
,
clip
):
if
self
.
opts
[
'clipToView'
]
==
clip
:
return
self
.
opts
[
'
downsample
'
]
=
ds
self
.
opts
[
'
clipToView
'
]
=
clip
self
.
xDisp
=
self
.
yDisp
=
None
self
.
updateItems
()
def
setData
(
self
,
*
args
,
**
kargs
):
"""
Clear any data displayed by this item and display new data.
...
...
@@ -315,7 +363,7 @@ class PlotDataItem(GraphicsObject):
raise
Exception
(
'Invalid data type %s'
%
type
(
data
))
elif
len
(
args
)
==
2
:
seq
=
(
'listOfValues'
,
'MetaArray'
)
seq
=
(
'listOfValues'
,
'MetaArray'
,
'empty'
)
if
dataType
(
args
[
0
])
not
in
seq
or
dataType
(
args
[
1
])
not
in
seq
:
raise
Exception
(
'When passing two unnamed arguments, both must be a list or array of values. (got %s, %s)'
%
(
str
(
type
(
args
[
0
])),
str
(
type
(
args
[
1
]))))
if
not
isinstance
(
args
[
0
],
np
.
ndarray
):
...
...
@@ -376,6 +424,7 @@ class PlotDataItem(GraphicsObject):
self
.
xData
=
x
.
view
(
np
.
ndarray
)
## one last check to make sure there are no MetaArrays getting by
self
.
yData
=
y
.
view
(
np
.
ndarray
)
self
.
xClean
=
self
.
yClean
=
None
self
.
xDisp
=
None
self
.
yDisp
=
None
prof
.
mark
(
'set data'
)
...
...
@@ -423,23 +472,28 @@ class PlotDataItem(GraphicsObject):
def
getData
(
self
):
if
self
.
xData
is
None
:
return
(
None
,
None
)
if
self
.
xDisp
is
None
:
if
self
.
xClean
is
None
:
nanMask
=
np
.
isnan
(
self
.
xData
)
|
np
.
isnan
(
self
.
yData
)
|
np
.
isinf
(
self
.
xData
)
|
np
.
isinf
(
self
.
yData
)
if
any
(
nanMask
):
self
.
dataMask
=
~
nanMask
x
=
self
.
xData
[
self
.
dataMask
]
y
=
self
.
yData
[
self
.
dataMask
]
self
.
xClean
=
self
.
xData
[
self
.
dataMask
]
self
.
yClean
=
self
.
yData
[
self
.
dataMask
]
else
:
self
.
dataMask
=
None
x
=
self
.
xData
y
=
self
.
yData
self
.
xClean
=
self
.
xData
self
.
yClean
=
self
.
yData
ds
=
self
.
opts
[
'downsample'
]
if
ds
>
1
:
x
=
x
[::
ds
]
#y = resample(y[:len(x)*ds], len(x)) ## scipy.signal.resample causes nasty ringing
y
=
y
[::
ds
]
if
self
.
xDisp
is
None
:
x
=
self
.
xClean
y
=
self
.
yClean
#ds = self.opts['downsample']
#if isinstance(ds, int) and ds > 1:
#x = x[::ds]
##y = resample(y[:len(x)*ds], len(x)) ## scipy.signal.resample causes nasty ringing
#y = y[::ds]
if
self
.
opts
[
'fftMode'
]:
f
=
np
.
fft
.
fft
(
y
)
/
len
(
y
)
y
=
abs
(
f
[
1
:
len
(
f
)
/
2
])
...
...
@@ -457,6 +511,53 @@ class PlotDataItem(GraphicsObject):
y
=
y
[
self
.
dataMask
]
else
:
self
.
dataMask
=
None
ds
=
self
.
opts
[
'downsample'
]
if
not
isinstance
(
ds
,
int
):
ds
=
1
if
self
.
opts
[
'autoDownsample'
]:
# this option presumes that x-values have uniform spacing
range
=
self
.
viewRect
()
if
range
is
not
None
:
dx
=
float
(
x
[
-
1
]
-
x
[
0
])
/
(
len
(
x
)
-
1
)
x0
=
(
range
.
left
()
-
x
[
0
])
/
dx
x1
=
(
range
.
right
()
-
x
[
0
])
/
dx
width
=
self
.
getViewBox
().
width
()
ds
=
int
(
max
(
1
,
int
(
0.2
*
(
x1
-
x0
)
/
width
)))
## downsampling is expensive; delay until after clipping.
if
self
.
opts
[
'clipToView'
]:
# this option presumes that x-values have uniform spacing
range
=
self
.
viewRect
()
if
range
is
not
None
:
dx
=
float
(
x
[
-
1
]
-
x
[
0
])
/
(
len
(
x
)
-
1
)
# clip to visible region extended by downsampling value
x0
=
np
.
clip
(
int
((
range
.
left
()
-
x
[
0
])
/
dx
)
-
1
*
ds
,
0
,
len
(
x
)
-
1
)
x1
=
np
.
clip
(
int
((
range
.
right
()
-
x
[
0
])
/
dx
)
+
2
*
ds
,
0
,
len
(
x
)
-
1
)
x
=
x
[
x0
:
x1
]
y
=
y
[
x0
:
x1
]
if
ds
>
1
:
if
self
.
opts
[
'downsampleMethod'
]
==
'subsample'
:
x
=
x
[::
ds
]
y
=
y
[::
ds
]
elif
self
.
opts
[
'downsampleMethod'
]
==
'mean'
:
n
=
len
(
x
)
/
ds
x
=
x
[:
n
*
ds
:
ds
]
y
=
y
[:
n
*
ds
].
reshape
(
n
,
ds
).
mean
(
axis
=
1
)
elif
self
.
opts
[
'downsampleMethod'
]
==
'peak'
:
n
=
len
(
x
)
/
ds
x1
=
np
.
empty
((
n
,
2
))
x1
[:]
=
x
[:
n
*
ds
:
ds
,
np
.
newaxis
]
x
=
x1
.
reshape
(
n
*
2
)
y1
=
np
.
empty
((
n
,
2
))
y2
=
y
[:
n
*
ds
].
reshape
((
n
,
ds
))
y1
[:,
0
]
=
y2
.
max
(
axis
=
1
)
y1
[:,
1
]
=
y2
.
min
(
axis
=
1
)
y
=
y1
.
reshape
(
n
*
2
)
self
.
xDisp
=
x
self
.
yDisp
=
y
#print self.yDisp.shape, self.yDisp.min(), self.yDisp.max()
...
...
@@ -542,6 +643,8 @@ class PlotDataItem(GraphicsObject):
#self.scatters = []
self
.
xData
=
None
self
.
yData
=
None
self
.
xClean
=
None
self
.
yClean
=
None
self
.
xDisp
=
None
self
.
yDisp
=
None
self
.
curve
.
setData
([])
...
...
@@ -557,6 +660,14 @@ class PlotDataItem(GraphicsObject):
self
.
sigClicked
.
emit
(
self
)
self
.
sigPointsClicked
.
emit
(
self
,
points
)
def
viewRangeChanged
(
self
):
# view range has changed; re-plot if needed
if
self
.
opts
[
'clipToView'
]
or
self
.
opts
[
'autoDownsample'
]:
self
.
xDisp
=
self
.
yDisp
=
None
self
.
updateItems
()
def
dataType
(
obj
):
if
hasattr
(
obj
,
'__len__'
)
and
len
(
obj
)
==
0
:
...
...
pyqtgraph/graphicsItems/PlotItem/PlotItem.py
View file @
8c13a3e7
...
...
@@ -256,6 +256,11 @@ class PlotItem(GraphicsWidget):
c
.
logYCheck
.
toggled
.
connect
(
self
.
updateLogMode
)
c
.
downsampleSpin
.
valueChanged
.
connect
(
self
.
updateDownsampling
)
c
.
downsampleCheck
.
toggled
.
connect
(
self
.
updateDownsampling
)
c
.
autoDownsampleCheck
.
toggled
.
connect
(
self
.
updateDownsampling
)
c
.
subsampleRadio
.
toggled
.
connect
(
self
.
updateDownsampling
)
c
.
meanRadio
.
toggled
.
connect
(
self
.
updateDownsampling
)
c
.
clipToViewCheck
.
toggled
.
connect
(
self
.
updateDownsampling
)
self
.
ctrl
.
avgParamList
.
itemClicked
.
connect
(
self
.
avgParamListClicked
)
self
.
ctrl
.
averageGroup
.
toggled
.
connect
(
self
.
avgToggled
)
...
...
@@ -526,7 +531,8 @@ class PlotItem(GraphicsWidget):
(
alpha
,
auto
)
=
self
.
alphaState
()
item
.
setAlpha
(
alpha
,
auto
)
item
.
setFftMode
(
self
.
ctrl
.
fftCheck
.
isChecked
())
item
.
setDownsampling
(
self
.
downsampleMode
())
item
.
setDownsampling
(
*
self
.
downsampleMode
())
item
.
setClipToView
(
self
.
clipToViewMode
())
item
.
setPointMode
(
self
.
pointMode
())
## Hide older plots if needed
...
...
@@ -568,8 +574,8 @@ class PlotItem(GraphicsWidget):
:func:`InfiniteLine.__init__() <pyqtgraph.InfiniteLine.__init__>`.
Returns the item created.
"""
angle
=
0
if
x
is
None
else
90
pos
=
x
if
x
is
not
None
else
y
pos
=
kwds
.
get
(
'pos'
,
x
if
x
is
not
None
else
y
)
angle
=
kwds
.
get
(
'angle'
,
0
if
x
is
None
else
90
)
line
=
InfiniteLine
(
pos
,
angle
,
**
kwds
)
self
.
addItem
(
line
)
if
z
is
not
None
:
...
...
@@ -941,23 +947,81 @@ class PlotItem(GraphicsWidget):
self
.
enableAutoRange
()
self
.
recomputeAverages
()
def
setDownsampling
(
self
,
ds
=
None
,
auto
=
None
,
mode
=
None
):
"""Change the default downsampling mode for all PlotDataItems managed by this plot.
=========== =================================================================
Arguments
ds (int) Reduce visible plot samples by this factor, or
(bool) To enable/disable downsampling without changing the value.
auto (bool) If True, automatically pick *ds* based on visible range
mode 'subsample': Downsample by taking the first of N samples.
This method is fastest and least accurate.
'mean': Downsample by taking the mean of N samples.
'peak': Downsample by drawing a saw wave that follows the min
and max of the original data. This method produces the best
visual representation of the data but is slower.
=========== =================================================================
"""
if
ds
is
not
None
:
if
ds
is
False
:
self
.
ctrl
.
downsampleCheck
.
setChecked
(
False
)
elif
ds
is
True
:
self
.
ctrl
.
downsampleCheck
.
setChecked
(
True
)
else
:
self
.
ctrl
.
downsampleCheck
.
setChecked
(
True
)
self
.
ctrl
.
downsampleSpin
.
setValue
(
ds
)
if
auto
is
not
None
:
if
auto
and
ds
is
not
False
:
self
.
ctrl
.
downsampleCheck
.
setChecked
(
True
)
self
.
ctrl
.
autoDownsampleCheck
.
setChecked
(
auto
)
if
mode
is
not
None
: