2015-10-02 18:32:46 +01:00
|
|
|
#===============================================================================
|
|
|
|
|
# Copyright (c) 2012-2015, GPy authors (see AUTHORS.txt).
|
|
|
|
|
# All rights reserved.
|
2015-10-09 16:07:57 +01:00
|
|
|
#
|
2015-10-02 18:32:46 +01:00
|
|
|
# Redistribution and use in source and binary forms, with or without
|
|
|
|
|
# modification, are permitted provided that the following conditions are met:
|
2015-10-09 16:07:57 +01:00
|
|
|
#
|
2015-10-02 18:32:46 +01:00
|
|
|
# * Redistributions of source code must retain the above copyright notice, this
|
|
|
|
|
# list of conditions and the following disclaimer.
|
2015-10-09 16:07:57 +01:00
|
|
|
#
|
2015-10-02 18:32:46 +01:00
|
|
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
|
# this list of conditions and the following disclaimer in the documentation
|
|
|
|
|
# and/or other materials provided with the distribution.
|
2015-10-09 16:07:57 +01:00
|
|
|
#
|
2015-10-02 18:32:46 +01:00
|
|
|
# * Neither the name of GPy nor the names of its
|
|
|
|
|
# contributors may be used to endorse or promote products derived from
|
|
|
|
|
# this software without specific prior written permission.
|
2015-10-09 16:07:57 +01:00
|
|
|
#
|
2015-10-02 18:32:46 +01:00
|
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
|
|
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
|
|
|
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
|
|
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
#===============================================================================
|
|
|
|
|
import numpy as np
|
2015-10-09 16:07:57 +01:00
|
|
|
from . import plotting_library as pl
|
|
|
|
|
#from .. import gpy_plot
|
2015-10-03 13:59:01 +01:00
|
|
|
from .plot_util import get_x_y_var, get_free_dims, get_which_data_ycols,\
|
2015-10-03 19:45:19 +01:00
|
|
|
get_which_data_rows, update_not_existing_kwargs, helper_predict_with_model
|
2015-10-02 18:32:46 +01:00
|
|
|
|
2015-10-04 16:10:35 +01:00
|
|
|
def plot_data(self, which_data_rows='all',
|
|
|
|
|
which_data_ycols='all', visible_dims=None,
|
|
|
|
|
projection='2d', label=None, **plot_kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Plot the training data
|
|
|
|
|
- For higher dimensions than two, use fixed_inputs to plot the data points with some of the inputs fixed.
|
|
|
|
|
|
|
|
|
|
Can plot only part of the data
|
|
|
|
|
using which_data_rows and which_data_ycols.
|
|
|
|
|
|
|
|
|
|
:param which_data_rows: which of the training data to plot (default all)
|
|
|
|
|
:type which_data_rows: 'all' or a slice object to slice self.X, self.Y
|
|
|
|
|
:param which_data_ycols: when the data has several columns (independant outputs), only plot these
|
|
|
|
|
:type which_data_ycols: 'all' or a list of integers
|
|
|
|
|
:param visible_dims: an array specifying the input dimensions to plot (maximum two)
|
|
|
|
|
:type visible_dims: a numpy array
|
|
|
|
|
:param {'2d','3d'} projection: whether to plot in 2d or 3d. This only applies when plotting two dimensional inputs!
|
|
|
|
|
:param str label: the label for the plot
|
|
|
|
|
:param kwargs plot_kwargs: kwargs for the data plot for the plotting library you are using
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-04 16:10:35 +01:00
|
|
|
:returns list: of plots created.
|
|
|
|
|
"""
|
2015-10-09 16:07:57 +01:00
|
|
|
canvas, plot_kwargs = pl().new_canvas(projection=projection, **plot_kwargs)
|
2015-10-04 16:10:35 +01:00
|
|
|
plots = _plot_data(self, canvas, which_data_rows, which_data_ycols, visible_dims, projection, label, **plot_kwargs)
|
2015-10-09 16:07:57 +01:00
|
|
|
return pl().add_to_canvas(canvas, plots)
|
2015-10-04 16:10:35 +01:00
|
|
|
|
2015-10-02 18:32:46 +01:00
|
|
|
def _plot_data(self, canvas, which_data_rows='all',
|
|
|
|
|
which_data_ycols='all', visible_dims=None,
|
2015-10-04 16:10:35 +01:00
|
|
|
projection='2d', label=None, **plot_kwargs):
|
2015-10-03 13:59:01 +01:00
|
|
|
ycols = get_which_data_ycols(self, which_data_ycols)
|
|
|
|
|
rows = get_which_data_rows(self, which_data_rows)
|
2015-10-02 18:32:46 +01:00
|
|
|
|
2015-10-04 16:10:35 +01:00
|
|
|
X, _, Y = get_x_y_var(self)
|
2015-10-03 13:59:01 +01:00
|
|
|
free_dims = get_free_dims(self, visible_dims, None)
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-03 13:59:01 +01:00
|
|
|
plots = {}
|
|
|
|
|
plots['dataplot'] = []
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-02 18:32:46 +01:00
|
|
|
#one dimensional plotting
|
|
|
|
|
if len(free_dims) == 1:
|
2015-10-03 13:59:01 +01:00
|
|
|
for d in ycols:
|
2015-10-09 16:07:57 +01:00
|
|
|
update_not_existing_kwargs(plot_kwargs, pl().defaults.data_1d) # @UndefinedVariable
|
|
|
|
|
plots['dataplot'].append(pl().scatter(canvas, X[rows, free_dims], Y[rows, d], label=label, **plot_kwargs))
|
2015-10-02 18:32:46 +01:00
|
|
|
#2D plotting
|
|
|
|
|
elif len(free_dims) == 2:
|
2015-10-04 16:10:35 +01:00
|
|
|
if projection=='2d':
|
|
|
|
|
for d in ycols:
|
2015-10-09 16:07:57 +01:00
|
|
|
update_not_existing_kwargs(plot_kwargs, pl().defaults.data_2d) # @UndefinedVariable
|
|
|
|
|
plots['dataplot'].append(pl().scatter(canvas, X[rows, free_dims[0]], X[rows, free_dims[1]],
|
2015-10-07 19:03:03 +01:00
|
|
|
color=Y[rows, d], label=label, **plot_kwargs))
|
2015-10-04 16:10:35 +01:00
|
|
|
else:
|
|
|
|
|
for d in ycols:
|
2015-10-09 16:07:57 +01:00
|
|
|
update_not_existing_kwargs(plot_kwargs, pl().defaults.data_2d) # @UndefinedVariable
|
|
|
|
|
plots['dataplot'].append(pl().scatter(canvas, X[rows, free_dims[0]], X[rows, free_dims[1]],
|
2015-10-07 19:03:03 +01:00
|
|
|
Z=Y[rows, d], color=Y[rows, d], label=label, **plot_kwargs))
|
2015-10-03 19:45:19 +01:00
|
|
|
elif len(free_dims) == 0:
|
|
|
|
|
pass #Nothing to plot!
|
2015-10-02 18:32:46 +01:00
|
|
|
else:
|
|
|
|
|
raise NotImplementedError("Cannot plot in more then two dimensions")
|
2015-10-03 13:59:01 +01:00
|
|
|
return plots
|
2015-10-02 18:32:46 +01:00
|
|
|
|
2015-10-04 16:10:35 +01:00
|
|
|
def plot_data_error(self, which_data_rows='all',
|
2015-10-02 18:32:46 +01:00
|
|
|
which_data_ycols='all', visible_dims=None,
|
2015-10-04 16:10:35 +01:00
|
|
|
projection='2d', label=None, **error_kwargs):
|
2015-10-03 13:59:01 +01:00
|
|
|
"""
|
2015-10-04 16:10:35 +01:00
|
|
|
Plot the training data input error.
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-04 16:10:35 +01:00
|
|
|
For higher dimensions than two, use fixed_inputs to plot the data points with some of the inputs fixed.
|
2015-10-03 13:59:01 +01:00
|
|
|
|
|
|
|
|
Can plot only part of the data
|
|
|
|
|
using which_data_rows and which_data_ycols.
|
|
|
|
|
|
|
|
|
|
:param which_data_rows: which of the training data to plot (default all)
|
|
|
|
|
:type which_data_rows: 'all' or a slice object to slice self.X, self.Y
|
|
|
|
|
:param which_data_ycols: when the data has several columns (independant outputs), only plot these
|
2015-10-04 12:31:22 +01:00
|
|
|
:type which_data_ycols: 'all' or a list of integers
|
2015-10-03 13:59:01 +01:00
|
|
|
:param visible_dims: an array specifying the input dimensions to plot (maximum two)
|
|
|
|
|
:type visible_dims: a numpy array
|
2015-10-04 16:10:35 +01:00
|
|
|
:param {'2d','3d'} projection: whether to plot in 2d or 3d. This only applies when plotting two dimensional inputs!
|
2015-10-03 13:59:01 +01:00
|
|
|
:param dict error_kwargs: kwargs for the error plot for the plotting library you are using
|
2015-10-04 16:10:35 +01:00
|
|
|
:param str label: the label for the plot
|
2015-10-03 13:59:01 +01:00
|
|
|
:param kwargs plot_kwargs: kwargs for the data plot for the plotting library you are using
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-03 13:59:01 +01:00
|
|
|
:returns list: of plots created.
|
|
|
|
|
"""
|
2015-10-09 16:07:57 +01:00
|
|
|
canvas, error_kwargs = pl().new_canvas(projection=projection, **error_kwargs)
|
2015-10-04 16:10:35 +01:00
|
|
|
plots = _plot_data_error(self, canvas, which_data_rows, which_data_ycols, visible_dims, projection, label, **error_kwargs)
|
2015-10-09 16:07:57 +01:00
|
|
|
return pl().add_to_canvas(canvas, plots)
|
2015-10-04 16:10:35 +01:00
|
|
|
|
|
|
|
|
def _plot_data_error(self, canvas, which_data_rows='all',
|
|
|
|
|
which_data_ycols='all', visible_dims=None,
|
2015-10-08 14:05:20 +01:00
|
|
|
projection='2d', label=None, **error_kwargs):
|
2015-10-04 16:10:35 +01:00
|
|
|
ycols = get_which_data_ycols(self, which_data_ycols)
|
|
|
|
|
rows = get_which_data_rows(self, which_data_rows)
|
|
|
|
|
|
|
|
|
|
X, X_variance, Y = get_x_y_var(self)
|
|
|
|
|
free_dims = get_free_dims(self, visible_dims, None)
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-04 16:10:35 +01:00
|
|
|
plots = {}
|
2015-10-09 16:07:57 +01:00
|
|
|
|
|
|
|
|
if X_variance is not None:
|
|
|
|
|
plots['xerrorplot'] = []
|
2015-10-04 16:10:35 +01:00
|
|
|
#one dimensional plotting
|
|
|
|
|
if len(free_dims) == 1:
|
|
|
|
|
for d in ycols:
|
2015-10-09 16:07:57 +01:00
|
|
|
update_not_existing_kwargs(error_kwargs, pl().defaults.xerrorbar)
|
|
|
|
|
plots['xerrorplot'].append(pl().xerrorbar(canvas, X[rows, free_dims].flatten(), Y[rows, d].flatten(),
|
|
|
|
|
2 * np.sqrt(X_variance[rows, free_dims].flatten()), label=label,
|
2015-10-04 16:10:35 +01:00
|
|
|
**error_kwargs))
|
|
|
|
|
#2D plotting
|
|
|
|
|
elif len(free_dims) == 2:
|
2015-10-09 16:07:57 +01:00
|
|
|
update_not_existing_kwargs(error_kwargs, pl().defaults.xerrorbar) # @UndefinedVariable
|
2015-10-04 16:10:35 +01:00
|
|
|
for d in ycols:
|
2015-10-09 16:07:57 +01:00
|
|
|
plots['xerrorplot'].append(pl().xerrorbar(canvas, X[rows, free_dims[0]].flatten(), Y[rows, d].flatten(),
|
|
|
|
|
2 * np.sqrt(X_variance[rows, free_dims[0]].flatten()), label=label,
|
2015-10-04 16:10:35 +01:00
|
|
|
**error_kwargs))
|
2015-10-09 16:07:57 +01:00
|
|
|
plots['yerrorplot'].append(pl().xerrorbar(canvas, X[rows, free_dims[1]].flatten(), Y[rows, d].flatten(),
|
|
|
|
|
2 * np.sqrt(X_variance[rows, free_dims[1]].flatten()), label=label,
|
2015-10-04 16:10:35 +01:00
|
|
|
**error_kwargs))
|
|
|
|
|
elif len(free_dims) == 0:
|
|
|
|
|
pass #Nothing to plot!
|
|
|
|
|
else:
|
|
|
|
|
raise NotImplementedError("Cannot plot in more then two dimensions")
|
2015-10-03 19:45:19 +01:00
|
|
|
|
2015-10-04 16:10:35 +01:00
|
|
|
return plots
|
2015-10-03 19:45:19 +01:00
|
|
|
|
2015-10-04 16:10:35 +01:00
|
|
|
def plot_inducing(self, visible_dims=None, projection='2d', label=None, **plot_kwargs):
|
2015-10-03 19:45:19 +01:00
|
|
|
"""
|
|
|
|
|
Plot the inducing inputs of a sparse gp model
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-03 19:45:19 +01:00
|
|
|
:param array-like visible_dims: an array specifying the input dimensions to plot (maximum two)
|
|
|
|
|
:param kwargs plot_kwargs: keyword arguments for the plotting library
|
|
|
|
|
"""
|
2015-10-09 16:07:57 +01:00
|
|
|
canvas, kwargs = pl().new_canvas(projection=projection, **plot_kwargs)
|
2015-10-04 16:10:35 +01:00
|
|
|
plots = _plot_inducing(self, canvas, visible_dims, projection, label, **kwargs)
|
2015-10-09 16:07:57 +01:00
|
|
|
return pl().add_to_canvas(canvas, plots)
|
2015-10-03 19:45:19 +01:00
|
|
|
|
2015-10-04 16:10:35 +01:00
|
|
|
def _plot_inducing(self, canvas, visible_dims, projection, label, **plot_kwargs):
|
2015-10-06 14:48:52 +01:00
|
|
|
if visible_dims is None:
|
|
|
|
|
sig_dims = self.get_most_significant_input_dimensions()
|
|
|
|
|
visible_dims = [i for i in sig_dims if i is not None]
|
2015-10-03 19:45:19 +01:00
|
|
|
free_dims = get_free_dims(self, visible_dims, None)
|
|
|
|
|
|
|
|
|
|
Z = self.Z[:, free_dims]
|
|
|
|
|
plots = {}
|
|
|
|
|
|
|
|
|
|
#one dimensional plotting
|
|
|
|
|
if len(free_dims) == 1:
|
2015-10-09 16:07:57 +01:00
|
|
|
update_not_existing_kwargs(plot_kwargs, pl().defaults.inducing_1d) # @UndefinedVariable
|
|
|
|
|
plots['inducing'] = pl().plot_axis_lines(canvas, Z[:, free_dims], **plot_kwargs)
|
2015-10-03 19:45:19 +01:00
|
|
|
#2D plotting
|
2015-10-04 16:10:35 +01:00
|
|
|
elif len(free_dims) == 2 and projection == '3d':
|
2015-10-09 16:07:57 +01:00
|
|
|
update_not_existing_kwargs(plot_kwargs, pl().defaults.inducing_3d) # @UndefinedVariable
|
|
|
|
|
plots['inducing'] = pl().plot_axis_lines(canvas, Z[:, free_dims], **plot_kwargs)
|
2015-10-03 19:45:19 +01:00
|
|
|
elif len(free_dims) == 2:
|
2015-10-09 16:07:57 +01:00
|
|
|
update_not_existing_kwargs(plot_kwargs, pl().defaults.inducing_2d) # @UndefinedVariable
|
|
|
|
|
plots['inducing'] = pl().scatter(canvas, Z[:, free_dims[0]], Z[:, free_dims[1]],
|
2015-10-03 19:45:19 +01:00
|
|
|
**plot_kwargs)
|
|
|
|
|
elif len(free_dims) == 0:
|
|
|
|
|
pass #Nothing to plot!
|
|
|
|
|
else:
|
|
|
|
|
raise NotImplementedError("Cannot plot in more then two dimensions")
|
|
|
|
|
return plots
|
|
|
|
|
|
|
|
|
|
def plot_errorbars_trainset(self, which_data_rows='all',
|
2015-10-09 16:07:57 +01:00
|
|
|
which_data_ycols='all', fixed_inputs=None,
|
2015-10-04 16:10:35 +01:00
|
|
|
plot_raw=False, apply_link=False, label=None, projection='2d',
|
2015-10-03 19:45:19 +01:00
|
|
|
predict_kw=None, **plot_kwargs):
|
|
|
|
|
"""
|
|
|
|
|
Plot the errorbars of the GP likelihood on the training data.
|
2015-10-09 16:07:57 +01:00
|
|
|
These are the errorbars after the appropriate
|
2015-10-03 19:45:19 +01:00
|
|
|
approximations according to the likelihood are done.
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-03 19:45:19 +01:00
|
|
|
This also works for heteroscedastic likelihoods.
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-03 19:45:19 +01:00
|
|
|
Give the Y_metadata in the predict_kw if you need it.
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-03 19:45:19 +01:00
|
|
|
:param which_data_rows: which of the training data to plot (default all)
|
|
|
|
|
:type which_data_rows: 'all' or a slice object to slice self.X, self.Y
|
|
|
|
|
:param which_data_ycols: when the data has several columns (independant outputs), only plot these
|
|
|
|
|
:param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input dimension i should be set to value v.
|
|
|
|
|
:type fixed_inputs: a list of tuples
|
|
|
|
|
:param dict predict_kwargs: kwargs for the prediction used to predict the right quantiles.
|
|
|
|
|
:param kwargs plot_kwargs: kwargs for the data plot for the plotting library you are using
|
|
|
|
|
"""
|
2015-10-09 16:07:57 +01:00
|
|
|
canvas, kwargs = pl().new_canvas(projection=projection, **plot_kwargs)
|
|
|
|
|
plots = _plot_errorbars_trainset(self, canvas, which_data_rows, which_data_ycols,
|
2015-10-04 16:10:35 +01:00
|
|
|
fixed_inputs, plot_raw, apply_link, label, projection, predict_kw, **kwargs)
|
2015-10-09 16:07:57 +01:00
|
|
|
return pl().add_to_canvas(canvas, plots)
|
2015-10-03 19:45:19 +01:00
|
|
|
|
2015-10-09 16:07:57 +01:00
|
|
|
def _plot_errorbars_trainset(self, canvas,
|
|
|
|
|
which_data_rows='all', which_data_ycols='all',
|
2015-10-03 19:45:19 +01:00
|
|
|
fixed_inputs=None,
|
|
|
|
|
plot_raw=False, apply_link=False,
|
2015-10-04 16:10:35 +01:00
|
|
|
label=None, projection='2d', predict_kw=None, **plot_kwargs):
|
2015-10-03 19:45:19 +01:00
|
|
|
|
|
|
|
|
ycols = get_which_data_ycols(self, which_data_ycols)
|
|
|
|
|
rows = get_which_data_rows(self, which_data_rows)
|
|
|
|
|
|
|
|
|
|
X, _, Y = get_x_y_var(self)
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-03 19:45:19 +01:00
|
|
|
if fixed_inputs is None:
|
|
|
|
|
fixed_inputs = []
|
2015-10-09 16:07:57 +01:00
|
|
|
free_dims = get_free_dims(self, None, fixed_inputs)
|
2015-10-03 19:45:19 +01:00
|
|
|
|
|
|
|
|
Xgrid = X.copy()
|
|
|
|
|
for i, v in fixed_inputs:
|
|
|
|
|
Xgrid[:, i] = v
|
|
|
|
|
|
|
|
|
|
plots = []
|
2015-10-09 16:07:57 +01:00
|
|
|
|
2015-10-04 16:10:35 +01:00
|
|
|
if len(free_dims)<=2:
|
2015-10-09 16:07:57 +01:00
|
|
|
update_not_existing_kwargs(plot_kwargs, pl().defaults.yerrorbar)
|
2015-10-07 19:03:03 +01:00
|
|
|
if predict_kw is None:
|
2015-10-03 21:14:32 +01:00
|
|
|
predict_kw = {}
|
2015-10-07 19:03:03 +01:00
|
|
|
if 'Y_metadata' not in predict_kw:
|
|
|
|
|
predict_kw['Y_metadata'] = self.Y_metadata or {}
|
2015-10-09 16:07:57 +01:00
|
|
|
mu, percs, _ = helper_predict_with_model(self, Xgrid, plot_raw,
|
|
|
|
|
apply_link, (2.5, 97.5),
|
2015-10-07 19:03:03 +01:00
|
|
|
ycols, predict_kw)
|
|
|
|
|
if len(free_dims)==1:
|
2015-10-03 19:45:19 +01:00
|
|
|
for d in ycols:
|
2015-10-09 16:07:57 +01:00
|
|
|
plots.append(pl().yerrorbar(canvas, X[rows,free_dims[0]], mu[rows,d],
|
2015-10-07 19:03:03 +01:00
|
|
|
np.vstack([mu[rows, d] - percs[0][rows, d], percs[1][rows, d] - mu[rows,d]]),
|
2015-10-09 16:07:57 +01:00
|
|
|
label=label,
|
2015-10-03 19:45:19 +01:00
|
|
|
**plot_kwargs))
|
2015-10-04 16:10:35 +01:00
|
|
|
elif len(free_dims) == 2:
|
2015-10-07 19:03:03 +01:00
|
|
|
for d in ycols:
|
2015-10-09 16:07:57 +01:00
|
|
|
plots.append(pl().yerrorbar(canvas, X[rows,free_dims[0]], X[rows,free_dims[1]],
|
2015-10-07 19:03:03 +01:00
|
|
|
np.vstack([mu[rows, d] - percs[0][rows, d], percs[1][rows, d] - mu[rows,d]]),
|
|
|
|
|
color=Y[rows,d],
|
2015-10-09 16:07:57 +01:00
|
|
|
label=label,
|
2015-10-07 19:03:03 +01:00
|
|
|
**plot_kwargs))
|
2015-10-09 16:07:57 +01:00
|
|
|
plots.append(pl().xerrorbar(canvas, X[rows,free_dims[0]], X[rows,free_dims[1]],
|
2015-10-07 19:03:03 +01:00
|
|
|
np.vstack([mu[rows, d] - percs[0][rows, d], percs[1][rows, d] - mu[rows,d]]),
|
|
|
|
|
color=Y[rows,d],
|
2015-10-09 16:07:57 +01:00
|
|
|
label=label,
|
2015-10-07 19:03:03 +01:00
|
|
|
**plot_kwargs))
|
2015-10-03 19:45:19 +01:00
|
|
|
pass #Nothing to plot!
|
|
|
|
|
else:
|
|
|
|
|
raise NotImplementedError("Cannot plot in more then one dimension.")
|
2015-10-04 12:31:22 +01:00
|
|
|
return dict(yerrorbars=plots)
|
|
|
|
|
|
|
|
|
|
|