Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1244c5a

Browse files
committed
added curosor props to ax
svn path=/trunk/matplotlib/; revision=1101
1 parent a93634d commit 1244c5a

10 files changed

Lines changed: 359 additions & 237 deletions

File tree

examples/coords_demo.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
ax.plot(t,s)
1313

1414

15-
1615
def on_move(event):
1716
# get the x and y pixel coords
1817
x, y = event.x, event.y

examples/errorbar_demo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
h = 2*f
1010

1111
figure(1)
12-
errorbar(t, s, e, fmt='o') # vertical symmetric
12+
#errorbar(t, s, e, fmt='o') # vertical symmetric
1313
#errorbar(t, s, None, f, fmt='o') # horizontal symmetric
1414
#errorbar(t, s, e, f, fmt='o') # both symmetric
15-
#errorbar(t, s, [e,g], [f,h], fmt='o') # both asymmetric
15+
errorbar(t, s, [e,g], [f,h], fmt='--o') # both asymmetric
1616
#errorbar(t, s, [e,g], f, fmt='o', ecolor='g') # both mixed
1717
#errorbar(t, s, e, [f,h], fmt='o') # both mixed
1818
#errorbar(t, s, [e,g], fmt='o') # vertical asymmetric

lib/matplotlib/artist.py

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import division
22
import sys
3+
from cbook import iterable, flatten
34
from transforms import identity_transform
45

56
## Note, matplotlib artists use the doc strings for set and get
@@ -174,3 +175,250 @@ def update_from(self, other):
174175
self._lod = other._lod
175176
self._label = other._label
176177

178+
179+
class ArtistInspector:
180+
"""
181+
A helper class to insect an Artist and return information about
182+
it's settable properties and their current values
183+
"""
184+
def __init__(self, o):
185+
"""
186+
Initialize the artist inspector with an artist or sequence of
187+
artists. Id a sequence is used, we assume it is a homogeneous
188+
sequence (all Artists are of the same type) and it is your
189+
responsibility to make sure this is so.
190+
"""
191+
if iterable(o): o = o[0]
192+
self.o = o
193+
self.aliasd = self.get_aliases()
194+
195+
def get_aliases(self):
196+
"""
197+
get a dict mapping fullname -> alias for each alias in o.
198+
Eg for lines: {'markerfacecolor': 'mfc',
199+
'linewidth' : 'lw',
200+
}
201+
"""
202+
names = [name for name in dir(self.o) if
203+
(name.startswith('set_') or name.startswith('get_'))
204+
and callable(getattr(self.o,name))]
205+
aliases = {}
206+
for name in names:
207+
func = getattr(self.o, name)
208+
if not self.is_alias(func): continue
209+
docstring = func.__doc__
210+
fullname = docstring[10:]
211+
aliases[fullname[4:]] = name[4:]
212+
return aliases
213+
214+
def get_valid_values(self, attr):
215+
"""
216+
get the legal arguments for the setter associated with attr
217+
218+
This is done by querying the doc string of the function set_attr
219+
for a line that begins with ACCEPTS:
220+
221+
Eg, for a line linestyle, return
222+
[ '-' | '--' | '-.' | ':' | 'steps' | 'None' ]
223+
"""
224+
225+
name = 'set_%s'%attr
226+
if not hasattr(self.o, name):
227+
raise AttributeError('%s has no function %s'%(self.o,name))
228+
func = getattr(self.o, name)
229+
230+
docstring = func.__doc__
231+
if docstring is None: return 'unknown'
232+
233+
if docstring.startswith('alias for '):
234+
return None
235+
for line in docstring.split('\n'):
236+
line = line.lstrip()
237+
if not line.startswith('ACCEPTS:'): continue
238+
return line[8:].strip()
239+
return 'unknown'
240+
241+
def get_setters(self):
242+
"""
243+
Get the attribute strings with setters for object h. Eg, for a line,
244+
return ['markerfacecolor', 'linewidth', ....]
245+
"""
246+
247+
setters = []
248+
for name in dir(self.o):
249+
if not name.startswith('set_'): continue
250+
o = getattr(self.o,name)
251+
if not callable(o): continue
252+
func = o
253+
if self.is_alias(func): continue
254+
setters.append(name[4:])
255+
return setters
256+
257+
def is_alias(self, o):
258+
'return true if method object o is an alias for another function'
259+
ds = o.__doc__
260+
if ds is None: return False
261+
return ds.startswith('alias for ')
262+
263+
def aliased_name(self, s):
264+
"""
265+
return 'PROPNAME or alias' if s has an alias, else return
266+
PROPNAME.
267+
268+
Eg for the line markerfacecolor property, which has an alias,
269+
return 'markerfacecolor or mfc' and for the transform
270+
property, which does not, return 'transform'
271+
"""
272+
if self.aliasd.has_key(s):
273+
return '%s or %s' % (s, self.aliasd[s])
274+
else: return s
275+
276+
def pprint_setters(self, prop=None):
277+
"""
278+
if prop is None, return a list of strings of all settable properies
279+
and their valid values
280+
281+
if prop is not None, it is a valid property name and that
282+
property will be returned as a string of property : valid
283+
values
284+
"""
285+
if prop is not None:
286+
accepts = self.get_valid_values(prop)
287+
return ' %s: %s' %(prop, accepts)
288+
289+
attrs = self.get_setters()
290+
attrs.sort()
291+
lines = []
292+
293+
for prop in attrs:
294+
accepts = self.get_valid_values(prop)
295+
name = self.aliased_name(prop)
296+
lines.append(' %s: %s' %(name, accepts))
297+
return lines
298+
299+
def pprint_getters(self):
300+
"""
301+
return the getters and actual values as list of strings'
302+
"""
303+
getters = [name for name in dir(self.o)
304+
if name.startswith('get_')
305+
and callable(getattr(self.o, name))]
306+
getters.sort()
307+
lines = []
308+
for name in getters:
309+
func = getattr(self.o, name)
310+
if self.is_alias(func): continue
311+
try: val = func()
312+
except: continue
313+
if hasattr(val, 'shape') and len(val)>6:
314+
s = str(val[:6]) + '...'
315+
else:
316+
s = str(val)
317+
name = self.aliased_name(name[4:])
318+
lines.append(' %s = %s' %(name, s))
319+
return lines
320+
321+
322+
def get(o, *args):
323+
"""
324+
Return the value of handle property s
325+
326+
h is an instance of a class, eg a Line2D or an Axes or Text.
327+
if s is 'somename', this function returns
328+
329+
o.get_somename()
330+
331+
get can be used to query all the gettable properties with get(o)
332+
Many properties have aliases for shorter typing, eg 'lw' is an
333+
alias for 'linewidth'. In the output, aliases and full property
334+
names will be listed as
335+
336+
property or alias = value
337+
338+
eg
339+
340+
linewidth or lw = 2
341+
"""
342+
343+
insp = ArtistInspector(o)
344+
345+
if len(args)==0:
346+
print '\n'.join(insp.pprint_getters())
347+
return
348+
349+
name = args[0]
350+
func = getattr(o, 'get_' + name)
351+
return func()
352+
353+
def set(h, *args, **kwargs):
354+
"""
355+
matlab(TM) and pylab allow you to use set and get to set and get
356+
object properties, as well as to do introspection on the object
357+
For example, to set the linestyle of a line to be dashed, you can do
358+
359+
>>> line, = plot([1,2,3])
360+
>>> set(line, linestyle='--')
361+
362+
If you want to know the valid types of arguments, you can provide the
363+
name of the property you want to set without a value
364+
365+
>>> set(line, 'linestyle')
366+
linestyle: [ '-' | '--' | '-.' | ':' | 'steps' | 'None' ]
367+
368+
If you want to see all the properties that can be set, and their
369+
possible values, you can do
370+
371+
372+
>>> set(line)
373+
... long output listing omitted'
374+
375+
set operates on a single instance or a list of instances. If you are
376+
in quey mode introspecting the possible values, only the first
377+
instance in the sequnce is used. When actually setting values, all
378+
the instances will be set. Eg, suppose you have a list of two lines,
379+
the following will make both lines thicker and red
380+
381+
>>> x = arange(0,1.0,0.01)
382+
>>> y1 = sin(2*pi*x)
383+
>>> y2 = sin(4*pi*x)
384+
>>> lines = plot(x, y1, x, y2)
385+
>>> set(lines, linewidth=2, color='r')
386+
387+
Set works with the matlab(TM) style string/value pairs or with python
388+
kwargs. For example, the following are equivalent
389+
390+
>>> set(lines, 'linewidth', 2, 'color', r') # matlab style
391+
>>> set(lines, linewidth=2, color='r') # python style
392+
"""
393+
394+
insp = ArtistInspector(h)
395+
396+
if len(kwargs)==0 and len(args)==0:
397+
print '\n'.join(insp.pprint_setters())
398+
return
399+
400+
if len(kwargs)==0 and len(args)==1:
401+
print insp.pprint_setters(prop=args[0])
402+
return
403+
404+
if not iterable(h): h = [h]
405+
else: h = flatten(h)
406+
407+
408+
if len(args)%2:
409+
raise ValueError('The set args must be string, value pairs')
410+
411+
funcvals = []
412+
for i in range(0, len(args)-1, 2):
413+
funcvals.append((args[i], args[i+1]))
414+
funcvals.extend(kwargs.items())
415+
416+
ret = []
417+
for o in h:
418+
for s, val in funcvals:
419+
s = s.lower()
420+
funcName = "set_%s"%s
421+
func = getattr(o,funcName)
422+
ret.extend( [func(val)] )
423+
return [x for x in flatten(ret)]
424+

lib/matplotlib/axes.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
from __future__ import division, generators
23

34
import math, sys
@@ -345,12 +346,36 @@ def __init__(self, fig, rect,
345346

346347
self._contourHelper = ContourSupport(self)
347348
self._contourLabeler = ContourLabeler(self)
349+
350+
self.set_cursor_props((1,'k')) # set the cursor properties for axes
348351

349352
def _init_axis(self):
350353
"move this out of __init__ because non-separable axes don't use it"
351354
self.xaxis = XAxis(self)
352355
self.yaxis = YAxis(self)
353356

357+
def set_cursor_props(self, *args):
358+
"""
359+
Set the cursor property as
360+
ax.set_cursor_props(linewidth, color) OR
361+
ax.set_cursor_props((linewidth, color))
362+
363+
ACCEPTS: a (float, color) tuple
364+
"""
365+
if len(args)==1:
366+
lw, c = args[0]
367+
elif len(args)==2:
368+
lw, c = args
369+
else:
370+
raise ValueError('args must be a (linewidth, color) tuple')
371+
c =colorConverter.to_rgba(c)
372+
self._cursorProps = lw, c
373+
374+
def get_cursor_props(self):
375+
"""return the cursor props as a linewidth, color tuple where
376+
linewidth is a float and color is an RGBA tuple"""
377+
return self._cursorProps
378+
354379
def set_figure(self, fig):
355380
"""
356381
Set the Axes figure
@@ -1597,7 +1622,7 @@ def grid(self, b=None):
15971622
self.xaxis.grid(b)
15981623
self.yaxis.grid(b)
15991624

1600-
def hist(self, x, bins=10, normed=0, bottom=0):
1625+
def hist(self, x, bins=10, normed=0, bottom=0, **kwargs):
16011626
"""
16021627
HIST(x, bins=10, normed=0, bottom=0)
16031628
@@ -1609,11 +1634,15 @@ def hist(self, x, bins=10, normed=0, bottom=0):
16091634
If normed is true, the first element of the return tuple will be the
16101635
counts normalized to form a probability distribtion, ie,
16111636
n/(len(x)*dbin)
1637+
1638+
kwargs are used to update the properties of the hist bars
16121639
"""
16131640
if not self._hold: self.cla()
16141641
n,bins = matplotlib.mlab.hist(x, bins, normed)
16151642
width = 0.9*(bins[1]-bins[0])
16161643
patches = self.bar(bins, n, width=width, bottom=bottom)
1644+
for p in patches:
1645+
p.update(kwargs)
16171646
return n, bins, silent_list('Patch', patches)
16181647

16191648
def hold(self, b=None):
@@ -2381,7 +2410,7 @@ def plot(self, *args, **kwargs):
23812410
for line in self._get_lines(*args, **kwargs):
23822411
self.add_line(line)
23832412
lines.append(line)
2384-
2413+
lines = [line for line in lines] # consume the generator
23852414
self.autoscale_view()
23862415
return lines
23872416

@@ -2500,7 +2529,10 @@ def psd(self, x, NFFT=256, Fs=2, detrend=detrend_none,
25002529
self.grid(True)
25012530
vmin, vmax = self.viewLim.intervaly().get_bounds()
25022531
intv = vmax-vmin
2503-
step = 10*int(log10(intv))
2532+
logi = int(log10(intv))
2533+
if logi==0: logi=.1
2534+
step = 10*logi
2535+
print vmin, vmax, step, intv, math.floor(vmin), math.ceil(vmax)+1
25042536
ticks = arange(math.floor(vmin), math.ceil(vmax)+1, step)
25052537
self.set_yticks(ticks)
25062538

lib/matplotlib/backend_bases.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ def __init__(self, figure):
695695
self._key = None # the key pressed
696696
self._lastx, self._lasty = None, None
697697

698+
698699
def key_press_event(self, key, guiEvent=None):
699700
self._key = key
700701
event = KeyEvent('key_press_event', self, key, self._lastx, self._lasty, guiEvent=guiEvent)
@@ -741,12 +742,19 @@ def motion_notify_event(self, x, y, guiEvent=None):
741742
for cid, func in self.callbacks.get('motion_notify_event', {}).items():
742743
func(event)
743744

744-
def draw(self):
745+
def draw(self, *args, **kwargs):
745746
"""
746747
Render the figure
747748
"""
748749
pass
749750

751+
def draw_cursor(self, event):
752+
"""
753+
Draw a cursor in the event.axes if inaxes is not None. Use
754+
native GUI drawing for efficiency if possible
755+
"""
756+
pass
757+
750758
def print_figure(self, filename, dpi=300, facecolor='w', edgecolor='w',
751759
orientation='portrait'):
752760
"""

0 commit comments

Comments
 (0)