Skip to content

Commit 0fe8048

Browse files
committed
added support for pixels or data min coords to the rectangle selector widget
svn path=/trunk/matplotlib/; revision=5769
1 parent b0c6111 commit 0fe8048

File tree

5 files changed

+60
-26
lines changed

5 files changed

+60
-26
lines changed

doc/faq/howto_faq.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,33 @@ Howto
66

77
.. contents::
88

9+
10+
.. _howto-findobj:
11+
12+
How do I find all the objects in my figure of a certain type?
13+
=============================================================
14+
15+
Every matplotlib artist (see :ref:`artist-tutorial`) has a method
16+
called :meth:`~matplotlib.artist.Artist.findobj` that can be used to
17+
recursively search the artist for any artists it may contain that meet
18+
some criteria (eg match all :class:`~matplotlib.lines.Line2D`
19+
instances or match some arbitrary filter function). For example, the
20+
following snippet finds every object in the figure which has a
21+
`set_color` property and makes the object blue::
22+
23+
def myfunc(x):
24+
return hasattr(x, 'set_color')
25+
26+
for o in fig.findobj(myfunc):
27+
o.set_color('blue')
28+
29+
You can also filter on class instances::
30+
31+
import matplotlib.text as text
32+
for o in fig.findobj(text.Text):
33+
o.set_fontstyle('italic')
34+
35+
936
.. _howto-transparent:
1037

1138
How do I save transparent figures?

examples/widgets/rectangle_selector.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ def line_select_callback(event1, event2):
2929

3030
# drawtype is 'box' or 'line' or 'none'
3131
LS = RectangleSelector(current_ax, line_select_callback,
32-
drawtype='box',useblit=True)
32+
drawtype='box',useblit=True,
33+
minspanx=5,minspany=5,spancoords='pixels')
3334
show()

lib/matplotlib/artist.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,9 @@ def set(self, **kwargs):
510510

511511
def findobj(self, match=None):
512512
"""
513+
pyplot signature:
514+
findobj(o=gcf(), match=None)
515+
513516
recursively find all :class:matplotlib.artist.Artist instances
514517
contained in self
515518
@@ -520,6 +523,8 @@ def findobj(self, match=None):
520523
- function with signature ``boolean = match(artist)`` used to filter matches
521524
522525
- class instance: eg Line2D. Only return artists of class type
526+
527+
.. plot:: ../mpl_examples/pylab_examples/findobj_demo.py
523528
"""
524529

525530
if match is None: # always return True

lib/matplotlib/pyplot.py

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from matplotlib.backend_bases import FigureCanvasBase
88
from matplotlib.image import imread as _imread
99
from matplotlib import rcParams, rcParamsDefault, get_backend
10-
from matplotlib.artist import getp, get
10+
from matplotlib.artist import getp, get, Artist
1111
from matplotlib.artist import setp as _setp
1212
from matplotlib.axes import Axes
1313
from matplotlib.projections import PolarAxes
@@ -41,25 +41,10 @@
4141

4242

4343
def findobj(o=None, match=None):
44-
"""
45-
recursively find all :class:matplotlib.artist.Artist instances
46-
contained in artist instance *p*. if *o* is None, use
47-
current figure
48-
49-
*match* can be
50-
51-
- None: return all objects contained in artist (including artist)
52-
53-
- function with signature ``boolean = match(artist)`` used to filter matches
54-
55-
- class instance: eg Line2D. Only return artists of class type
56-
57-
"""
58-
5944
if o is None:
6045
o = gcf()
6146
return o.findobj(match)
62-
47+
findobj.__doc__ = Artist.findobj.__doc__
6348

6449
def switch_backend(newbackend):
6550
"""

lib/matplotlib/widgets.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ class RectangleSelector:
979979
"""
980980
Select a min/max range of the x axes for a matplotlib Axes
981981
982-
Example usage:
982+
Example usage::
983983
984984
from matplotlib.widgets import RectangleSelector
985985
from pylab import *
@@ -1011,7 +1011,7 @@ def toggle_selector(event):
10111011
"""
10121012
def __init__(self, ax, onselect, drawtype='box',
10131013
minspanx=None, minspany=None, useblit=False,
1014-
lineprops=None, rectprops=None):
1014+
lineprops=None, rectprops=None, spancoords='data'):
10151015

10161016
"""
10171017
Create a selector in ax. When a selection is made, clear
@@ -1035,7 +1035,12 @@ def __init__(self, ax, onselect, drawtype='box',
10351035
10361036
Use type if you want the mouse to draw a line, a box or nothing
10371037
between click and actual position ny setting
1038+
10381039
drawtype = 'line', drawtype='box' or drawtype = 'none'.
1040+
1041+
spancoords is one of 'data' or 'pixels'. If 'data', minspanx
1042+
and minspanx will be interpreted in the same coordinates as
1043+
the x and ya axis, if 'pixels', they are in pixels
10391044
"""
10401045
self.ax = ax
10411046
self.visible = True
@@ -1072,6 +1077,10 @@ def __init__(self, ax, onselect, drawtype='box',
10721077
self.useblit = useblit
10731078
self.minspanx = minspanx
10741079
self.minspany = minspany
1080+
1081+
assert(spancoords in ('data', 'pixels'))
1082+
1083+
self.spancoords = spancoords
10751084
self.drawtype = drawtype
10761085
# will save the data (position at mouseclick)
10771086
self.eventpress = None
@@ -1125,14 +1134,21 @@ def release(self, event):
11251134
self.canvas.draw()
11261135
# release coordinates, button, ...
11271136
self.eventrelease = event
1128-
xmin, ymin = self.eventpress.xdata, self.eventpress.ydata
1129-
xmax, ymax = self.eventrelease.xdata, self.eventrelease.ydata
1130-
# calculate dimensions of box or line get values in the right
1131-
# order
1132-
if xmin>xmax: xmin, xmax = xmax, xmin
1133-
if ymin>ymax: ymin, ymax = ymax, ymin
1137+
1138+
if self.spancoords=='data':
1139+
xmin, ymin = self.eventpress.xdata, self.eventpress.ydata
1140+
xmax, ymax = self.eventrelease.xdata, self.eventrelease.ydata
1141+
# calculate dimensions of box or line get values in the right
1142+
# order
1143+
elif self.spancoords=='pixels':
1144+
xmin, ymin = self.eventpress.x, self.eventpress.y
1145+
xmax, ymax = self.eventrelease.x, self.eventrelease.y
1146+
else:
1147+
raise ValueError('spancoords must be "data" or "pixels"')
11341148

11351149

1150+
if xmin>xmax: xmin, xmax = xmax, xmin
1151+
if ymin>ymax: ymin, ymax = ymax, ymin
11361152

11371153
spanx = xmax - xmin
11381154
spany = ymax - ymin

0 commit comments

Comments
 (0)