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

Skip to content

Commit 2a6ae2f

Browse files
committed
Errorbar limit symbols patch by Manuel Metz
svn path=/trunk/matplotlib/; revision=3772
1 parent 3ff68f7 commit 2a6ae2f

3 files changed

Lines changed: 157 additions & 12 deletions

File tree

examples/errorbar_limits.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'''
2+
Illustration of upper and lower limit symbols on errorbars
3+
'''
4+
5+
from math import pi
6+
from numpy import array, arange, sin
7+
import pylab as P
8+
9+
fig = P.figure()
10+
x = arange(10.0)
11+
y = sin(arange(10.0)/20.0*pi)
12+
13+
P.errorbar(x,y,yerr=0.1,capsize=3)
14+
15+
y = sin(arange(10.0)/20.0*pi) + 1
16+
P.errorbar(x,y,yerr=0.1, uplims=True)
17+
18+
y = sin(arange(10.0)/20.0*pi) + 2
19+
upperlimits = array([1,0]*5)
20+
lowerlimits = array([0,1]*5)
21+
P.errorbar(x, y, yerr=0.1, uplims=upperlimits, lolims=lowerlimits)
22+
23+
P.xlim(-1,10)
24+
25+
fig = P.figure()
26+
x = arange(10.0)/10.0
27+
y = (x+0.1)**2
28+
29+
P.errorbar(x, y, xerr=0.1, xlolims=True)
30+
y = (x+0.1)**3
31+
32+
P.errorbar(x+0.6, y, xerr=0.1, xuplims=upperlimits, xlolims=lowerlimits)
33+
34+
y = (x+0.1)**4
35+
P.errorbar(x+1.2, y, xerr=0.1, xuplims=True)
36+
37+
P.xlim(-0.2,2.4)
38+
P.ylim(-0.1,1.3)
39+
40+
P.show()

lib/matplotlib/axes.py

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3522,10 +3522,13 @@ def pie(self, x, explode=None, labels=None,
35223522

35233523
def errorbar(self, x, y, yerr=None, xerr=None,
35243524
fmt='-', ecolor=None, capsize=3,
3525-
barsabove=False, **kwargs):
3525+
barsabove=False, lolims=False, uplims=False,
3526+
xlolims=False, xuplims=False, **kwargs):
35263527
"""
35273528
ERRORBAR(x, y, yerr=None, xerr=None,
3528-
fmt='b-', ecolor=None, capsize=3, barsabove=False)
3529+
fmt='b-', ecolor=None, capsize=3, barsabove=False,
3530+
lolims=False, uplims=False,
3531+
xlolims=False, xuplims=False)
35293532
35303533
Plot x versus y with error deltas in yerr and xerr.
35313534
Vertical errorbars are plotted if yerr is not None
@@ -3554,6 +3557,11 @@ def errorbar(self, x, y, yerr=None, xerr=None,
35543557
barsabove, if True, will plot the errorbars above the plot symbols
35553558
- default is below
35563559
3560+
lolims, uplims, xlolims, xuplims: These arguments can be used
3561+
to indicate that a value gives only upper/lower limits. In
3562+
that case a caret symbol is used to indicate this. lims-arguments
3563+
may be of the same type as xerr and yerr.
3564+
35573565
kwargs are passed on to the plot command for the markers.
35583566
So you can add additional key=value pairs to control the
35593567
errorbar markers. For example, this code makes big red
@@ -3579,18 +3587,18 @@ def errorbar(self, x, y, yerr=None, xerr=None,
35793587
if not self._hold: self.cla()
35803588

35813589
# make sure all the args are iterable arrays
3582-
if not iterable(x): x = npy.asarray([x])
3590+
if not iterable(x): x = npy.array([x])
35833591
else: x = npy.asarray(x)
35843592

3585-
if not iterable(y): y = npy.asarray([y])
3593+
if not iterable(y): y = npy.array([y])
35863594
else: y = npy.asarray(y)
35873595

35883596
if xerr is not None:
3589-
if not iterable(xerr): xerr = npy.asarray([xerr])
3597+
if not iterable(xerr): xerr = npy.array([xerr])
35903598
else: xerr = npy.asarray(xerr)
35913599

35923600
if yerr is not None:
3593-
if not iterable(yerr): yerr = npy.asarray([yerr])
3601+
if not iterable(yerr): yerr = npy.array([yerr])
35943602
else: yerr = npy.asarray(yerr)
35953603

35963604
l0 = None
@@ -3607,6 +3615,18 @@ def errorbar(self, x, y, yerr=None, xerr=None,
36073615
if 'lw' in kwargs:
36083616
lines_kw['lw']=kwargs['lw']
36093617

3618+
if not iterable(lolims): lolims = npy.array([lolims]*len(x), bool)
3619+
else: lolims = npy.asarray(lolims, bool)
3620+
3621+
if not iterable(uplims): uplims = npy.array([uplims]*len(x), bool)
3622+
else: uplims = npy.asarray(uplims, bool)
3623+
3624+
if not iterable(xlolims): xlolims = npy.array([xlolims]*len(x), bool)
3625+
else: xlolims = npy.asarray(xlolims, bool)
3626+
3627+
if not iterable(xuplims): xuplims = npy.array([xuplims]*len(x), bool)
3628+
else: xuplims = npy.asarray(xuplims, bool)
3629+
36103630
if capsize > 0:
36113631
plot_kw = {
36123632
'ms':2*capsize,
@@ -3626,8 +3646,19 @@ def errorbar(self, x, y, yerr=None, xerr=None,
36263646

36273647
barcols.append( self.hlines(y, left, right, **lines_kw ) )
36283648
if capsize > 0:
3629-
caplines.extend( self.plot(left, y, 'k|', **plot_kw) )
3630-
caplines.extend( self.plot(right, y, 'k|', **plot_kw) )
3649+
if xlolims.any():
3650+
caplines.extend( self.plot(left[xlolims], y[xlolims], ls='None', marker=mlines.CARETLEFT, **plot_kw) )
3651+
xlolims = ~xlolims
3652+
caplines.extend( self.plot(left[xlolims], y[xlolims], 'k|', **plot_kw) )
3653+
else:
3654+
caplines.extend( self.plot(left, y, 'k|', **plot_kw) )
3655+
3656+
if xuplims.any():
3657+
caplines.extend( self.plot(right[xuplims], y[xuplims], ls='None', marker=mlines.CARETRIGHT, **plot_kw) )
3658+
xuplims = ~xuplims
3659+
caplines.extend( self.plot(right[xuplims], y[xuplims], 'k|', **plot_kw) )
3660+
else:
3661+
caplines.extend( self.plot(right, y, 'k|', **plot_kw) )
36313662

36323663
if yerr is not None:
36333664
if len(yerr.shape) == 1:
@@ -3639,8 +3670,20 @@ def errorbar(self, x, y, yerr=None, xerr=None,
36393670

36403671
barcols.append( self.vlines(x, lower, upper, **lines_kw) )
36413672
if capsize > 0:
3642-
caplines.extend( self.plot(x, lower, 'k_', **plot_kw) )
3643-
caplines.extend( self.plot(x, upper, 'k_', **plot_kw) )
3673+
3674+
if lolims.any():
3675+
caplines.extend( self.plot(x[lolims], lower[lolims], ls='None', marker=mlines.CARETDOWN, **plot_kw) )
3676+
lolims = ~lolims
3677+
caplines.extend( self.plot(x[lolims], lower[lolims], 'k_', **plot_kw) )
3678+
else:
3679+
caplines.extend( self.plot(x, lower, 'k_', **plot_kw) )
3680+
3681+
if uplims.any():
3682+
caplines.extend( self.plot(x[uplims], upper[uplims], ls='None', marker=mlines.CARETUP, **plot_kw) )
3683+
uplims = ~uplims
3684+
caplines.extend( self.plot(x[uplims], upper[uplims], 'k_', **plot_kw) )
3685+
else:
3686+
caplines.extend( self.plot(x, upper, 'k_', **plot_kw) )
36443687

36453688
if not barsabove and fmt is not None:
36463689
l0, = self.plot(x,y,fmt,**kwargs)

lib/matplotlib/lines.py

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
from transforms import lbwh_to_bbox, LOG10
2222
from matplotlib import rcParams
2323

24-
TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN = range(4)
24+
# special-purpose marker identifiers:
25+
(TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN,
26+
CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN) = range(8)
2527

2628
def unmasked_index_ranges(mask, compressed = True):
2729
'''
@@ -97,7 +99,7 @@ def segment_hits(cx,cy,x,y,radius):
9799
point_hits = (cx - x)**2 + (cy - y)**2 <= radius**2
98100
#if any(point_hits): print "points",xr[candidates]
99101
candidates = candidates & ~point_hits[:-1] & ~point_hits[1:]
100-
102+
101103
# For those candidates which remain, determine how far they lie away
102104
# from the line.
103105
px,py = xr+u*dx,yr+u*dy
@@ -147,6 +149,10 @@ class Line2D(Artist):
147149
TICKRIGHT : '_draw_tickright',
148150
TICKUP : '_draw_tickup',
149151
TICKDOWN : '_draw_tickdown',
152+
CARETLEFT : '_draw_caretleft',
153+
CARETRIGHT : '_draw_caretright',
154+
CARETUP : '_draw_caretup',
155+
CARETDOWN : '_draw_caretdown',
150156
'None' : '_draw_nothing',
151157
' ' : '_draw_nothing',
152158
'' : '_draw_nothing',
@@ -1201,6 +1207,62 @@ def _draw_tri_right(self, renderer, gc, xt, yt):
12011207
renderer.draw_line(gc, x, y, x-offset2, y+offset1)
12021208
renderer.draw_line(gc, x, y, x-offset2, y-offset1)
12031209

1210+
def _draw_caretdown(self, renderer, gc, xt, yt):
1211+
offset = 0.5*renderer.points_to_pixels(self._markersize)
1212+
offset1 = 1.5*offset
1213+
if self._newstyle:
1214+
path = agg.path_storage()
1215+
path.move_to(-offset, offset1)
1216+
path.line_to(0, 0)
1217+
path.line_to(+offset, offset1)
1218+
renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
1219+
else:
1220+
for (x,y) in zip(xt, yt):
1221+
renderer.draw_line(gc, x-offset, y+offset1, x, y)
1222+
renderer.draw_line(gc, x, y, x+offset, y+offset1)
1223+
1224+
def _draw_caretup(self, renderer, gc, xt, yt):
1225+
offset = 0.5*renderer.points_to_pixels(self._markersize)
1226+
offset1 = 1.5*offset
1227+
if self._newstyle:
1228+
path = agg.path_storage()
1229+
path.move_to(-offset, -offset1)
1230+
path.line_to(0, 0)
1231+
path.line_to(+offset, -offset1)
1232+
renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
1233+
else:
1234+
for (x,y) in zip(xt, yt):
1235+
renderer.draw_line(gc, x-offset, y-offset1, x, y)
1236+
renderer.draw_line(gc, x, y, x+offset, y-offset1)
1237+
1238+
def _draw_caretleft(self, renderer, gc, xt, yt):
1239+
offset = 0.5*renderer.points_to_pixels(self._markersize)
1240+
offset1 = 1.5*offset
1241+
if self._newstyle:
1242+
path = agg.path_storage()
1243+
path.move_to(offset1, -offset)
1244+
path.line_to(0, 0)
1245+
path.line_to(offset1, offset)
1246+
renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
1247+
else:
1248+
for (x,y) in zip(xt, yt):
1249+
renderer.draw_line(gc, x+offset1, y-offset, x, y)
1250+
renderer.draw_line(gc, x, y, x+offset1, y+offset)
1251+
1252+
def _draw_caretright(self, renderer, gc, xt, yt):
1253+
offset = 0.5*renderer.points_to_pixels(self._markersize)
1254+
offset1 = 1.5*offset
1255+
if self._newstyle:
1256+
path = agg.path_storage()
1257+
path.move_to(-offset1, -offset)
1258+
path.line_to(0, 0)
1259+
path.line_to(-offset1, offset)
1260+
renderer.draw_markers(gc, path, None, xt, yt, self.get_transform())
1261+
else:
1262+
for (x,y) in zip(xt, yt):
1263+
renderer.draw_line(gc, x-offset1, y-offset, x, y)
1264+
renderer.draw_line(gc, x, y, x-offset1, y+offset)
1265+
12041266
def _draw_x(self, renderer, gc, xt, yt):
12051267
offset = 0.5*renderer.points_to_pixels(self._markersize)
12061268

0 commit comments

Comments
 (0)