Skip to content

Commit

Permalink
Added ErrorBars Element
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Apr 30, 2015
1 parent 3238903 commit f2b276b
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 2 deletions.
33 changes: 33 additions & 0 deletions holoviews/element/chart.py
Expand Up @@ -239,6 +239,39 @@ def progressive(self):



class ErrorBars(Chart):
"""
ErrorBars is a Chart Element type representing any number of
errorbars situated in a 2D space. The errors must be supplied
as an Nx3 or Nx4 array representing the x/y-positions and
either the symmetric error or assymetric errors respectively.
Internally the data is always held as an Nx4 array with the
lower and upper bounds.
"""

group = param.String(default='ErrorBars', doc="""
A string describing the quantitity measured by the ErrorBars
object.""")

key_dimensions = param.List(default=[Dimension('x'), Dimension('y')],
bounds=(2, 2), constant=True, doc="""
The Dimensions corresponding to the x- and y-positions of
the error bars.""")

value_dimensions = param.List(default=[Dimension('lerror'), Dimension('uerror')],
bounds=(2,2), constant=True)

def __init__(self, data, **params):
data = list(data)
data = self._null_value if (data is None) or (len(data) == 0) else data
if len(data) and not isinstance(data, np.ndarray):
data = np.array(data)
if data.shape[1] == 3:
data = np.hstack([data, np.atleast_2d(data[:, 2]).T])
super(ErrorBars, self).__init__(data, **params)



class Bars(NdElement):
"""
Bars is an Element type, representing a number of stacked and
Expand Down
1 change: 1 addition & 0 deletions holoviews/plotting/__init__.py
Expand Up @@ -299,6 +299,7 @@ def set_style(key):
# Charts
Store.options.Curve = Options('style', color=Cycle(), linewidth=2)
Store.options.Scatter = Options('style', color=Cycle(), marker='o')
Store.options.ErrorBars = Options('style', ecolor='k')
Store.options.Bars = Options('style', ec='k', color=Cycle())
Store.options.Histogram = Options('style', ec='k', fc=Cycle())
Store.options.Points = Options('style', color=Cycle(), marker='o')
Expand Down
71 changes: 69 additions & 2 deletions holoviews/plotting/chart.py
Expand Up @@ -10,7 +10,7 @@
from ..core.options import Store
from ..core import OrderedDict, NdMapping, ViewableElement, CompositeOverlay, HoloMap
from ..core.util import match_spec
from ..element import Scatter, Curve, Histogram, Bars, Points, Raster, VectorField
from ..element import Scatter, Curve, Histogram, Bars, Points, Raster, VectorField, ErrorBars
from .element import ElementPlot
from .plot import Plot

Expand Down Expand Up @@ -144,6 +144,72 @@ def update_handles(self, axis, view, key, ranges=None):




class ErrorPlot(ChartPlot):
"""
ErrorPlot plots the ErrorBar Element type and supporting
both horizontal and vertical error bars via the vertical
plot option.
"""

vertical = param.Boolean(default=False, doc="""
Whether to draw horizontal or vertical error bars.""")

style_opts = ['ecolor', 'elinewidth', 'capsize', 'capthick',
'barsabove', 'lolims', 'uplims', 'xlolims',
'errorevery', 'xuplims', 'alpha', 'linestyle',
'linewidth', 'markeredgecolor', 'markeredgewidth',
'markerfacecolor', 'markersize', 'solid_capstyle',
'solid_joinstyle', 'dashes', 'color']


def __call__(self, ranges=None):
element = self.map.last
axis = self.handles['axis']
key = self.keys[-1]

ranges = self.compute_ranges(self.map, key, ranges)
ranges = match_spec(element, ranges)

error_kwargs = dict(self.style[self.cyclic_index], fmt='none',
zorder=self.zorder)
kwarg = 'xerr' if self.vertical else 'yerr'
error_kwargs[kwarg] = element.data[:, 2:4].T
_, (bottoms, tops), verts = axis.errorbar(element.data[:, 0],
element.data[:, 1],
**error_kwargs)
self.handles['bottoms'] = bottoms
self.handles['tops'] = tops
self.handles['verts'] = verts[0]

return self._finalize_axis(self.keys[-1], ranges=ranges)


def update_handles(self, axis, view, key, ranges=None):
data = view.data
bottoms = self.handles['bottoms']
tops = self.handles['tops']
verts = self.handles['verts']
paths = verts.get_paths()
if self.vertical:
bdata = data[:, 0] - data[:, 2]
tdata = data[:, 0] + data[:, 3]
tops.set_xdata(bdata)
bottoms.set_xdata(tdata)
for i, path in enumerate(paths):
path.vertices = np.array([[bdata[i], data[i, 1]],
[tdata[i], data[i, 1]]])
else:
bdata = data[:, 1] - data[:, 2]
tdata = data[:, 1] + data[:, 3]
bottoms.set_ydata(bdata)
tops.set_ydata(tdata)
for i, path in enumerate(paths):
path.vertices = np.array([[data[i, 0], bdata[i]],
[data[i, 0], tdata[i]]])



class HistogramPlot(ChartPlot):
"""
HistogramPlot can plot DataHistograms and ViewMaps of
Expand Down Expand Up @@ -885,6 +951,7 @@ def update_handles(self, axis, element, key, ranges=None):
Bars: BarPlot,
Histogram: HistogramPlot,
Points: PointPlot,
VectorField: VectorFieldPlot})
VectorField: VectorFieldPlot,
ErrorBars: ErrorPlot})

Plot.sideplots.update({Histogram: SideHistogramPlot})

0 comments on commit f2b276b

Please sign in to comment.