[testing] more restructuring, almost ready to ship, added some tests for testing with travis

This commit is contained in:
mzwiessele 2015-10-04 16:10:35 +01:00
parent 831e032ade
commit fa8f73326e
65 changed files with 628 additions and 1046 deletions

View file

@ -1,8 +1,6 @@
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
# Licensed under the BSD 3-clause license (see LICENSE.txt)
import sys
colorsHex = {\
"Aluminium6":"#2e3436",\
"Aluminium5":"#555753",\

View file

@ -35,6 +35,7 @@ if config.get('plotting', 'library') is not 'none':
GP.plot_density = gpy_plot.gp_plots.plot_density
GP.plot_samples = gpy_plot.gp_plots.plot_samples
GP.plot = gpy_plot.gp_plots.plot
GP.plot_f = gpy_plot.gp_plots.plot_f
#GP.plot_magnificaion = gpy_plot.latent_plots.plot_magnification
from ..core import SparseGP
@ -54,5 +55,5 @@ if config.get('plotting', 'library') is not 'none':
#GP.plot = matplot_dep.models_plots.plot_fit
#GP.plot_f = matplot_dep.models_plots.plot_fit_f
GP.plot_magnification = matplot_dep.dim_reduction_plots.plot_magnification
#GP.plot_magnification = matplot_dep.dim_reduction_plots.plot_magnification

View file

@ -57,7 +57,7 @@ class AbstractPlottingLibrary(object):
return self.__defaults
#===============================================================================
def get_new_canvas(self, plot_3d=False, **kwargs):
def get_new_canvas(self, plot_3d=False, xlabel=None, ylabel=None, zlabel=None, title=None, legend=True, **kwargs):
"""
Return a canvas, kwargupdate for your plotting library.
@ -68,13 +68,18 @@ class AbstractPlottingLibrary(object):
the kwargs are plotting library specific kwargs!
:param bool plot_3d: whether to plot in 3d.
:param xlabel: the label to put on the xaxis
:param ylabel: the label to put on the yaxis
:param zlabel: the label to put on the zaxis (if plotting in 3d)
:param title: the title of the plot
:param legend: whether to put a legend on
E.g. in matplotlib this means it deletes references to ax, as
plotting is done on the axis itself and is not a kwarg.
"""
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
def show_canvas(self, canvas, plots, xlabel=None, ylabel=None, zlabel=None, title=None, xlim=None, ylim=None, zlim=None, legend=True, **kwargs):
def show_canvas(self, canvas, plots, xlim=None, ylim=None, zlim=None, **kwargs):
"""
Show the canvas given.
plots is a dictionary with the plots
@ -82,14 +87,9 @@ class AbstractPlottingLibrary(object):
the kwargs are plotting library specific kwargs!
:param xlabel: the label to put on the xaxis
:param ylabel: the label to put on the yaxis
:param zlabel: the label to put on the zaxis (if plotting in 3d)
:param title: the title of the plot
:param (float, float) xlim: the limits for the xaxis
:param (float, float) ylim: the limits for the yaxis
:param (float, float) zlim: the limits for the zaxis (if plotting in 3d)
:param legend: whether to put a legend on
E.g. in matplotlib this does not have to do anything, we make the tight plot, though.
"""
@ -114,7 +114,15 @@ class AbstractPlottingLibrary(object):
"""
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
def scatter(self, canvas, X, Y, Z=None, c=None, vmin=None, vmax=None, label=None, **kwargs):
def surface(self, canvas, X, Y, Z, color=None, label=None, **kwargs):
"""
Plot a surface for 3d plotting for the inputs (X, Y, Z).
the kwargs are plotting library specific kwargs!
"""
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
def scatter(self, canvas, X, Y, Z=None, color=None, vmin=None, vmax=None, label=None, **kwargs):
"""
Make a scatter plot between X and Y on the canvas given.
@ -174,10 +182,12 @@ class AbstractPlottingLibrary(object):
"""
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
def contour(self, canvas, X, Y, C, color=None, label=None, **kwargs):
def contour(self, canvas, X, Y, C, Z=None, color=None, label=None, **kwargs):
"""
Make a contour plot at (X, Y) with heights stored in C on the canvas.
Make a contour plot at (X, Y) with heights/colors stored in C on the canvas.
if Z is not None: make 3d contour plot at (X, Y, Z) with heights/colors stored in C on the canvas.
the kwargs are plotting library specific kwargs!
"""
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")

View file

@ -32,48 +32,9 @@ from . import pl
from .plot_util import get_x_y_var, get_free_dims, get_which_data_ycols,\
get_which_data_rows, update_not_existing_kwargs, helper_predict_with_model
def _plot_data(self, canvas, which_data_rows='all',
which_data_ycols='all', visible_dims=None,
error_kwargs=None, **plot_kwargs):
if error_kwargs is None:
error_kwargs = {}
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)
plots = {}
plots['dataplot'] = []
if X_variance is not None: plots['xerrorplot'] = []
#one dimensional plotting
if len(free_dims) == 1:
for d in ycols:
update_not_existing_kwargs(plot_kwargs, pl.defaults.data_1d) # @UndefinedVariable
plots['dataplot'].append(pl.scatter(canvas, X[rows, free_dims], Y[rows, d], **plot_kwargs))
if X_variance is not None:
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()),
**error_kwargs))
#2D plotting
elif len(free_dims) == 2:
for d in ycols:
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]],
c=Y[rows, d], vmin=Y.min(), vmax=Y.max(), **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_data(self, which_data_rows='all',
which_data_ycols='all', visible_dims=None,
error_kwargs=None, **plot_kwargs):
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.
@ -87,28 +48,128 @@ def plot_data(self, which_data_rows='all',
: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 dict error_kwargs: kwargs for the error plot for the plotting library you are using
: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
:returns list: of plots created.
"""
canvas, kwargs = pl.get_new_canvas(plot_kwargs)
plots = _plot_data(self, canvas, which_data_rows, which_data_ycols, visible_dims, error_kwargs, **kwargs)
return pl.show_canvas(canvas, plots, xlabel='x', ylabel='y', legend='dataplot')
canvas, plot_kwargs = pl.get_new_canvas(projection=projection, **plot_kwargs)
plots = _plot_data(self, canvas, which_data_rows, which_data_ycols, visible_dims, projection, label, **plot_kwargs)
return pl.show_canvas(canvas, plots)
def _plot_data(self, canvas, which_data_rows='all',
which_data_ycols='all', visible_dims=None,
projection='2d', label=None, **plot_kwargs):
ycols = get_which_data_ycols(self, which_data_ycols)
rows = get_which_data_rows(self, which_data_rows)
def plot_inducing(self, visible_dims=None, **plot_kwargs):
X, _, Y = get_x_y_var(self)
free_dims = get_free_dims(self, visible_dims, None)
plots = {}
plots['dataplot'] = []
#one dimensional plotting
if len(free_dims) == 1:
for d in ycols:
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))
#2D plotting
elif len(free_dims) == 2:
if projection=='2d':
for d in ycols:
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]],
color=Y[rows, d], vmin=Y.min(), vmax=Y.max(), label=label, **plot_kwargs))
else:
for d in ycols:
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]],
Z=Y[rows, d], vmin=Y.min(), color=Y[rows, d], vmax=Y.max(), label=label, **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_data_error(self, which_data_rows='all',
which_data_ycols='all', visible_dims=None,
projection='2d', label=None, **error_kwargs):
"""
Plot the training data input error.
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 dict error_kwargs: kwargs for the error plot for the plotting library you are using
:param str label: the label for the plot
:param kwargs plot_kwargs: kwargs for the data plot for the plotting library you are using
:returns list: of plots created.
"""
canvas, error_kwargs = pl.get_new_canvas(projection=='3d', **error_kwargs)
plots = _plot_data_error(self, canvas, which_data_rows, which_data_ycols, visible_dims, projection, label, **error_kwargs)
return pl.show_canvas(canvas, plots)
def _plot_data_error(self, canvas, which_data_rows='all',
which_data_ycols='all', visible_dims=None,
projection='2d', **error_kwargs):
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)
plots = {}
if X_variance is not None:
plots['xerrorplot'] = []
#one dimensional plotting
if len(free_dims) == 1:
for d in ycols:
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()),
**error_kwargs))
#2D plotting
elif len(free_dims) == 2:
update_not_existing_kwargs(error_kwargs, pl.defaults.xerrorbar) # @UndefinedVariable
for d in ycols:
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()),
**error_kwargs))
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()),
**error_kwargs))
elif len(free_dims) == 0:
pass #Nothing to plot!
else:
raise NotImplementedError("Cannot plot in more then two dimensions")
return plots
def plot_inducing(self, visible_dims=None, projection='2d', label=None, **plot_kwargs):
"""
Plot the inducing inputs of a sparse gp model
: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
"""
canvas, kwargs = pl.get_new_canvas(plot_kwargs)
plots = _plot_inducing(self, canvas, visible_dims, **kwargs)
canvas, kwargs = pl.get_new_canvas(projection=projection, **plot_kwargs)
plots = _plot_inducing(self, canvas, visible_dims, projection, label, **kwargs)
return pl.show_canvas(canvas, plots)
def _plot_inducing(self, canvas, visible_dims, **plot_kwargs):
def _plot_inducing(self, canvas, visible_dims, projection, label, **plot_kwargs):
free_dims = get_free_dims(self, visible_dims, None)
Z = self.Z[:, free_dims]
@ -119,6 +180,9 @@ def _plot_inducing(self, canvas, visible_dims, **plot_kwargs):
update_not_existing_kwargs(plot_kwargs, pl.defaults.inducing_1d) # @UndefinedVariable
plots['inducing'] = pl.plot_axis_lines(canvas, Z[:, free_dims], **plot_kwargs)
#2D plotting
elif len(free_dims) == 2 and projection == '3d':
update_not_existing_kwargs(plot_kwargs, pl.defaults.inducing_3d) # @UndefinedVariable
plots['inducing'] = pl.plot_axis_lines(canvas, Z[:, free_dims], **plot_kwargs)
elif len(free_dims) == 2:
update_not_existing_kwargs(plot_kwargs, pl.defaults.inducing_2d) # @UndefinedVariable
plots['inducing'] = pl.scatter(canvas, Z[:, free_dims[0]], Z[:, free_dims[1]],
@ -131,7 +195,7 @@ def _plot_inducing(self, canvas, visible_dims, **plot_kwargs):
def plot_errorbars_trainset(self, which_data_rows='all',
which_data_ycols='all', fixed_inputs=None,
plot_raw=False, apply_link=False,
plot_raw=False, apply_link=False, label=None, projection='2d',
predict_kw=None, **plot_kwargs):
"""
Plot the errorbars of the GP likelihood on the training data.
@ -150,16 +214,16 @@ def plot_errorbars_trainset(self, which_data_rows='all',
: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
"""
canvas, kwargs = pl.get_new_canvas(plot_kwargs)
canvas, kwargs = pl.get_new_canvas(projection=projection, **plot_kwargs)
plots = _plot_errorbars_trainset(self, canvas, which_data_rows, which_data_ycols,
fixed_inputs, plot_raw, apply_link, predict_kw, **kwargs)
fixed_inputs, plot_raw, apply_link, label, projection, predict_kw, **kwargs)
return pl.show_canvas(canvas, plots)
def _plot_errorbars_trainset(self, canvas,
which_data_rows='all', which_data_ycols='all',
fixed_inputs=None,
plot_raw=False, apply_link=False,
predict_kw=None, **plot_kwargs):
label=None, projection='2d', predict_kw=None, **plot_kwargs):
ycols = get_which_data_ycols(self, which_data_ycols)
rows = get_which_data_rows(self, which_data_rows)
@ -176,9 +240,9 @@ def _plot_errorbars_trainset(self, canvas,
plots = []
if len(free_dims)<2:
if len(free_dims)<=2:
update_not_existing_kwargs(plot_kwargs, pl.defaults.yerrorbar)
if len(free_dims)==1:
update_not_existing_kwargs(plot_kwargs, pl.defaults.yerrorbar)
if predict_kw is None:
predict_kw = {}
if 'Y_metadata' not in predict_kw:
@ -189,8 +253,14 @@ def _plot_errorbars_trainset(self, canvas,
for d in ycols:
plots.append(pl.yerrorbar(canvas, X[rows,free_dims[0]], Y[rows,d],
np.vstack([Y[rows,d]-percs[0][rows,d], percs[1][rows,d]-Y[rows,d]]),
label=label,
**plot_kwargs))
else:
elif len(free_dims) == 2:
plots.append(pl.yerrorbar(canvas, X[rows,free_dims[0]], X[rows,free_dims[1]],
np.vstack([Y[rows,d]-percs[0][rows,d], percs[1][rows,d]-Y[rows,d]]),
Y[rows,d],
label=label,
**plot_kwargs))
pass #Nothing to plot!
else:
raise NotImplementedError("Cannot plot in more then one dimension.")

View file

@ -33,13 +33,14 @@ import numpy as np
from . import pl
from .plot_util import helper_for_plot_data, update_not_existing_kwargs, \
helper_predict_with_model, get_which_data_ycols
from .data_plots import _plot_data, _plot_inducing
from .data_plots import _plot_data, _plot_inducing, _plot_data_error
def plot_mean(self, plot_limits=None, fixed_inputs=None,
resolution=None, plot_raw=False,
apply_link=False, visible_dims=None,
which_data_ycols='all',
levels=20,
levels=20, projection='2d',
label=None,
predict_kw=None,
**kwargs):
"""
@ -56,22 +57,25 @@ def plot_mean(self, plot_limits=None, fixed_inputs=None,
:param bool plot_raw: plot the latent function (usually denoted f) only?
:param bool apply_link: whether to apply the link function of the GP to the raw prediction.
:param array-like which_data_ycols: which columns of y to plot (array-like or list of ints)
:param dict predict_kw: the keyword arguments for the prediction. If you want to plot a specific kernel give dict(kern=<specific kernel>) in here
:param int levels: for 2D plotting, the number of contour levels to use is
: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 dict predict_kw: the keyword arguments for the prediction. If you want to plot a specific kernel give dict(kern=<specific kernel>) in here
"""
canvas, kwargs = pl.get_new_canvas(kwargs)
canvas, kwargs = pl.get_new_canvas(projection=projection, **kwargs)
plots = _plot_mean(self, canvas, plot_limits, fixed_inputs,
resolution, plot_raw,
apply_link, visible_dims, which_data_ycols, levels,
predict_kw, **kwargs)
apply_link, visible_dims, which_data_ycols,
levels, projection, label, predict_kw, **kwargs)
return pl.show_canvas(canvas, plots)
def _plot_mean(self, canvas, plot_limits=None, fixed_inputs=None,
resolution=None, plot_raw=False,
apply_link=False, visible_dims=None,
which_data_ycols=None,
levels=20,
predict_kw=None, **kwargs):
which_data_ycols='all',
levels=20, projection='2d', label=None,
predict_kw=None,
**kwargs):
_, _, _, _, free_dims, Xgrid, x, y, _, _, resolution = helper_for_plot_data(self, plot_limits, visible_dims, fixed_inputs, resolution)
if len(free_dims)<=2:
@ -82,17 +86,25 @@ def _plot_mean(self, canvas, plot_limits=None, fixed_inputs=None,
if len(free_dims)==1:
# 1D plotting:
update_not_existing_kwargs(kwargs, pl.defaults.meanplot_1d) # @UndefinedVariable
return dict(gpmean=[pl.plot(canvas, Xgrid[:, free_dims], mu, **kwargs)])
plots = dict(gpmean=[pl.plot(canvas, Xgrid[:, free_dims], mu, label=label, **kwargs)])
else:
update_not_existing_kwargs(kwargs, pl.defaults.meanplot_2d) # @UndefinedVariable
return dict(gpmean=[pl.contour(canvas, x, y,
mu.reshape(resolution, resolution),
levels=levels, **kwargs)])
if projection == '2d':
update_not_existing_kwargs(kwargs, pl.defaults.meanplot_2d) # @UndefinedVariable
plots = dict(gpmean=[pl.contour(canvas, x, y,
mu.reshape(resolution, resolution),
levels=levels, label=label, **kwargs)])
elif projection == '3d':
update_not_existing_kwargs(kwargs, pl.defaults.meanplot_3d) # @UndefinedVariable
plots = dict(gpmean=[pl.surface(canvas, x, y,
mu.reshape(resolution, resolution),
label=label,
**kwargs)])
elif len(free_dims)==0:
pass # Nothing to plot!
else:
raise RuntimeError('Cannot plot mean in more then 2 input dimensions')
return plots
def plot_confidence(self, lower=2.5, upper=97.5, plot_limits=None, fixed_inputs=None,
resolution=None, plot_raw=False,
apply_link=False, visible_dims=None,
@ -119,7 +131,7 @@ def plot_confidence(self, lower=2.5, upper=97.5, plot_limits=None, fixed_inputs=
:param array-like which_data_ycols: which columns of the output y (!) to plot (array-like or list of ints)
:param dict predict_kw: the keyword arguments for the prediction. If you want to plot a specific kernel give dict(kern=<specific kernel>) in here
"""
canvas, kwargs = pl.get_new_canvas(kwargs)
canvas, kwargs = pl.get_new_canvas(**kwargs)
plots = _plot_confidence(self, canvas, lower, upper, plot_limits,
fixed_inputs, resolution, plot_raw,
apply_link, visible_dims, which_data_ycols,
@ -158,7 +170,7 @@ def plot_samples(self, plot_limits=None, fixed_inputs=None,
resolution=None, plot_raw=True,
apply_link=False, visible_dims=None,
which_data_ycols='all',
samples=3, predict_kw=None,
samples=3, projection='2d', predict_kw=None,
**kwargs):
"""
Plot the mean of the GP.
@ -178,29 +190,37 @@ def plot_samples(self, plot_limits=None, fixed_inputs=None,
:param dict predict_kw: the keyword arguments for the prediction. If you want to plot a specific kernel give dict(kern=<specific kernel>) in here
:param int levels: for 2D plotting, the number of contour levels to use is
"""
canvas, kwargs = pl.get_new_canvas(kwargs)
canvas, kwargs = pl.get_new_canvas(projection=projection, **kwargs)
plots = _plot_samples(self, canvas, plot_limits, fixed_inputs,
resolution, plot_raw,
apply_link, visible_dims, which_data_ycols, samples,
apply_link, visible_dims, which_data_ycols, samples, projection,
predict_kw, **kwargs)
return pl.show_canvas(canvas, plots)
def _plot_samples(self, canvas, plot_limits=None, fixed_inputs=None,
resolution=None, plot_raw=False,
resolution=None, plot_raw=True,
apply_link=False, visible_dims=None,
which_data_ycols=None,
samples=3,
samples=3, projection='2d',
label=None,
predict_kw=None, **kwargs):
_, _, _, _, free_dims, Xgrid, _, _, _, _, resolution = helper_for_plot_data(self, plot_limits, visible_dims, fixed_inputs, resolution)
_, _, _, _, free_dims, Xgrid, x, y, _, _, resolution = helper_for_plot_data(self, plot_limits, visible_dims, fixed_inputs, resolution)
if len(free_dims)<2:
if len(free_dims)<=2:
if len(free_dims)==1:
# 1D plotting:
_, _, samples = helper_predict_with_model(self, Xgrid, plot_raw, apply_link,
None, get_which_data_ycols(self, which_data_ycols), predict_kw, samples)
update_not_existing_kwargs(kwargs, pl.defaults.samples_1d) # @UndefinedVariable
return dict(gpmean=[pl.plot(canvas, Xgrid[:, free_dims], samples, **kwargs)])
elif len(free_dims)==2 and projection=='3d':
_, _, samples = helper_predict_with_model(self, Xgrid, plot_raw, apply_link,
None, get_which_data_ycols(self, which_data_ycols), predict_kw, samples)
update_not_existing_kwargs(kwargs, pl.defaults.samples_3d) # @UndefinedVariable
for s in range(samples.shape[-1]):
return dict(gpmean=[pl.surface(canvas, x,
y, samples[:, s].reshape(resolution, resolution),
**kwargs)])
else:
pass # Nothing to plot!
else:
@ -233,7 +253,7 @@ def plot_density(self, plot_limits=None, fixed_inputs=None,
:param int levels: the number of levels in the density (number bigger then 1, where 35 is smooth and 1 is the same as plot_confidence). You can go higher then 50 if the result is not smooth enough for you.
:param dict predict_kw: the keyword arguments for the prediction. If you want to plot a specific kernel give dict(kern=<specific kernel>) in here
"""
canvas, kwargs = pl.get_new_canvas(kwargs)
canvas, kwargs = pl.get_new_canvas(**kwargs)
plots = _plot_density(self, canvas, plot_limits,
fixed_inputs, resolution, plot_raw,
apply_link, visible_dims, which_data_ycols,
@ -276,13 +296,14 @@ def plot(self, plot_limits=None, fixed_inputs=None,
visible_dims=None,
levels=20, samples=0, samples_likelihood=0, lower=2.5, upper=97.5,
plot_data=True, plot_inducing=True, plot_density=False,
predict_kw=None, error_kwargs=None,
**kwargs):
predict_kw=None, projection='2d', **kwargs):
"""
Convinience function for plotting the fit of a GP.
Give the Y_metadata in the predict_kw if you need it.
If you want fine graned control use the specific plotting functions supplied in the model.
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
:type plot_limits: np.array
:param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input dimension i should be set to value v.
@ -304,14 +325,12 @@ def plot(self, plot_limits=None, fixed_inputs=None,
:param bool plot_inducing: plot inducing inputs?
:param bool plot_density: plot density instead of the confidence interval?
:param dict predict_kw: the keyword arguments for the prediction. If you want to plot a specific kernel give dict(kern=<specific kernel>) in here
:param dict error_kwargs: kwargs for the error plot for the plotting library you are using
:param kwargs plot_kwargs: kwargs for the data plot for the plotting library you are using
"""
canvas, kwargs = pl.get_new_canvas(kwargs)
canvas, _ = pl.get_new_canvas(projection=projection, **kwargs)
plots = _plot(self, canvas, plot_limits, fixed_inputs, resolution, plot_raw,
apply_link, which_data_ycols, which_data_rows, visible_dims,
levels, samples, samples_likelihood, lower, upper, plot_data,
plot_inducing, plot_density, predict_kw, error_kwargs)
plot_inducing, plot_density, projection, predict_kw)
return pl.show_canvas(canvas, plots)
@ -322,13 +341,15 @@ def plot_f(self, plot_limits=None, fixed_inputs=None,
visible_dims=None,
levels=20, samples=0, lower=2.5, upper=97.5,
plot_density=False,
plot_data=True, plot_inducing=True,
predict_kw=None, error_kwargs=None,
plot_data=True, plot_inducing=True,
projection='2d',
predict_kw=None,
**kwargs):
"""
Convinience function for plotting the fit of a GP.
This is the same as plot, except it plots the latent function fit of the GP!
If you want fine graned control use the specific plotting functions supplied in the model.
Give the Y_metadata in the predict_kw if you need it.
@ -354,12 +375,12 @@ def plot_f(self, plot_limits=None, fixed_inputs=None,
:param dict error_kwargs: kwargs for the error plot for the plotting library you are using
:param kwargs plot_kwargs: kwargs for the data plot for the plotting library you are using
"""
canvas, kwargs = pl.get_new_canvas(kwargs)
canvas, _ = pl.get_new_canvas(projection=='3d', **kwargs)
plots = _plot(self, canvas, plot_limits, fixed_inputs, resolution,
True, apply_link, which_data_ycols, which_data_rows,
visible_dims, levels, samples, 0, lower, upper,
plot_data, plot_inducing, plot_density,
predict_kw, error_kwargs)
plot_data, plot_inducing, plot_density, projection,
predict_kw)
return pl.show_canvas(canvas, plots)
@ -370,19 +391,27 @@ def _plot(self, canvas, plot_limits=None, fixed_inputs=None,
which_data_ycols='all', which_data_rows='all',
visible_dims=None,
levels=20, samples=0, samples_likelihood=0, lower=2.5, upper=97.5,
plot_data=True, plot_inducing=True, plot_density=False,
predict_kw=None, error_kwargs=None,
**kwargs):
plot_data=True, plot_inducing=True, plot_density=False, projection='2d',
predict_kw=None):
plots = {}
if plot_raw and not apply_link:
# It does not make sense to plot the data (which lives not in the latent function space) into latent function space.
plot_data = False
if plot_data:
plots.update(_plot_data(self, canvas, which_data_rows, which_data_ycols, visible_dims, error_kwargs))
plots.update(_plot_mean(self, canvas, plot_limits, fixed_inputs, resolution, plot_raw, apply_link, visible_dims, which_data_ycols, levels, predict_kw))
if not plot_density:
plots.update(_plot_confidence(self, canvas, lower, upper, plot_limits, fixed_inputs, resolution, plot_raw, apply_link, visible_dims, which_data_ycols, predict_kw))
else:
plots.update(_plot_density(self, canvas, plot_limits, fixed_inputs, resolution, plot_raw, apply_link, visible_dims, which_data_ycols, levels, predict_kw))
plots.update(_plot_data(self, canvas, which_data_rows, which_data_ycols, visible_dims,
projection, label=None))
plots.update(_plot_data_error(self, canvas, which_data_rows, which_data_ycols, visible_dims,
projection, label=None))
plots.update(_plot_mean(self, canvas, plot_limits, fixed_inputs, resolution, plot_raw, apply_link, visible_dims, which_data_ycols, levels, projection, label=None,
predict_kw=None))
if projection=='2d':
if not plot_density:
plots.update(_plot_confidence(self, canvas, lower, upper, plot_limits, fixed_inputs, resolution, plot_raw, apply_link, visible_dims, which_data_ycols, predict_kw))
else:
plots.update(_plot_density(self, canvas, plot_limits, fixed_inputs, resolution, plot_raw, apply_link, visible_dims, which_data_ycols, levels, predict_kw))
if samples > 0:
plots.update(_plot_samples(self, canvas, plot_limits, fixed_inputs, resolution, True, apply_link, visible_dims, which_data_ycols, samples, predict_kw))
@ -390,6 +419,6 @@ def _plot(self, canvas, plot_limits=None, fixed_inputs=None,
plots.update(_plot_samples(self, canvas, plot_limits, fixed_inputs, resolution, False, apply_link, visible_dims, which_data_ycols, samples, predict_kw))
if hasattr(self, 'Z') and plot_inducing:
plots.update(_plot_inducing(self, canvas, visible_dims))
plots.update(_plot_inducing(self, canvas, visible_dims, projection, None))
return plots

View file

@ -0,0 +1,82 @@
#===============================================================================
# Copyright (c) 2015, Max Zwiessele
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * 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.
#
# * Neither the name of GPy.plotting.gpy_plot.kernel_plots nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# 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
from . import pl
from .. import Tango
def plot_ARD(kernel, filtering=None, **kwargs):
"""
If an ARD kernel is present, plot a bar representation using matplotlib
:param fignum: figure number of the plot
:param filtering: list of names, which to use for plotting ARD parameters.
Only kernels which match names in the list of names in filtering
will be used for plotting.
:type filtering: list of names to use for ARD plot
"""
canvas, kwargs = pl.get_new_canvas(kwargs)
Tango.reset()
bars = []
ard_params = np.atleast_2d(kernel.input_sensitivity(summarize=False))
bottom = 0
last_bottom = bottom
x = np.arange(kernel.input_dim)
if filtering is None:
filtering = kernel.parameter_names(recursive=False)
for i in range(ard_params.shape[0]):
if kernel.parameters[i].name in filtering:
c = Tango.nextMedium()
bars.append(pl.barplot(canvas, x, ard_params[i,:], color=c, label=kernel.parameters[i].name, bottom=bottom))
last_bottom = ard_params[i,:]
bottom += last_bottom
else:
print("filtering out {}".format(kernel.parameters[i].name))
plt.show_canvas()
ax.set_xlim(-.5, kernel.input_dim - .5)
add_bar_labels(fig, ax, [bars[-1]], bottom=bottom-last_bottom)
if legend:
if title is '':
mode = 'expand'
if len(bars) > 1:
mode = 'expand'
ax.legend(bbox_to_anchor=(0., 1.02, 1., 1.02), loc=3,
ncol=len(bars), mode=mode, borderaxespad=0.)
fig.tight_layout(rect=(0, 0, 1, .9))
else:
ax.legend()
return dict(barplots=bars)

View file

@ -0,0 +1,107 @@
#===============================================================================
# Copyright (c) 2015, Max Zwiessele
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * 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.
#
# * Neither the name of GPy.plotting.gpy_plot.latent_plots nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# 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
from . import pl
from .plot_util import get_x_y_var, get_free_dims, get_which_data_ycols,\
get_which_data_rows, update_not_existing_kwargs, helper_predict_with_model,\
helper_for_plot_data
def plot_prediction_fit(self, plot_limits=None,
which_data_rows='all', which_data_ycols='all',
fixed_inputs=None, resolution=None,
plot_raw=False, apply_link=False, visible_dims=None,
predict_kw=None, scatter_kwargs=None, **plot_kwargs):
"""
Plot the fit of the (Bayesian)GPLVM latent space prediction to the outputs.
This scatters two output dimensions against each other and a line
from the prediction in two dimensions between them.
Give the Y_metadata in the predict_kw if you need it.
: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 array-like which_data_ycols: which columns of y to plot (array-like or list of ints)
: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 int resolution: The resolution of the prediction [defaults are 1D:200, 2D:50]
:param bool plot_raw: plot the latent function (usually denoted f) only?
:param bool apply_link: whether to apply the link function of the GP to the raw prediction.
:param array-like visible_dims: which columns of the input X (!) to plot (array-like or list of ints)
:param dict predict_kw: the keyword arguments for the prediction. If you want to plot a specific kernel give dict(kern=<specific kernel>) in here
:param dict sactter_kwargs: kwargs for the scatter plot, specific for the plotting library you are using
:param kwargs plot_kwargs: kwargs for the data plot for the plotting library you are using
"""
canvas, kwargs = pl.get_new_canvas(plot_kwargs)
plots = _plot_prediction_fit(self, canvas, plot_limits, which_data_rows, which_data_ycols,
fixed_inputs, resolution, plot_raw,
apply_link, visible_dims,
predict_kw, scatter_kwargs, **kwargs)
return pl.show_canvas(canvas, plots)
def _plot_prediction_fit(self, canvas, plot_limits=None,
which_data_rows='all', which_data_ycols='all',
fixed_inputs=None, resolution=None,
plot_raw=False, apply_link=False, visible_dims=False,
predict_kw=None, scatter_kwargs=None, **plot_kwargs):
ycols = get_which_data_ycols(self, which_data_ycols)
rows = get_which_data_rows(self, which_data_rows)
if visible_dims is None:
visible_dims = self.get_most_significant_input_dimensions()[:1]
X, _, Y, _, free_dims, Xgrid, _, _, _, _, resolution = helper_for_plot_data(self, plot_limits, visible_dims, fixed_inputs, resolution)
plots = {}
if len(free_dims)<2:
if len(free_dims)==1:
if scatter_kwargs is None:
scatter_kwargs = {}
update_not_existing_kwargs(scatter_kwargs, pl.defaults.data_y_1d) # @UndefinedVariable
plots['output'] = pl.scatter(canvas, Y[rows, ycols[0]], Y[rows, ycols[1]],
c=X[rows, free_dims[0]],
**scatter_kwargs)
if predict_kw is None:
predict_kw = {}
mu, _, _ = helper_predict_with_model(self, Xgrid, plot_raw,
apply_link, None,
ycols, predict_kw)
update_not_existing_kwargs(plot_kwargs, pl.defaults.data_y_1d_plot) # @UndefinedVariable
plots['output_fit'] = pl.plot(canvas, mu[:, 0], mu[:, 1], **plot_kwargs)
else:
pass #Nothing to plot!
else:
raise NotImplementedError("Cannot plot in more then one dimension.")
return plots

View file

@ -1,19 +1,20 @@
# Copyright (c) 2014, GPy authors (see AUTHORS.txt).
# Licensed under the BSD 3-clause license (see LICENSE.txt)
from . import base_plots
from . import models_plots
from . import priors_plots
from . import variational_plots
from . import kernel_plots
from . import dim_reduction_plots
from . import mapping_plots
from GPy.plotting.gpy_plot import Tango
from . import visualize
from . import latent_space_visualizations
from . import inference_plots
from . import maps
from . import img_plots
from .ssgplvm import SSGPLVM_plot
# from . import base_plots
# from . import models_plots
# from . import priors_plots
# from . import variational_plots
# from . import kernel_plots
# from . import dim_reduction_plots
# from . import mapping_plots
# from GPy.plotting.gpy_plot import Tango
# from . import visualize
# from . import latent_space_visualizations
# from . import inference_plots
# from . import maps
# from . import img_plots
# from .ssgplvm import SSGPLVM_plot
from util import align_subplot_array, align_subplots, fewerXticks, removeRightTicks, removeUpperTicks

View file

@ -1,265 +0,0 @@
# #Copyright (c) 2012, GPy authors (see AUTHORS.txt).
# Licensed under the BSD 3-clause license (see LICENSE.txt)
from matplotlib import pyplot as plt
import numpy as np
def ax_default(fignum, ax):
if ax is None:
fig = plt.figure(fignum)
ax = fig.add_subplot(111)
else:
fig = ax.figure
return fig, ax
def meanplot(x, mu, color='#3300FF', ax=None, fignum=None, linewidth=2,**kw):
_, axes = ax_default(fignum, ax)
return axes.plot(x,mu,color=color,linewidth=linewidth,**kw)
def gpplot(x, mu, lower, upper, edgecol='#3300FF', fillcol='#33CCFF', ax=None, fignum=None, **kwargs):
_, axes = ax_default(fignum, ax)
mu = mu.flatten()
x = x.flatten()
lower = lower.flatten()
upper = upper.flatten()
plots = []
#here's the mean
plots.append(meanplot(x, mu, edgecol, axes))
#here's the box
kwargs['linewidth']=0.5
if not 'alpha' in kwargs.keys():
kwargs['alpha'] = 0.3
plots.append(axes.fill(np.hstack((x,x[::-1])),np.hstack((upper,lower[::-1])),color=fillcol,**kwargs))
#this is the edge:
plots.append(meanplot(x, upper,color=edgecol, linewidth=0.2, ax=axes))
plots.append(meanplot(x, lower,color=edgecol, linewidth=0.2, ax=axes))
return plots
def gradient_fill(x, percentiles, ax=None, fignum=None, **kwargs):
_, ax = ax_default(fignum, ax)
plots = []
#here's the box
if 'linewidth' not in kwargs:
kwargs['linewidth'] = 0.5
if not 'alpha' in kwargs.keys():
kwargs['alpha'] = 1./(len(percentiles))
# pop where from kwargs
where = kwargs.pop('where') if 'where' in kwargs else None
# pop interpolate, which we actually do not do here!
if 'interpolate' in kwargs: kwargs.pop('interpolate')
def pairwise(inlist):
l = len(inlist)
for i in range(int(np.ceil(l/2.))):
yield inlist[:][i], inlist[:][(l-1)-i]
polycol = []
for y1, y2 in pairwise(percentiles):
import matplotlib.mlab as mlab
# Handle united data, such as dates
ax._process_unit_info(xdata=x, ydata=y1)
ax._process_unit_info(ydata=y2)
# Convert the arrays so we can work with them
from numpy import ma
x = ma.masked_invalid(ax.convert_xunits(x))
y1 = ma.masked_invalid(ax.convert_yunits(y1))
y2 = ma.masked_invalid(ax.convert_yunits(y2))
if y1.ndim == 0:
y1 = np.ones_like(x) * y1
if y2.ndim == 0:
y2 = np.ones_like(x) * y2
if where is None:
where = np.ones(len(x), np.bool)
else:
where = np.asarray(where, np.bool)
if not (x.shape == y1.shape == y2.shape == where.shape):
raise ValueError("Argument dimensions are incompatible")
mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)])
if mask is not ma.nomask:
where &= ~mask
polys = []
for ind0, ind1 in mlab.contiguous_regions(where):
xslice = x[ind0:ind1]
y1slice = y1[ind0:ind1]
y2slice = y2[ind0:ind1]
if not len(xslice):
continue
N = len(xslice)
X = np.zeros((2 * N + 2, 2), np.float)
# the purpose of the next two lines is for when y2 is a
# scalar like 0 and we want the fill to go all the way
# down to 0 even if none of the y1 sample points do
start = xslice[0], y2slice[0]
end = xslice[-1], y2slice[-1]
X[0] = start
X[N + 1] = end
X[1:N + 1, 0] = xslice
X[1:N + 1, 1] = y1slice
X[N + 2:, 0] = xslice[::-1]
X[N + 2:, 1] = y2slice[::-1]
polys.append(X)
polycol.extend(polys)
from matplotlib.collections import PolyCollection
plots.append(PolyCollection(polycol, **kwargs))
ax.add_collection(plots[-1], autolim=True)
ax.autoscale_view()
return plots
def gperrors(x, mu, lower, upper, edgecol=None, ax=None, fignum=None, **kwargs):
_, axes = ax_default(fignum, ax)
mu = mu.flatten()
x = x.flatten()
lower = lower.flatten()
upper = upper.flatten()
plots = []
if edgecol is None:
edgecol='#3300FF'
if not 'alpha' in kwargs.keys():
kwargs['alpha'] = 1.
if not 'lw' in kwargs.keys():
kwargs['lw'] = 1.
plots.append(axes.errorbar(x,mu,yerr=np.vstack([mu-lower,upper-mu]),color=edgecol,**kwargs))
plots[-1][0].remove()
return plots
def removeRightTicks(ax=None):
ax = ax or plt.gca()
for i, line in enumerate(ax.get_yticklines()):
if i%2 == 1: # odd indices
line.set_visible(False)
def removeUpperTicks(ax=None):
ax = ax or plt.gca()
for i, line in enumerate(ax.get_xticklines()):
if i%2 == 1: # odd indices
line.set_visible(False)
def fewerXticks(ax=None,divideby=2):
ax = ax or plt.gca()
ax.set_xticks(ax.get_xticks()[::divideby])
def align_subplots(N,M,xlim=None, ylim=None):
"""make all of the subplots have the same limits, turn off unnecessary ticks"""
#find sensible xlim,ylim
if xlim is None:
xlim = [np.inf,-np.inf]
for i in range(N*M):
plt.subplot(N,M,i+1)
xlim[0] = min(xlim[0],plt.xlim()[0])
xlim[1] = max(xlim[1],plt.xlim()[1])
if ylim is None:
ylim = [np.inf,-np.inf]
for i in range(N*M):
plt.subplot(N,M,i+1)
ylim[0] = min(ylim[0],plt.ylim()[0])
ylim[1] = max(ylim[1],plt.ylim()[1])
for i in range(N*M):
plt.subplot(N,M,i+1)
plt.xlim(xlim)
plt.ylim(ylim)
if (i)%M:
plt.yticks([])
else:
removeRightTicks()
if i<(M*(N-1)):
plt.xticks([])
else:
removeUpperTicks()
def align_subplot_array(axes,xlim=None, ylim=None):
"""
Make all of the axes in the array hae the same limits, turn off unnecessary ticks
use plt.subplots() to get an array of axes
"""
#find sensible xlim,ylim
if xlim is None:
xlim = [np.inf,-np.inf]
for ax in axes.flatten():
xlim[0] = min(xlim[0],ax.get_xlim()[0])
xlim[1] = max(xlim[1],ax.get_xlim()[1])
if ylim is None:
ylim = [np.inf,-np.inf]
for ax in axes.flatten():
ylim[0] = min(ylim[0],ax.get_ylim()[0])
ylim[1] = max(ylim[1],ax.get_ylim()[1])
N,M = axes.shape
for i,ax in enumerate(axes.flatten()):
ax.set_xlim(xlim)
ax.set_ylim(ylim)
if (i)%M:
ax.set_yticks([])
else:
removeRightTicks(ax)
if i<(M*(N-1)):
ax.set_xticks([])
else:
removeUpperTicks(ax)
def x_frame1D(X,plot_limits=None,resolution=None):
"""
Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits
"""
assert X.shape[1] ==1, "x_frame1D is defined for one-dimensional inputs"
if plot_limits is None:
from ...core.parameterization.variational import VariationalPosterior
if isinstance(X, VariationalPosterior):
xmin,xmax = X.mean.min(0),X.mean.max(0)
else:
xmin,xmax = X.min(0),X.max(0)
xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin)
elif len(plot_limits)==2:
xmin, xmax = plot_limits
else:
raise ValueError("Bad limits for plotting")
Xnew = np.linspace(xmin,xmax,resolution or 200)[:,None]
return Xnew, xmin, xmax
def x_frame2D(X,plot_limits=None,resolution=None):
"""
Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits
"""
assert X.shape[1] ==2, "x_frame2D is defined for two-dimensional inputs"
if plot_limits is None:
xmin,xmax = X.min(0),X.max(0)
xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin)
elif len(plot_limits)==2:
xmin, xmax = plot_limits
else:
raise ValueError("Bad limits for plotting")
resolution = resolution or 50
xx,yy = np.mgrid[xmin[0]:xmax[0]:1j*resolution,xmin[1]:xmax[1]:1j*resolution]
Xnew = np.vstack((xx.flatten(),yy.flatten())).T
return Xnew, xx, yy, xmin, xmax

View file

@ -28,9 +28,8 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#===============================================================================
from matplotlib.colors import LinearSegmentedColormap
from matplotlib import cm
from GPy.plotting.gpy_plot import Tango
from .. import Tango
'''
This file is for defaults for the gpy plot, specific to the plotting library.
@ -48,15 +47,18 @@ data_1d = dict(lw=1.5, marker='x', edgecolor='k')
data_2d = dict(s=35, edgecolors='none', linewidth=0., cmap=cm.get_cmap('hot'), alpha=.5)
inducing_1d = dict(lw=0, s=500, facecolors=Tango.colorsHex['darkRed'])
inducing_2d = dict(s=14, edgecolors='k', linewidth=.4, facecolors='white', alpha=.5)
inducing_3d = dict(lw=.3, s=500, facecolors='white', edgecolors='k')
xerrorbar = dict(color='k', fmt='none', elinewidth=.5, alpha=.5)
yerrorbar = dict(color=Tango.colorsHex['darkRed'], fmt='none', elinewidth=.5, alpha=.5)
# GP plots:
meanplot_1d = dict(color=Tango.colorsHex['mediumBlue'], linewidth=2)
meanplot_2d = dict(cmap='hot', linewidth=.5)
meanplot_3d = dict(linewidth=0, antialiased=True, cstride=1, rstride=1, cmap='hot', alpha=.3)
samples_1d = dict(color=Tango.colorsHex['mediumBlue'], linewidth=.3)
samples_3d = dict(cmap='hot', alpha=.1, antialiased=True, cstride=1, rstride=1, linewidth=0)
confidence_interval = dict(edgecolor=Tango.colorsHex['darkBlue'], linewidth=.5, color=Tango.colorsHex['lightBlue'],alpha=.2)
density = dict(alpha=.5, color=Tango.colorsHex['mediumBlue'])
density = dict(alpha=.5, color=Tango.colorsHex['lightBlue'])
# GPLVM plots:
data_y_1d = dict(linewidth=0, cmap='RdBu', s=40)

View file

@ -7,7 +7,7 @@ from ...core.parameterization.variational import VariationalPosterior
from .base_plots import x_frame2D
import itertools
try:
from GPy.plotting.gpy_plot import Tango
from GPy.plotting import Tango
from matplotlib.cm import get_cmap
from matplotlib import pyplot as pb
from matplotlib import cm

View file

@ -3,7 +3,7 @@
import numpy as np
try:
from GPy.plotting.gpy_plot import Tango
from GPy.plotting import Tango
from matplotlib import pyplot as pb
except:
pass

View file

@ -1,506 +0,0 @@
# Copyright (c) 2012-2015, GPy authors (see AUTHORS.txt).
# Licensed under the BSD 3-clause license (see LICENSE.txt)
import numpy as np
from .base_plots import gpplot, x_frame1D, x_frame2D,gperrors
from ...models.gp_coregionalized_regression import GPCoregionalizedRegression
from ...models.sparse_gp_coregionalized_regression import SparseGPCoregionalizedRegression
from scipy import sparse
from ...core.parameterization.variational import VariationalPosterior
from matplotlib import pyplot as plt
from .base_plots import gradient_fill
from functools import wraps
from .gpy_plot import Tango
def plot_data(self, which_data_rows='all',
which_data_ycols='all', visible_dims=None,
fignum=None, ax=None, data_symbol='kx',mew=1.5,**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_rows: '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 fignum: figure to plot on.
:type fignum: figure number
:param ax: axes to plot on.
:type ax: axes handle
"""
#deal with optional arguments
if which_data_rows == 'all':
which_data_rows = slice(None)
if which_data_ycols == 'all':
which_data_ycols = np.arange(self.output_dim)
if ax is None:
fig = plt.figure(num=fignum)
ax = fig.add_subplot(111)
if hasattr(self, 'has_uncertain_inputs') and self.has_uncertain_inputs():
X = self.X.mean
X_variance = self.X.variance
else:
X = self.X
X_variance = None
Y = self.Y
#work out what the inputs are for plotting (1D or 2D)
if visible_dims is None:
visible_dims = np.arange(self.input_dim)
assert visible_dims.size <= 2, "Visible inputs cannot be larger than two"
free_dims = visible_dims
plots = {}
#one dimensional plotting
if len(free_dims) == 1:
plots['dataplot'] = []
if X_variance is not None: plots['xerrorbar'] = []
for d in which_data_ycols:
plots['dataplot'].append(ax.plot(X[which_data_rows, free_dims], Y[which_data_rows, d], data_symbol, mew=mew))
if X_variance is not None:
plots['xerrorbar'] = ax.errorbar(X[which_data_rows, free_dims].flatten(), Y[which_data_rows, d].flatten(),
xerr=2 * np.sqrt(X_variance[which_data_rows, free_dims].flatten()),
ecolor='k', fmt='none', elinewidth=.5, alpha=.5)
#2D plotting
elif len(free_dims) == 2:
for d in which_data_ycols:
plots['dataplot'] = ax.scatter(X[which_data_rows, free_dims[0]], X[which_data_rows, free_dims[1]], 40,
Y[which_data_rows, d], cmap=plt.cm.jet, vmin=Y.min(), vmax=Y.max(), linewidth=0.)
else:
raise NotImplementedError("Cannot define a frame with more than two input dimensions")
return plots
def plot_fit(self, plot_limits=None, which_data_rows='all',
which_data_ycols='all', fixed_inputs=[],
levels=20, samples=0, fignum=None, ax=None, resolution=None,
plot_raw=False,
linecol=Tango.colorsHex['darkBlue'],fillcol=Tango.colorsHex['lightBlue'], Y_metadata=None, data_symbol='kx',
apply_link=False, samples_y=0, plot_uncertain_inputs=True, predict_kw=None, plot_training_data=True):
"""
Plot the posterior of the GP.
- In one dimension, the function is plotted with a shaded region identifying two standard deviations.
- In two dimsensions, a contour-plot shows the mean predicted function
- In higher dimensions, use fixed_inputs to plot the GP with some of the inputs fixed.
Can plot only part of the data and part of the posterior functions
using which_data_rowsm which_data_ycols.
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
:type plot_limits: np.array
: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_rows: 'all' or a list of integers
:param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
:type fixed_inputs: a list of tuples
:param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure
:type levels: int
:param samples: the number of a posteriori samples to plot p(f*|y)
:type samples: int
:param fignum: figure to plot on.
:type fignum: figure number
:param ax: axes to plot on.
:type ax: axes handle
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
:type resolution: int
:param plot_raw: Whether to plot the raw function p(f|y)
:type plot_raw: boolean
:param linecol: color of line to plot.
:type linecol: hex or color
:param fillcol: color of fill
:type fillcol: hex or color
:param apply_link: apply the link function if plotting f (default false), as well as posterior samples if requested
:type apply_link: boolean
:param samples_y: the number of posteriori f samples to plot p(y*|y)
:type samples_y: int
:param plot_uncertain_inputs: plot the uncertainty of the inputs as error bars if they have uncertainty (BGPLVM etc.)
:type plot_uncertain_inputs: boolean
:param predict_kw: keyword args for _raw_predict and predict functions if required
:type predict_kw: dict
:param plot_training_data: whether or not to plot the training points
:type plot_training_data: boolean
"""
#deal with optional arguments
if which_data_rows == 'all':
which_data_rows = slice(None)
if which_data_ycols == 'all':
which_data_ycols = np.arange(self.output_dim)
#if len(which_data_ycols)==0:
#raise ValueError('No data selected for plotting')
if ax is None:
fig = plt.figure(num=fignum)
ax = fig.add_subplot(111)
if hasattr(self, 'has_uncertain_inputs') and self.has_uncertain_inputs():
X = self.X.mean
X_variance = self.X.variance
else:
X = self.X
Y = self.Y
if sparse.issparse(Y): Y = Y.todense().view(np.ndarray)
if hasattr(self, 'Z'): Z = self.Z
if predict_kw is None:
predict_kw = {}
#work out what the inputs are for plotting (1D or 2D)
fixed_dims = np.array([i for i,v in fixed_inputs])
free_dims = np.setdiff1d(np.arange(self.input_dim),fixed_dims)
plots = {}
#one dimensional plotting
if len(free_dims) == 1:
#define the frame on which to plot
Xnew, xmin, xmax = x_frame1D(X[:,free_dims], plot_limits=plot_limits, resolution=resolution or 200)
Xgrid = np.empty((Xnew.shape[0],self.input_dim))
Xgrid[:,free_dims] = Xnew
for i,v in fixed_inputs:
Xgrid[:,i] = v
#make a prediction on the frame and plot it
if plot_raw:
m, v = self._raw_predict(Xgrid, **predict_kw)
if apply_link:
lower = self.likelihood.gp_link.transf(m - 2*np.sqrt(v))
upper = self.likelihood.gp_link.transf(m + 2*np.sqrt(v))
#Once transformed this is now the median of the function
m = self.likelihood.gp_link.transf(m)
else:
lower = m - 2*np.sqrt(v)
upper = m + 2*np.sqrt(v)
else:
if isinstance(self,GPCoregionalizedRegression) or isinstance(self,SparseGPCoregionalizedRegression):
extra_data = Xgrid[:,-1:].astype(np.int)
if Y_metadata is None:
Y_metadata = {'output_index': extra_data}
else:
Y_metadata['output_index'] = extra_data
m, v = self.predict(Xgrid, full_cov=False, Y_metadata=Y_metadata, **predict_kw)
fmu, fv = self._raw_predict(Xgrid, full_cov=False, **predict_kw)
lower, upper = self.likelihood.predictive_quantiles(fmu, fv, (2.5, 97.5), Y_metadata=Y_metadata)
for d in which_data_ycols:
plots['gpplot'] = gpplot(Xnew, m[:, d], lower[:, d], upper[:, d], ax=ax, edgecol=linecol, fillcol=fillcol)
#if not plot_raw: plots['dataplot'] = ax.plot(X[which_data_rows,free_dims], Y[which_data_rows, d], data_symbol, mew=1.5)
if not plot_raw and plot_training_data:
plots['dataplot'] = plot_data(self=self, which_data_rows=which_data_rows,
visible_dims=free_dims, data_symbol=data_symbol, mew=1.5, ax=ax, fignum=fignum)
#optionally plot some samples
if samples: #NOTE not tested with fixed_inputs
Fsim = self.posterior_samples_f(Xgrid, samples)
if apply_link:
Fsim = self.likelihood.gp_link.transf(Fsim)
for fi in Fsim.T:
plots['posterior_samples'] = ax.plot(Xnew, fi[:,None], '#3300FF', linewidth=0.25)
#ax.plot(Xnew, fi[:,None], marker='x', linestyle='--',color=Tango.colorsHex['darkBlue']) #TODO apply this line for discrete outputs.
if samples_y: #NOTE not tested with fixed_inputs
Ysim = self.posterior_samples(Xgrid, samples_y, Y_metadata=Y_metadata)
for yi in Ysim.T:
plots['posterior_samples_y'] = ax.scatter(Xnew, yi[:,None], s=5, c=Tango.colorsHex['darkBlue'], marker='o', alpha=0.5)
#ax.plot(Xnew, yi[:,None], marker='x', linestyle='--',color=Tango.colorsHex['darkBlue']) #TODO apply this line for discrete outputs.
#add error bars for uncertain (if input uncertainty is being modelled)
if hasattr(self,"has_uncertain_inputs") and self.has_uncertain_inputs() and plot_uncertain_inputs:
if plot_raw:
#add error bars for uncertain (if input uncertainty is being modelled), for plot_f
#Hack to plot error bars on latent function, rather than on the data
vs = self.X.mean.values.copy()
for i,v in fixed_inputs:
vs[:,i] = v
m_X, _ = self._raw_predict(vs)
if apply_link:
m_X = self.likelihood.gp_link.transf(m_X)
plots['xerrorbar'] = ax.errorbar(X[which_data_rows, free_dims].flatten(), m_X[which_data_rows, which_data_ycols].flatten(),
xerr=2 * np.sqrt(X_variance[which_data_rows, free_dims].flatten()),
ecolor='k', fmt=None, elinewidth=.5, alpha=.5)
#set the limits of the plot to some sensible values
try:
ymin, ymax = min(np.append(Y[which_data_rows, which_data_ycols].flatten(), lower)), max(np.append(Y[which_data_rows, which_data_ycols].flatten(), upper))
if ymin != ymax:
ymin, ymax = ymin - 0.1 * (ymax - ymin), ymax + 0.1 * (ymax - ymin)
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
except:
# do nothing
# No training data on model
pass
#add inducing inputs (if a sparse model is used)
if hasattr(self,"Z"):
#Zu = self.Z[:,free_dims] * self._Xscale[:,free_dims] + self._Xoffset[:,free_dims]
if isinstance(self,SparseGPCoregionalizedRegression):
Z = Z[Z[:,-1] == Y_metadata['output_index'],:]
Zu = Z[:,free_dims]
z_height = ax.get_ylim()[0]
plots['inducing_inputs'] = ax.plot(Zu, np.zeros_like(Zu) + z_height, 'r|', mew=1.5, markersize=12)
#2D plotting
elif len(free_dims) == 2:
#define the frame for plotting on
resolution = resolution or 50
Xnew, x, y, xmin, xmax = x_frame2D(X[:,free_dims], plot_limits, resolution)
Xgrid = np.empty((Xnew.shape[0],self.input_dim))
Xgrid[:,free_dims] = Xnew
for i,v in fixed_inputs:
Xgrid[:,i] = v
#x, y = np.linspace(xmin[0], xmax[0], resolution), np.linspace(xmin[1], xmax[1], resolution)
#predict on the frame and plot
if plot_raw:
m, _ = self._raw_predict(Xgrid, **predict_kw)
else:
if isinstance(self,GPCoregionalizedRegression) or isinstance(self,SparseGPCoregionalizedRegression):
extra_data = Xgrid[:,-1:].astype(np.int)
if Y_metadata is None:
Y_metadata = {'output_index': extra_data}
else:
Y_metadata['output_index'] = extra_data
m, v = self.predict(Xgrid, full_cov=False, Y_metadata=Y_metadata, **predict_kw)
for d in which_data_ycols:
m_d = m[:,d].reshape(resolution, resolution).T
plots['contour'] = ax.contour(x, y, m_d, levels, vmin=m.min(), vmax=m.max(), cmap=plt.cm.jet)
#if not plot_raw: plots['dataplot'] = ax.scatter(X[which_data_rows, free_dims[0]], X[which_data_rows, free_dims[1]], 40, Y[which_data_rows, d], cmap=plt.cm.jet, vmin=m.min(), vmax=m.max(), linewidth=0.)
if not plot_raw and plot_training_data:
plots['dataplot'] = ax.scatter(X[which_data_rows, free_dims[0]], X[which_data_rows, free_dims[1]], 40, Y[which_data_rows, d], cmap=plt.cm.jet, vmin=m.min(), vmax=m.max(), linewidth=0.)
#set the limits of the plot to some sensible values
ax.set_xlim(xmin[0], xmax[0])
ax.set_ylim(xmin[1], xmax[1])
if samples:
warnings.warn("Samples are rather difficult to plot for 2D inputs...")
#add inducing inputs (if a sparse self is used)
if hasattr(self,"Z"):
#Zu = self.Z[:,free_dims] * self._Xscale[:,free_dims] + self._Xoffset[:,free_dims]
Zu = Z[:,free_dims]
plots['inducing_inputs'] = ax.plot(Zu[:,0], Zu[:,1], 'wo')
else:
raise NotImplementedError("Cannot define a frame with more than two input dimensions")
return plots
def plot_density(self, levels=20, plot_limits=None,
fixed_inputs=[], plot_raw=False, edgecolor='none', facecolor='#3465a4',
predict_kw=None,Y_metadata=None,
apply_link=False, resolution=200, **patch_kwargs):
"""
Plot the posterior density of the GP.
- In one dimension, the function is plotted with a shaded gradient, visualizing the density of the posterior.
- Only implemented for one dimension, for higher dimensions use `plot`.
:param levels: number of levels to plot in the density plot. This is a number between 1 and 100. 1 corresponds to the normal plot_fit.
:type levels: int
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
:type plot_limits: np.array
:param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
:type fixed_inputs: a list of tuples
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
:type resolution: int
:param edgecolor: color of line to plot [Tango.colorsHex['darkBlue']]
:type edgecolor: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib
:param facecolor: color of fill [Tango.colorsHex['lightBlue']]
:type facecolor: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib
:param Y_metadata: additional data associated with Y which may be needed
:type Y_metadata: dict
:param apply_link: if there is a link function of the likelihood, plot the link(f*) rather than f*, when plotting posterior samples f
:type apply_link: boolean
:param resolution: resolution of interpolation (how many points to interpolate of the posterior).
:type resolution: int
:param: patch_kw: the keyword arguments for the patchcollection fill.
"""
#deal with optional arguments
if hasattr(self, 'has_uncertain_inputs') and self.has_uncertain_inputs():
X = self.X.mean
else:
X = self.X
Y = self.Y
if sparse.issparse(Y): Y = Y.todense().view(np.ndarray)
if predict_kw is None:
predict_kw = {}
#work out what the inputs are for plotting (1D or 2D)
fixed_dims = np.array([i for i,v in fixed_inputs])
free_dims = np.setdiff1d(np.arange(self.input_dim),fixed_dims)
plots = {}
#one dimensional plotting
if len(free_dims) == 1:
#define the frame on which to plot
Xnew, xmin, xmax = x_frame1D(X[:,free_dims], plot_limits=plot_limits, resolution=resolution)
Xgrid = np.empty((Xnew.shape[0],self.input_dim))
Xgrid[:,free_dims] = Xnew
for i,v in fixed_inputs:
Xgrid[:,i] = v
percs = np.linspace(2.5, 97.5, levels*2)
#make a prediction on the frame and plot it
if plot_raw:
from scipy import stats
from ...likelihoods import Gaussian
lik = Gaussian(variance=0)
else:
if isinstance(self,GPCoregionalizedRegression) or isinstance(self,SparseGPCoregionalizedRegression):
extra_data = Xgrid[:,-1:].astype(np.int)
if Y_metadata is None:
Y_metadata = {'output_index': extra_data}
else:
Y_metadata['output_index'] = extra_data
lik = None
percentiles = [i[:, 0] for i in self.predict_quantiles(Xgrid, percs, Y_metadata=Y_metadata, likelihood=lik, **predict_kw)]
if apply_link:
percentiles = self.likelihood.gp_link.transf(percentiles)
patch_kwargs['facecolor'] = facecolor
patch_kwargs['edgecolor'] = edgecolor
plots['density'] = gradient_fill(Xgrid[:, 0], percentiles, **patch_kwargs)
else:
raise NotImplementedError('Only 1D density plottable.')
return plots
@wraps(plot_fit)
def plot_fit_f(self, plot_limits=None, which_data_rows='all',
which_data_ycols='all', fixed_inputs=[],
levels=20, samples=0, fignum=None, ax=None, resolution=None,
plot_raw=True,
linecol=Tango.colorsHex['darkBlue'],fillcol=Tango.colorsHex['lightBlue'], Y_metadata=None, data_symbol='kx',
apply_link=False, samples_y=0, plot_uncertain_inputs=True, predict_kw=None, plot_training_data=True):
return plot_fit(self, plot_limits, which_data_rows, which_data_ycols, fixed_inputs, levels, samples, fignum, ax, resolution, plot_raw, linecol, fillcol, Y_metadata, data_symbol, apply_link, samples_y, plot_uncertain_inputs, predict_kw, plot_training_data)
def fixed_inputs(model, non_fixed_inputs, fix_routine='median', as_list=True, X_all=False):
"""
Convenience function for returning back fixed_inputs where the other inputs
are fixed using fix_routine
:param model: model
:type model: Model
:param non_fixed_inputs: dimensions of non fixed inputs
:type non_fixed_inputs: list
:param fix_routine: fixing routine to use, 'mean', 'median', 'zero'
:type fix_routine: string
:param as_list: if true, will return a list of tuples with (dimension, fixed_val) otherwise it will create the corresponding X matrix
:type as_list: boolean
"""
f_inputs = []
if hasattr(model, 'has_uncertain_inputs') and model.has_uncertain_inputs():
X = model.X.mean.values.copy()
elif isinstance(model.X, VariationalPosterior):
X = model.X.values.copy()
else:
if X_all:
X = model.X_all.copy()
else:
X = model.X.copy()
for i in range(X.shape[1]):
if i not in non_fixed_inputs:
if fix_routine == 'mean':
f_inputs.append( (i, np.mean(X[:,i])) )
if fix_routine == 'median':
f_inputs.append( (i, np.median(X[:,i])) )
else: # set to zero zero
f_inputs.append( (i, 0) )
if not as_list:
X[:,i] = f_inputs[-1][1]
if as_list:
return f_inputs
else:
return X
def plot_errorbars_trainset(model, which_data_rows='all',
which_data_ycols='all', fixed_inputs=[],
fignum=None, ax=None,
linecol='red', data_symbol='kx',
predict_kw=None, plot_training_data=True, **kwargs):
"""
Plot the posterior error bars corresponding to 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 model.X, model.Y
:param which_data_ycols: when the data has several columns (independant outputs), only plot these
:type which_data_rows: 'all' or a list of integers
:param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
:type fixed_inputs: a list of tuples
:param fignum: figure to plot on.
:type fignum: figure number
:param ax: axes to plot on.
:type ax: axes handle
:param plot_training_data: whether or not to plot the training points
:type plot_training_data: boolean
"""
#deal with optional arguments
if which_data_rows == 'all':
which_data_rows = slice(None)
if which_data_ycols == 'all':
which_data_ycols = np.arange(model.output_dim)
if ax is None:
fig = plt.figure(num=fignum)
ax = fig.add_subplot(111)
X = model.X
Y = model.Y
if predict_kw is None:
predict_kw = {}
#work out what the inputs are for plotting (1D or 2D)
fixed_dims = np.array([i for i,v in fixed_inputs])
free_dims = np.setdiff1d(np.arange(model.input_dim),fixed_dims)
plots = {}
#one dimensional plotting
if len(free_dims) == 1:
m, v = model.predict(X, full_cov=False, Y_metadata=model.Y_metadata, **predict_kw)
fmu, fv = model._raw_predict(X, full_cov=False, **predict_kw)
lower, upper = model.likelihood.predictive_quantiles(fmu, fv, (2.5, 97.5), Y_metadata=model.Y_metadata)
for d in which_data_ycols:
plots['gperrors'] = gperrors(X, m[:, d], lower[:, d], upper[:, d], edgecol=linecol, ax=ax, fignum=fignum, **kwargs )
if plot_training_data:
plots['dataplot'] = plot_data(self=model, which_data_rows=which_data_rows,
visible_dims=free_dims, data_symbol=data_symbol, mew=1.5, ax=ax, fignum=fignum)
#set the limits of the plot to some sensible values
ymin, ymax = min(np.append(Y[which_data_rows, which_data_ycols].flatten(), lower)), max(np.append(Y[which_data_rows, which_data_ycols].flatten(), upper))
ymin, ymax = ymin - 0.1 * (ymax - ymin), ymax + 0.1 * (ymax - ymin)
ax.set_xlim(X[:,free_dims].min(), X[:,free_dims].max())
ax.set_ylim(ymin, ymax)
elif len(free_dims) == 2:
raise NotImplementedError("Not implemented yet")
else:
raise NotImplementedError("Cannot define a frame with more than two input dimensions")
return plots

View file

@ -30,6 +30,7 @@
import numpy as np
from matplotlib import pyplot as plt
from ..abstract_plotting_library import AbstractPlottingLibrary
from .. import Tango
from . import defaults
from matplotlib.colors import LinearSegmentedColormap
@ -38,75 +39,81 @@ class MatplotlibPlots(AbstractPlottingLibrary):
super(MatplotlibPlots, self).__init__()
self._defaults = defaults.__dict__
def get_new_canvas(self, plot_3d=False, kwargs):
if plot_3d:
from matplotlib.mplot3d import Axis3D # @UnusedImport
pr = '3d'
else: pr=None
def get_new_canvas(self, xlabel=None, ylabel=None, zlabel=None, title=None, legend=True, projection='2d', **kwargs):
if projection == '3d':
from mpl_toolkits.mplot3d import Axes3D
elif projection == '2d':
projection = None
if 'ax' in kwargs:
ax = kwargs.pop('ax')
elif 'num' in kwargs and 'figsize' in kwargs:
ax = plt.figure(num=kwargs.pop('num'), figsize=kwargs.pop('figsize')).add_subplot(111, projection=pr)
ax = plt.figure(num=kwargs.pop('num'), figsize=kwargs.pop('figsize')).add_subplot(111, projection=projection)
elif 'num' in kwargs:
ax = plt.figure(num=kwargs.pop('num')).add_subplot(111, projection=pr)
ax = plt.figure(num=kwargs.pop('num')).add_subplot(111, projection=projection)
elif 'figsize' in kwargs:
ax = plt.figure(figsize=kwargs.pop('figsize')).add_subplot(111, projection=pr)
ax = plt.figure(figsize=kwargs.pop('figsize')).add_subplot(111, projection=projection)
else:
ax = plt.figure().add_subplot(111, projection=pr)
# Add ax to kwargs to add all subsequent plots to this axis:
#kwargs['ax'] = ax
ax = plt.figure().add_subplot(111, projection=projection)
if xlabel is not None: ax.set_xlabel(xlabel)
if ylabel is not None: ax.set_ylabel(ylabel)
if zlabel is not None: ax.set_zlabel(zlabel)
if title is not None: ax.set_title(title)
return ax, kwargs
def show_canvas(self, ax, plots, xlabel=None, ylabel=None,
zlabel=None, title=None, xlim=None, ylim=None,
zlim=None, legend=True, **kwargs):
ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)
if zlabel is not None:
ax.set_zlabel(zlabel)
ax.set_title(title)
def show_canvas(self, ax, plots, xlim=None, ylim=None, zlim=None, **kwargs):
try:
ax.autoscale_view()
ax.set_xlim(xlim)
ax.set_ylim(ylim)
if zlim is not None:
ax.set_zlim(zlim)
ax.figure.canvas.draw()
ax.figure.tight_layout()
#ax.figure.tight_layout()
except:
pass
return plots
def scatter(self, ax, X, Y, color=None, label=None, **kwargs):
def scatter(self, ax, X, Y, Z=None, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
if Z is not None:
return ax.scatter(X, Y, c=color, zs=Z, label=label, **kwargs)
return ax.scatter(X, Y, c=color, label=label, **kwargs)
def plot(self, ax, X, Y, color=None, label=None, **kwargs):
return ax.plot(X, Y, color=color, label=label, **kwargs)
def plot_axis_lines(self, ax, X, color=None, label=None, **kwargs):
def plot_axis_lines(self, ax, X, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
from matplotlib import transforms
from matplotlib.path import Path
if 'transform' not in kwargs:
kwargs['transform'] = transforms.blended_transform_factory(ax.transData, ax.transAxes)
if 'marker' not in kwargs:
kwargs['marker'] = Path([[-.2,0.], [-.2,.5], [0.,1.], [.2,.5], [.2,0.], [-.2,0.]],
[Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY])
if 'transform' not in kwargs:
if X.shape[1] == 1:
kwargs['transform'] = transforms.blended_transform_factory(ax.transData, ax.transAxes)
if X.shape[1] == 2:
return ax.scatter(X[:,0], X[:,1], ax.get_zlim()[0], c=color, label=label, **kwargs)
return ax.scatter(X, np.zeros_like(X), c=color, label=label, **kwargs)
def barplot(self, ax, x, height, width=0.8, bottom=0, color=None, label=None, **kwargs):
def barplot(self, ax, x, height, width=0.8, bottom=0, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
if 'align' not in kwargs:
kwargs['align'] = 'center'
return ax.bar(left=x, height=height, width=width,
bottom=bottom, label=label, color=color,
**kwargs)
def xerrorbar(self, ax, X, Y, error, color=None, label=None, **kwargs):
if not('linestyle' in kwargs or 'ls' in kwargs):
kwargs['ls'] = 'none'
return ax.errorbar(X, Y, xerr=error, ecolor=color, label=label, **kwargs)
def yerrorbar(self, ax, X, Y, error, color=None, label=None, **kwargs):
def xerrorbar(self, ax, X, Y, error, Z=None, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
if not('linestyle' in kwargs or 'ls' in kwargs):
kwargs['ls'] = 'none'
if Z is not None:
return ax.errorbar(X, Y, Z, xerr=error, ecolor=color, label=label, **kwargs)
return ax.errorbar(X, Y, xerr=error, ecolor=color, label=label, **kwargs)
def yerrorbar(self, ax, X, Y, error, Z=None, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
if not('linestyle' in kwargs or 'ls' in kwargs):
kwargs['ls'] = 'none'
if Z is not None:
return ax.errorbar(X, Y, Z, yerr=error, ecolor=color, label=label, **kwargs)
return ax.errorbar(X, Y, yerr=error, ecolor=color, label=label, **kwargs)
def imshow(self, ax, X, label=None, **kwargs):
@ -115,10 +122,13 @@ class MatplotlibPlots(AbstractPlottingLibrary):
def contour(self, ax, X, Y, C, levels=20, label=None, **kwargs):
return ax.contour(X, Y, C, levels=np.linspace(C.min(), C.max(), levels), label=label, **kwargs)
def fill_between(self, ax, X, lower, upper, color=None, label=None, **kwargs):
def surface(self, ax, X, Y, Z, color=None, label=None, **kwargs):
return ax.plot_surface(X, Y, Z, label=label, **kwargs)
def fill_between(self, ax, X, lower, upper, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
return ax.fill_between(X, lower, upper, facecolor=color, label=label, **kwargs)
def fill_gradient(self, canvas, X, percentiles, color=None, label=None, **kwargs):
def fill_gradient(self, canvas, X, percentiles, color=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
ax = canvas
plots = []
@ -132,7 +142,7 @@ class MatplotlibPlots(AbstractPlottingLibrary):
kwargs['facecolor'] = kwargs.pop('facecolors')
if 'cmap' not in kwargs:
kwargs['cmap'] = LinearSegmentedColormap.from_list('WhToColor', ((1., 1., 1.), kwargs['facecolor']), N=len(percentiles)-1)
kwargs['cmap'] = LinearSegmentedColormap.from_list('WhToColor', ((1., 1., 1.), kwargs['facecolor']), N=len(percentiles))
kwargs['cmap']._init()
if 'alpha' in kwargs:
@ -216,6 +226,8 @@ class MatplotlibPlots(AbstractPlottingLibrary):
polys.append(p)
polycol.extend(polys)
from matplotlib.collections import PolyCollection
if 'zorder' not in kwargs:
kwargs['zorder'] = 0
plots.append(PolyCollection(polycol, **kwargs))
ax.add_collection(plots[-1], autolim=True)
ax.autoscale_view()

View file

@ -0,0 +1,107 @@
#===============================================================================
# Copyright (c) 2015, Max Zwiessele
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * 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.
#
# * Neither the name of GPy.plotting.matplot_dep.util nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# 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.
#===============================================================================
from matplotlib import pyplot as plt
import numpy as np
def removeRightTicks(ax=None):
ax = ax or plt.gca()
for i, line in enumerate(ax.get_yticklines()):
if i%2 == 1: # odd indices
line.set_visible(False)
def removeUpperTicks(ax=None):
ax = ax or plt.gca()
for i, line in enumerate(ax.get_xticklines()):
if i%2 == 1: # odd indices
line.set_visible(False)
def fewerXticks(ax=None,divideby=2):
ax = ax or plt.gca()
ax.set_xticks(ax.get_xticks()[::divideby])
def align_subplots(N,M,xlim=None, ylim=None):
"""make all of the subplots have the same limits, turn off unnecessary ticks"""
#find sensible xlim,ylim
if xlim is None:
xlim = [np.inf,-np.inf]
for i in range(N*M):
plt.subplot(N,M,i+1)
xlim[0] = min(xlim[0],plt.xlim()[0])
xlim[1] = max(xlim[1],plt.xlim()[1])
if ylim is None:
ylim = [np.inf,-np.inf]
for i in range(N*M):
plt.subplot(N,M,i+1)
ylim[0] = min(ylim[0],plt.ylim()[0])
ylim[1] = max(ylim[1],plt.ylim()[1])
for i in range(N*M):
plt.subplot(N,M,i+1)
plt.xlim(xlim)
plt.ylim(ylim)
if (i)%M:
plt.yticks([])
else:
removeRightTicks()
if i<(M*(N-1)):
plt.xticks([])
else:
removeUpperTicks()
def align_subplot_array(axes,xlim=None, ylim=None):
"""
Make all of the axes in the array hae the same limits, turn off unnecessary ticks
use plt.subplots() to get an array of axes
"""
#find sensible xlim,ylim
if xlim is None:
xlim = [np.inf,-np.inf]
for ax in axes.flatten():
xlim[0] = min(xlim[0],ax.get_xlim()[0])
xlim[1] = max(xlim[1],ax.get_xlim()[1])
if ylim is None:
ylim = [np.inf,-np.inf]
for ax in axes.flatten():
ylim[0] = min(ylim[0],ax.get_ylim()[0])
ylim[1] = max(ylim[1],ax.get_ylim()[1])
N,M = axes.shape
for i,ax in enumerate(axes.flatten()):
ax.set_xlim(xlim)
ax.set_ylim(ylim)
if (i)%M:
ax.set_yticks([])
else:
removeRightTicks(ax)
if i<(M*(N-1)):
ax.set_xticks([])
else:
removeUpperTicks(ax)