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

Skip to content

Fixed issues with errorbar limits #2452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 4, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/api/api_changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ original location:
- mstream -> `from matplotlib import stream as mstream`
- mtable -> `from matplotlib import table as mtable`

* The :func:`~matplotlib.pyplot.errorbar` method has been changed such that
the upper and lower limits (*lolims*, *uplims*, *xlolims*, *xuplims*) now
point in the correct direction.

* The Sphinx extensions `ipython_directive` and
`ipython_console_highlighting` have been moved to the IPython
project itself. While they remain in matplotlib for this release,
Expand Down
5 changes: 5 additions & 0 deletions doc/users/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ specify wedgeprops = {'linewidth':3} to specify the width of the borders of
the wedges in the pie. For more properties that the user can specify, look at
the docs for the wedge and text objects.

Fixed the direction of errorbar upper/lower limits
``````````````````````````````````````````````````
Larry Bradley fixed the :func:`~matplotlib.pyplot.errorbar` method such
that the upper and lower limits (*lolims*, *uplims*, *xlolims*,
*xuplims*) now point in the correct direction.

Date handling
-------------
Expand Down
53 changes: 53 additions & 0 deletions examples/statistics/errorbar_limits.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""
Demo of the errorbar function, including upper and lower limits
"""
import numpy as np
import matplotlib.pyplot as plt

# example data
x = np.arange(0.5, 5.5, 0.5)
y = np.exp(-x)
xerr = 0.1
yerr = 0.2
ls = 'dotted'

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

# standard error bars
plt.errorbar(x, y, xerr=xerr, yerr=yerr, ls=ls, color='blue')

# including upper limits
uplims = np.zeros(x.shape)
uplims[[1, 5, 9]] = True
plt.errorbar(x, y+0.5, xerr=xerr, yerr=yerr, uplims=uplims, ls=ls,
color='green')

# including lower limits
lolims = np.zeros(x.shape)
lolims[[2, 4, 8]] = True
plt.errorbar(x, y+1.0, xerr=xerr, yerr=yerr, lolims=lolims, ls=ls,
color='red')

# including upper and lower limits
plt.errorbar(x, y+1.5, marker='o', ms=8, xerr=xerr, yerr=yerr,
lolims=lolims, uplims=uplims, ls=ls, color='magenta')

# including xlower and xupper limits
xerr = 0.2
yerr = np.zeros(x.shape) + 0.2
yerr[[3, 6]] = 0.3
xlolims = lolims
xuplims = uplims
lolims = np.zeros(x.shape)
uplims = np.zeros(x.shape)
lolims[[6]] = True
uplims[[3]] = True
plt.errorbar(x, y+2.1, marker='o', ms=8, xerr=xerr, yerr=yerr,
xlolims=xlolims, xuplims=xuplims, uplims=uplims, lolims=lolims,
ls='none', mec='blue', capsize=0, color='cyan')

ax.set_xlim((0, 5.5))
ax.set_title('Errorbar upper and lower limits')
plt.show()

193 changes: 103 additions & 90 deletions lib/matplotlib/axes/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2602,7 +2602,9 @@ def errorbar(self, x, y, yerr=None, xerr=None,
These arguments can be used to indicate that a value gives
only upper/lower limits. In that case a caret symbol is
used to indicate this. lims-arguments may be of the same
type as *xerr* and *yerr*.
type as *xerr* and *yerr*. To use limits with inverted
axes, :meth:`set_xlim` or :meth:`set_ylim` must be called
before :meth:`errorbar`.

*errorevery*: positive integer
subsamples the errorbars. e.g., if everyerror=5, errorbars for
Expand Down Expand Up @@ -2682,16 +2684,12 @@ def errorbar(self, x, y, yerr=None, xerr=None,
if elinewidth:
lines_kw['linewidth'] = elinewidth
else:
if 'linewidth' in kwargs:
lines_kw['linewidth'] = kwargs['linewidth']
if 'lw' in kwargs:
lines_kw['lw'] = kwargs['lw']
if 'transform' in kwargs:
lines_kw['transform'] = kwargs['transform']
if 'alpha' in kwargs:
lines_kw['alpha'] = kwargs['alpha']
if 'zorder' in kwargs:
lines_kw['zorder'] = kwargs['zorder']
for key in ('linewidth', 'lw'):
if key in kwargs:
lines_kw[key] = kwargs[key]
for key in ('transform', 'alpha', 'zorder'):
if key in kwargs:
lines_kw[key] = kwargs[key]

# arrays fine here, they are booleans and hence not units
if not iterable(lolims):
Expand Down Expand Up @@ -2727,29 +2725,21 @@ def xywhere(xs, ys, mask):
ys = [thisy for thisy, b in zip(ys, mask) if b]
return xs, ys

plot_kw = {'label': '_nolegend_'}
if capsize > 0:
plot_kw = {
'ms': 2 * capsize,
'label': '_nolegend_'}
if capthick is not None:
# 'mew' has higher priority, I believe,
# if both 'mew' and 'markeredgewidth' exists.
# So, save capthick to markeredgewidth so that
# explicitly setting mew or markeredgewidth will
# over-write capthick.
plot_kw['markeredgewidth'] = capthick
# For backwards-compat, allow explicit setting of
# 'mew' or 'markeredgewidth' to over-ride capthick.
if 'markeredgewidth' in kwargs:
plot_kw['markeredgewidth'] = kwargs['markeredgewidth']
if 'mew' in kwargs:
plot_kw['mew'] = kwargs['mew']
if 'transform' in kwargs:
plot_kw['transform'] = kwargs['transform']
if 'alpha' in kwargs:
plot_kw['alpha'] = kwargs['alpha']
if 'zorder' in kwargs:
plot_kw['zorder'] = kwargs['zorder']
plot_kw['ms'] = 2. * capsize
if capthick is not None:
# 'mew' has higher priority, I believe,
# if both 'mew' and 'markeredgewidth' exists.
# So, save capthick to markeredgewidth so that
# explicitly setting mew or markeredgewidth will
# over-write capthick.
plot_kw['markeredgewidth'] = capthick
# For backwards-compat, allow explicit setting of
# 'mew' or 'markeredgewidth' to over-ride capthick.
for key in ('markeredgewidth', 'mew', 'transform', 'alpha', 'zorder'):
if key in kwargs:
plot_kw[key] = kwargs[key]

if xerr is not None:
if (iterable(xerr) and len(xerr) == 2 and
Expand All @@ -2766,38 +2756,48 @@ def xywhere(xs, ys, mask):
right = [thisx + thiserr for (thisx, thiserr)
in cbook.safezip(x, xerr)]

yo, _ = xywhere(y, right, everymask)
lo, ro = xywhere(left, right, everymask)
barcols.append(self.hlines(yo, lo, ro, **lines_kw))
if capsize > 0:
if xlolims.any():
# can't use numpy logical indexing since left and
# y are lists
leftlo, ylo = xywhere(left, y, xlolims & everymask)

caplines.extend(
self.plot(leftlo, ylo, ls='None',
marker=mlines.CARETLEFT, **plot_kw))
xlolims = ~xlolims
leftlo, ylo = xywhere(left, y, xlolims & everymask)
caplines.extend(self.plot(leftlo, ylo, 'k|', **plot_kw))
# select points without upper/lower limits in x and
# draw normal errorbars for these points
noxlims = ~(xlolims | xuplims)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line deserves a comment

if noxlims.any():
yo, _ = xywhere(y, right, noxlims & everymask)
lo, ro = xywhere(left, right, noxlims & everymask)
barcols.append(self.hlines(yo, lo, ro, **lines_kw))
if capsize > 0:
caplines.extend(self.plot(lo, yo, 'k|', **plot_kw))
caplines.extend(self.plot(ro, yo, 'k|', **plot_kw))

if xlolims.any():
yo, _ = xywhere(y, right, xlolims & everymask)
lo, ro = xywhere(x, right, xlolims & everymask)
barcols.append(self.hlines(yo, lo, ro, **lines_kw))
rightup, yup = xywhere(right, y, xlolims & everymask)
if self.xaxis_inverted():
marker = mlines.CARETLEFT
else:

leftlo, ylo = xywhere(left, y, everymask)
caplines.extend(self.plot(leftlo, ylo, 'k|', **plot_kw))

if xuplims.any():

rightup, yup = xywhere(right, y, xuplims & everymask)
caplines.extend(
self.plot(rightup, yup, ls='None',
marker=mlines.CARETRIGHT, **plot_kw))
xuplims = ~xuplims
rightup, yup = xywhere(right, y, xuplims & everymask)
caplines.extend(self.plot(rightup, yup, 'k|', **plot_kw))
marker = mlines.CARETRIGHT
caplines.extend(
self.plot(rightup, yup, ls='None', marker=marker,
**plot_kw))
if capsize > 0:
xlo, ylo = xywhere(x, y, xlolims & everymask)
caplines.extend(self.plot(xlo, ylo, 'k|', **plot_kw))

if xuplims.any():
yo, _ = xywhere(y, right, xuplims & everymask)
lo, ro = xywhere(left, x, xuplims & everymask)
barcols.append(self.hlines(yo, lo, ro, **lines_kw))
leftlo, ylo = xywhere(left, y, xuplims & everymask)
if self.xaxis_inverted():
marker = mlines.CARETRIGHT
else:
rightup, yup = xywhere(right, y, everymask)
caplines.extend(self.plot(rightup, yup, 'k|', **plot_kw))
marker = mlines.CARETLEFT
caplines.extend(
self.plot(leftlo, ylo, ls='None', marker=marker,
**plot_kw))
if capsize > 0:
xup, yup = xywhere(x, y, xuplims & everymask)
caplines.extend(self.plot(xup, yup, 'k|', **plot_kw))

if yerr is not None:
if (iterable(yerr) and len(yerr) == 2 and
Expand All @@ -2814,35 +2814,48 @@ def xywhere(xs, ys, mask):
upper = [thisy + thiserr for (thisy, thiserr)
in cbook.safezip(y, yerr)]

xo, _ = xywhere(x, lower, everymask)
lo, uo = xywhere(lower, upper, everymask)
barcols.append(self.vlines(xo, lo, uo, **lines_kw))
if capsize > 0:

if lolims.any():
xlo, lowerlo = xywhere(x, lower, lolims & everymask)
caplines.extend(
self.plot(xlo, lowerlo, ls='None',
marker=mlines.CARETDOWN, **plot_kw))
lolims = ~lolims
xlo, lowerlo = xywhere(x, lower, lolims & everymask)
caplines.extend(self.plot(xlo, lowerlo, 'k_', **plot_kw))
# select points without upper/lower limits in y and
# draw normal errorbars for these points
noylims = ~(lolims | uplims)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for consistency, this line should also get a similar comment

if noylims.any():
xo, _ = xywhere(x, lower, noylims & everymask)
lo, uo = xywhere(lower, upper, noylims & everymask)
barcols.append(self.vlines(xo, lo, uo, **lines_kw))
if capsize > 0:
caplines.extend(self.plot(xo, lo, 'k_', **plot_kw))
caplines.extend(self.plot(xo, uo, 'k_', **plot_kw))

if lolims.any():
xo, _ = xywhere(x, lower, lolims & everymask)
lo, uo = xywhere(y, upper, lolims & everymask)
barcols.append(self.vlines(xo, lo, uo, **lines_kw))
xup, upperup = xywhere(x, upper, lolims & everymask)
if self.yaxis_inverted():
marker = mlines.CARETDOWN
else:
xlo, lowerlo = xywhere(x, lower, everymask)
caplines.extend(self.plot(xlo, lowerlo, 'k_', **plot_kw))

if uplims.any():
xup, upperup = xywhere(x, upper, uplims & everymask)

caplines.extend(
self.plot(xup, upperup, ls='None',
marker=mlines.CARETUP, **plot_kw))
uplims = ~uplims
xup, upperup = xywhere(x, upper, uplims & everymask)
caplines.extend(self.plot(xup, upperup, 'k_', **plot_kw))
marker = mlines.CARETUP
caplines.extend(
self.plot(xup, upperup, ls='None', marker=marker,
**plot_kw))
if capsize > 0:
xlo, ylo = xywhere(x, y, lolims & everymask)
caplines.extend(self.plot(xlo, ylo, 'k_', **plot_kw))

if uplims.any():
xo, _ = xywhere(x, lower, uplims & everymask)
lo, uo = xywhere(lower, y, uplims & everymask)
barcols.append(self.vlines(xo, lo, uo, **lines_kw))
xlo, lowerlo = xywhere(x, lower, uplims & everymask)
if self.yaxis_inverted():
marker = mlines.CARETUP
else:
xup, upperup = xywhere(x, upper, everymask)
caplines.extend(self.plot(xup, upperup, 'k_', **plot_kw))
marker = mlines.CARETDOWN
caplines.extend(
self.plot(xlo, lowerlo, ls='None', marker=marker,
**plot_kw))
if capsize > 0:
xup, yup = xywhere(x, y, uplims & everymask)
caplines.extend(self.plot(xup, yup, 'k_', **plot_kw))

if not barsabove and fmt is not None:
l0, = self.plot(x, y, fmt, **kwargs)
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading