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
33bc81a1
Commit
33bc81a1
authored
Apr 21, 2012
by
Luke Campagnola
Browse files
Fixed click signal propagation for PlotDataItem
parent
59ad54c5
Changes
3
Hide whitespace changes
Inline
Side-by-side
graphicsItems/PlotCurveItem.py
View file @
33bc81a1
...
...
@@ -12,17 +12,50 @@ __all__ = ['PlotCurveItem']
class
PlotCurveItem
(
GraphicsObject
):
"""Class representing a single plot curve. Provides:
- Fast data update
- FFT display mode
- shadow pen
- mouse interaction
"""
Class representing a single plot curve. Instances of this class are created
automatically as part of PlotDataItem; these rarely need to be instantiated
directly.
Features:
- Fast data update
- FFT display mode (accessed via PlotItem context menu)
- Fill under curve
- Mouse interaction
==================== ===============================================
**Signals:**
sigPlotChanged(self) Emitted when the data being plotted has changed
sigClicked(self) Emitted when the curve is clicked
==================== ===============================================
"""
sigPlotChanged
=
QtCore
.
Signal
(
object
)
sigClicked
=
QtCore
.
Signal
(
object
)
def
__init__
(
self
,
y
=
None
,
x
=
None
,
fillLevel
=
None
,
copy
=
False
,
pen
=
None
,
shadowPen
=
None
,
brush
=
None
,
parent
=
None
,
clickable
=
False
):
"""
============== =======================================================
**Arguments:**
x, y (numpy arrays) Data to show
pen Pen to use when drawing. Any single argument accepted by
:func:`mkPen <pyqtgraph.mkPen>` is allowed.
shadowPen Pen for drawing behind the primary pen. Usually this
is used to emphasize the curve by providing a
high-contrast border. Any single argument accepted by
:func:`mkPen <pyqtgraph.mkPen>` is allowed.
fillLevel (float or None) Fill the area 'under' the curve to
*fillLevel*
brush QBrush to use when filling. Any single argument accepted
by :func:`mkBrush <pyqtgraph.mkBrush>` is allowed.
clickable If True, the item will emit sigClicked when it is
clicked on.
============== =======================================================
"""
GraphicsObject
.
__init__
(
self
,
parent
)
self
.
clear
()
self
.
path
=
None
...
...
@@ -62,6 +95,7 @@ class PlotCurveItem(GraphicsObject):
return
interface
in
ints
def
setClickable
(
self
,
s
):
"""Sets whether the item responds to mouse clicks."""
self
.
clickable
=
s
...
...
@@ -127,18 +161,25 @@ class PlotCurveItem(GraphicsObject):
#return self.metaData
def
setPen
(
self
,
*
args
,
**
kargs
):
"""Set the pen used to draw the curve."""
self
.
opts
[
'pen'
]
=
fn
.
mkPen
(
*
args
,
**
kargs
)
self
.
update
()
def
setShadowPen
(
self
,
*
args
,
**
kargs
):
"""Set the shadow pen used to draw behind tyhe primary pen.
This pen must have a larger width than the primary
pen to be visible.
"""
self
.
opts
[
'shadowPen'
]
=
fn
.
mkPen
(
*
args
,
**
kargs
)
self
.
update
()
def
setBrush
(
self
,
*
args
,
**
kargs
):
"""Set the brush used when filling the area under the curve"""
self
.
opts
[
'brush'
]
=
fn
.
mkBrush
(
*
args
,
**
kargs
)
self
.
update
()
def
setFillLevel
(
self
,
level
):
"""Set the level filled to when filling under the curve"""
self
.
opts
[
'fillLevel'
]
=
level
self
.
fillPath
=
None
self
.
update
()
...
...
@@ -177,7 +218,9 @@ class PlotCurveItem(GraphicsObject):
#self.update()
def
setData
(
self
,
*
args
,
**
kargs
):
"""Same as updateData()"""
"""
Accepts most of the same arguments as __init__.
"""
self
.
updateData
(
*
args
,
**
kargs
)
def
updateData
(
self
,
*
args
,
**
kargs
):
...
...
graphicsItems/PlotDataItem.py
View file @
33bc81a1
...
...
@@ -24,15 +24,18 @@ class PlotDataItem(GraphicsObject):
usually created by plot() methods such as :func:`pyqtgraph.plot` and
:func:`PlotItem.plot() <pyqtgraph.PlotItem.plot>`.
===================== ==============================================
=====================
=========
==============================================
**Signals:**
sigPlotChanged(self) Emitted when the data in this item is updated.
sigClicked(self) Emitted when the item is clicked.
===================== ==============================================
sigPlotChanged(self) Emitted when the data in this item is updated.
sigClicked(self) Emitted when the item is clicked.
sigPointsClicked(self, points) Emitted when a plot point is clicked
Sends the list of points under the mouse.
============================== ==============================================
"""
sigPlotChanged
=
QtCore
.
Signal
(
object
)
sigClicked
=
QtCore
.
Signal
(
object
)
sigPointsClicked
=
QtCore
.
Signal
(
object
,
object
)
def
__init__
(
self
,
*
args
,
**
kargs
):
"""
...
...
@@ -109,6 +112,10 @@ class PlotDataItem(GraphicsObject):
self
.
curve
.
setParentItem
(
self
)
self
.
scatter
.
setParentItem
(
self
)
self
.
curve
.
sigClicked
.
connect
(
self
.
curveClicked
)
self
.
scatter
.
sigClicked
.
connect
(
self
.
scatterClicked
)
#self.clear()
self
.
opts
=
{
'fftMode'
:
False
,
...
...
@@ -127,6 +134,8 @@ class PlotDataItem(GraphicsObject):
'symbolPen'
:
(
200
,
200
,
200
),
'symbolBrush'
:
(
50
,
50
,
150
),
'identical'
:
False
,
'data'
:
None
,
}
self
.
setData
(
*
args
,
**
kargs
)
...
...
@@ -150,8 +159,8 @@ class PlotDataItem(GraphicsObject):
self
.
xDisp
=
self
.
yDisp
=
None
self
.
updateItems
()
def
setLogMode
(
self
,
m
ode
):
self
.
opts
[
'logMode'
]
=
mode
def
setLogMode
(
self
,
xMode
,
yM
ode
):
self
.
opts
[
'logMode'
]
=
(
xMode
,
yMode
)
self
.
xDisp
=
self
.
yDisp
=
None
self
.
updateItems
()
...
...
@@ -244,7 +253,7 @@ class PlotDataItem(GraphicsObject):
data
=
args
[
0
]
dt
=
dataType
(
data
)
if
dt
==
'empty'
:
return
pass
elif
dt
==
'listOfValues'
:
y
=
np
.
array
(
data
)
elif
dt
==
'Nx2array'
:
...
...
@@ -260,6 +269,8 @@ class PlotDataItem(GraphicsObject):
x
=
np
.
array
([
d
.
get
(
'x'
,
None
)
for
d
in
data
])
if
'y'
in
data
[
0
]:
y
=
np
.
array
([
d
.
get
(
'y'
,
None
)
for
d
in
data
])
for
k
in
[
'data'
,
'symbolSize'
,
'symbolPen'
,
'symbolBrush'
,
'symbolShape'
]:
kargs
[
k
]
=
[
d
.
get
(
k
,
None
)
for
d
in
data
]
elif
dt
==
'MetaArray'
:
y
=
data
.
view
(
np
.
ndarray
)
x
=
data
.
xvals
(
0
).
view
(
np
.
ndarray
)
...
...
@@ -349,8 +360,9 @@ class PlotDataItem(GraphicsObject):
curveArgs
[
v
]
=
self
.
opts
[
k
]
scatterArgs
=
{}
for
k
,
v
in
[(
'symbolPen'
,
'pen'
),
(
'symbolBrush'
,
'brush'
),
(
'symbol'
,
'symbol'
),
(
'symbolSize'
,
'size'
)]:
scatterArgs
[
v
]
=
self
.
opts
[
k
]
for
k
,
v
in
[(
'symbolPen'
,
'pen'
),
(
'symbolBrush'
,
'brush'
),
(
'symbol'
,
'symbol'
),
(
'symbolSize'
,
'size'
),
(
'data'
,
'data'
)]:
if
k
in
self
.
opts
:
scatterArgs
[
v
]
=
self
.
opts
[
k
]
x
,
y
=
self
.
getData
()
...
...
@@ -398,6 +410,11 @@ class PlotDataItem(GraphicsObject):
x
=
np
.
log10
(
x
)
if
self
.
opts
[
'logMode'
][
1
]:
y
=
np
.
log10
(
y
)
if
any
(
self
.
opts
[
'logMode'
]):
## re-check for NANs after log
nanMask
=
np
.
isinf
(
x
)
|
np
.
isinf
(
y
)
|
np
.
isnan
(
x
)
|
np
.
isnan
(
y
)
if
any
(
nanMask
):
x
=
x
[
~
nanMask
]
y
=
y
[
~
nanMask
]
self
.
xDisp
=
x
self
.
yDisp
=
y
#print self.yDisp.shape, self.yDisp.min(), self.yDisp.max()
...
...
@@ -438,6 +455,13 @@ class PlotDataItem(GraphicsObject):
def
appendData
(
self
,
*
args
,
**
kargs
):
pass
def
curveClicked
(
self
):
self
.
sigClicked
.
emit
(
self
)
def
scatterClicked
(
self
,
plt
,
points
):
self
.
sigClicked
.
emit
(
self
)
self
.
sigPointsClicked
.
emit
(
self
,
points
)
def
dataType
(
obj
):
if
hasattr
(
obj
,
'__len__'
)
and
len
(
obj
)
==
0
:
...
...
graphicsItems/ScatterPlotItem.py
View file @
33bc81a1
...
...
@@ -7,7 +7,23 @@ import scipy.stats
__all__
=
[
'ScatterPlotItem'
,
'SpotItem'
]
class
ScatterPlotItem
(
GraphicsObject
):
"""
Displays a set of x/y points. Instances of this class are created
automatically as part of PlotDataItem; these rarely need to be instantiated
directly.
The size, shape, pen, and fill brush may be set for each point individually
or for all points.
======================== ===============================================
**Signals:**
sigPlotChanged(self) Emitted when the data being plotted has changed
sigClicked(self, points) Emitted when the curve is clicked. Sends a list
of all the points under the mouse pointer.
======================== ===============================================
"""
#sigPointClicked = QtCore.Signal(object, object)
sigClicked
=
QtCore
.
Signal
(
object
,
object
)
## self, points
sigPlotChanged
=
QtCore
.
Signal
(
object
)
...
...
@@ -37,35 +53,37 @@ class ScatterPlotItem(GraphicsObject):
def
setData
(
self
,
*
args
,
**
kargs
):
"""
Ordered Arguments:
If there is only one unnamed argument, it will be interpreted like the 'spots' argument.
If there are two unnamed arguments, they will be interpreted as sequences of x and y values.
Keyword Arguments:
*spots*: Optional list of dicts. Each dict specifies parameters for a single spot:
{'pos': (x,y), 'size', 'pen', 'brush', 'symbol'}. This is just an alternate method
of passing in data for the corresponding arguments.
*x*,*y*: 1D arrays of x,y values.
*pos*: 2D structure of x,y pairs (such as Nx2 array or list of tuples)
*pxMode*: If True, spots are always the same size regardless of scaling, and size is given in px.
Otherwise, size is in scene coordinates and the spots scale with the view.
Default is True
*identical*: If True, all spots are forced to look identical.
This can result in performance enhancement.
Default is False
*symbol* can be one (or a list) of:
'o' circle (default)
's' square
't' triangle
'd' diamond
'+' plus
*pen*: The pen (or list of pens) to use for drawing spot outlines.
*brush*: The brush (or list of brushes) to use for filling spots.
*size*: The size (or list of sizes) of spots. If *pxMode* is True, this value is in pixels. Otherwise,
it is in the item's local coordinate system.
*data*: a list of python objects used to uniquely identify each spot.
**Ordered Arguments:**
* If there is only one unnamed argument, it will be interpreted like the 'spots' argument.
* If there are two unnamed arguments, they will be interpreted as sequences of x and y values.
====================== =================================================
**Keyword Arguments:**
*spots* Optional list of dicts. Each dict specifies parameters for a single spot:
{'pos': (x,y), 'size', 'pen', 'brush', 'symbol'}. This is just an alternate method
of passing in data for the corresponding arguments.
*x*,*y* 1D arrays of x,y values.
*pos* 2D structure of x,y pairs (such as Nx2 array or list of tuples)
*pxMode* If True, spots are always the same size regardless of scaling, and size is given in px.
Otherwise, size is in scene coordinates and the spots scale with the view.
Default is True
*identical* If True, all spots are forced to look identical.
This can result in performance enhancement.
Default is False
*symbol* can be one (or a list) of:
* 'o' circle (default)
* 's' square
* 't' triangle
* 'd' diamond
* '+' plus
*pen* The pen (or list of pens) to use for drawing spot outlines.
*brush* The brush (or list of brushes) to use for filling spots.
*size* The size (or list of sizes) of spots. If *pxMode* is True, this value is in pixels. Otherwise,
it is in the item's local coordinate system.
*data* a list of python objects used to uniquely identify each spot.
====================== =================================================
"""
self
.
clear
()
...
...
@@ -148,6 +166,9 @@ class ScatterPlotItem(GraphicsObject):
if
k
in
kargs
:
setMethod
=
getattr
(
self
,
'set'
+
k
[
0
].
upper
()
+
k
[
1
:])
setMethod
(
kargs
[
k
])
if
'data'
in
kargs
:
self
.
setPointData
(
kargs
[
'data'
])
self
.
updateSpots
()
...
...
@@ -183,7 +204,7 @@ class ScatterPlotItem(GraphicsObject):
#self.data[k].append(v)
def
setPoints
(
self
,
*
args
,
**
kargs
):
"""
Deprecated; use setData
"""
##
Deprecated; use setData
return
self
.
setData
(
*
args
,
**
kargs
)
#def setPoints(self, spots=None, x=None, y=None, data=None):
...
...
@@ -259,6 +280,16 @@ class ScatterPlotItem(GraphicsObject):
self
.
opts
[
'size'
]
=
size
self
.
updateSpots
()
def
setPointData
(
self
,
data
):
if
isinstance
(
data
,
np
.
ndarray
)
or
isinstance
(
data
,
list
):
if
self
.
data
is
None
:
raise
Exception
(
"Must set xy data before setting meta data."
)
if
len
(
data
)
!=
len
(
self
.
data
):
raise
Exception
(
"Length of meta data does not match number of points (%d != %d)"
%
(
len
(
data
),
len
(
self
.
data
)))
self
.
data
[
'data'
]
=
data
self
.
updateSpots
()
def
setIdentical
(
self
,
ident
):
self
.
opts
[
'identical'
]
=
ident
self
.
updateSpots
()
...
...
@@ -353,6 +384,12 @@ class ScatterPlotItem(GraphicsObject):
symbol
=
self
.
data
[
'symbol'
].
copy
()
symbol
[
symbol
==
''
]
=
self
.
opts
[
'symbol'
]
data
=
self
.
data
[
'data'
].
copy
()
if
'data'
in
self
.
opts
:
data
[
data
==
None
]
=
self
.
opts
[
'data'
]
for
i
in
xrange
(
len
(
self
.
data
)):
s
=
self
.
data
[
i
]
...
...
@@ -373,7 +410,7 @@ class ScatterPlotItem(GraphicsObject):
#ymn = min(ymn, pos[1]-psize)
#ymx = max(ymx, pos[1]+psize)
item
=
self
.
mkSpot
(
pos
,
size
[
i
],
self
.
opts
[
'pxMode'
],
brush
[
i
],
pen
[
i
],
s
[
'
data
'
],
symbol
=
symbol
[
i
],
index
=
len
(
self
.
spots
))
item
=
self
.
mkSpot
(
pos
,
size
[
i
],
self
.
opts
[
'pxMode'
],
brush
[
i
],
pen
[
i
],
data
[
i
],
symbol
=
symbol
[
i
],
index
=
len
(
self
.
spots
))
self
.
spots
.
append
(
item
)
self
.
data
[
i
][
'spot'
]
=
item
#if self.optimize:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment