mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-06-08 15:05:15 +02:00
commit
0dc7c8b06b
173 changed files with 4797 additions and 2817 deletions
87
.travis.yml
87
.travis.yml
|
|
@ -1,23 +1,17 @@
|
|||
sudo: false
|
||||
|
||||
os:
|
||||
- osx
|
||||
- linux
|
||||
- osx
|
||||
- linux
|
||||
|
||||
#language: python
|
||||
addons:
|
||||
apt_packages:
|
||||
- pandoc
|
||||
|
||||
#addons:
|
||||
# apt:
|
||||
# packages:
|
||||
# - gfortran
|
||||
# - libatlas-dev
|
||||
# - libatlas-base-dev
|
||||
# - liblapack-dev
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/download/
|
||||
- $HOME/install/
|
||||
#cache:
|
||||
# directories:
|
||||
# - "$HOME/download/"
|
||||
# - "$HOME/install/"
|
||||
|
||||
env:
|
||||
- PYTHON_VERSION=2.7
|
||||
|
|
@ -25,41 +19,54 @@ env:
|
|||
|
||||
before_install:
|
||||
- export CONDA_CACHED=1
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||
export OS=Linux;
|
||||
elif [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
export OS=MacOSX;
|
||||
else
|
||||
echo "OS not supported yet";
|
||||
exit 1;
|
||||
fi;
|
||||
- if [[ $PYTHON_VERSION == "2.7" ]]; then
|
||||
export MINICONDA=Miniconda;
|
||||
elif [[ $PYTHON_VERSION == 3* ]]; then
|
||||
export MINICONDA=Miniconda3;
|
||||
else
|
||||
echo "Could not find python version";
|
||||
exit 1;
|
||||
fi;
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]];
|
||||
then export OS=Linux;
|
||||
elif [[ "$TRAVIS_OS_NAME" == "osx" ]];
|
||||
then export OS=MacOSX;
|
||||
brew install pandoc;
|
||||
else
|
||||
echo "OS not supported yet";
|
||||
exit 1; fi;
|
||||
- if [[ $PYTHON_VERSION == "2.7" ]];
|
||||
then export MINICONDA=Miniconda;
|
||||
elif [[ $PYTHON_VERSION == 3* ]];
|
||||
then export MINICONDA=Miniconda3;
|
||||
else echo "Could not find python version";exit 1; fi;
|
||||
- if [ ! -d $HOME/download/ ]; then mkdir $HOME/download/; fi;
|
||||
- if [ ! -d $HOME/install/ ]; then mkdir $HOME/install/; fi;
|
||||
- export MINICONDA_FILE=$MINICONDA-latest-$OS-x86_64-$PYTHON_VERSION
|
||||
- export MINCONDA_CACHE_FILE=$HOME/download/$MINICONDA_FILE.sh
|
||||
- export MINICONDA_INSTALL=$HOME/install/$MINICONDA_FILE
|
||||
- if [ ! -f $MINCONDA_CACHE_FILE ]; then
|
||||
export CONDA_CACHED=0;
|
||||
wget http://repo.continuum.io/miniconda/$MINICONDA-latest-$OS-x86_64.sh -O $MINCONDA_CACHE_FILE;
|
||||
bash $MINCONDA_CACHE_FILE -b -p $MINICONDA_INSTALL;
|
||||
fi;
|
||||
- if [ ! -f $MINCONDA_CACHE_FILE ]; then export CONDA_CACHED=0; wget http://repo.continuum.io/miniconda/$MINICONDA-latest-$OS-x86_64.sh -O $MINCONDA_CACHE_FILE; bash $MINCONDA_CACHE_FILE -b -p $MINICONDA_INSTALL; fi;
|
||||
- export PATH="$MINICONDA_INSTALL/bin:$PATH";
|
||||
|
||||
|
||||
install:
|
||||
- conda install --yes python=$PYTHON_VERSION numpy=1.9 scipy=0.16 nose pip six matplotlib;
|
||||
- conda install --yes python=$PYTHON_VERSION numpy=1.9 scipy=0.16 nose pip six matplotlib sphinx;
|
||||
- pip install codecov
|
||||
- pip install pypandoc
|
||||
- python setup.py develop
|
||||
|
||||
|
||||
script:
|
||||
- coverage run travis_tests.py
|
||||
|
||||
after_success:
|
||||
- codecov
|
||||
- codecov
|
||||
|
||||
before_deploy:
|
||||
- cd doc
|
||||
- pip install sphinx_rtd_theme
|
||||
- sphinx-apidoc -o source/ ../GPy
|
||||
- make html
|
||||
- cd ../
|
||||
|
||||
deploy:
|
||||
provider: pypi
|
||||
user: maxz
|
||||
password:
|
||||
secure: "vMEOlP7DQhFJ7hQAKtKC5hrJXFl5BkUt4nXdosWWiw//Kg8E+PPLg88XPI2gqIosir9wwgtbSBBbbwCxkM6uxRNMpoNR8Ixyv9fmSXp4rLl7bbBY768W7IRXKIBjpuEy2brQjoT+CwDDSzUkckHvuUjJDNRvUv8ab4P/qYO1LG4="
|
||||
on:
|
||||
#tags: true
|
||||
branch: plot_density
|
||||
server: https://testpypi.python.org/pypi
|
||||
distributions: "bdist_wheel sdist"
|
||||
skip_cleanup: true
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
See contributors.
|
||||
[GPy Authors](https://github.com/SheffieldML/GPy/graphs/contributors)
|
||||
|
|
@ -49,7 +49,7 @@ def load(file_or_path):
|
|||
m = pickle.load(file_or_path)
|
||||
except:
|
||||
import pickle
|
||||
if isinstance(file_or_path, basestring):
|
||||
if isinstance(file_or_path, str):
|
||||
with open(file_or_path, 'rb') as f:
|
||||
m = pickle.load(f)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
__version__ = "0.8.8"
|
||||
__version__ = "0.8.8dev5"
|
||||
|
|
|
|||
292
GPy/core/gp.py
292
GPy/core/gp.py
|
|
@ -242,7 +242,7 @@ class GP(Model):
|
|||
|
||||
return mu, var
|
||||
|
||||
def predict(self, Xnew, full_cov=False, Y_metadata=None, kern=None):
|
||||
def predict(self, Xnew, full_cov=False, Y_metadata=None, kern=None, likelihood=None):
|
||||
"""
|
||||
Predict the function(s) at the new point(s) Xnew.
|
||||
|
||||
|
|
@ -269,10 +269,12 @@ class GP(Model):
|
|||
mu, var = self.normalizer.inverse_mean(mu), self.normalizer.inverse_variance(var)
|
||||
|
||||
# now push through likelihood
|
||||
mean, var = self.likelihood.predictive_values(mu, var, full_cov, Y_metadata=Y_metadata)
|
||||
if likelihood is None:
|
||||
likelihood = self.likelihood
|
||||
mean, var = likelihood.predictive_values(mu, var, full_cov, Y_metadata=Y_metadata)
|
||||
return mean, var
|
||||
|
||||
def predict_quantiles(self, X, quantiles=(2.5, 97.5), Y_metadata=None, kern=None):
|
||||
def predict_quantiles(self, X, quantiles=(2.5, 97.5), Y_metadata=None, kern=None, likelihood=None):
|
||||
"""
|
||||
Get the predictive quantiles around the prediction at X
|
||||
|
||||
|
|
@ -288,9 +290,11 @@ class GP(Model):
|
|||
m, v = self._raw_predict(X, full_cov=False, kern=kern)
|
||||
if self.normalizer is not None:
|
||||
m, v = self.normalizer.inverse_mean(m), self.normalizer.inverse_variance(v)
|
||||
return self.likelihood.predictive_quantiles(m, v, quantiles, Y_metadata=Y_metadata)
|
||||
if likelihood is None:
|
||||
likelihood = self.likelihood
|
||||
return likelihood.predictive_quantiles(m, v, quantiles, Y_metadata=Y_metadata)
|
||||
|
||||
def predictive_gradients(self, Xnew):
|
||||
def predictive_gradients(self, Xnew, kern=None):
|
||||
"""
|
||||
Compute the derivatives of the predicted latent function with respect to X*
|
||||
|
||||
|
|
@ -307,16 +311,19 @@ class GP(Model):
|
|||
:rtype: [np.ndarray (N*, Q ,D), np.ndarray (N*,Q) ]
|
||||
|
||||
"""
|
||||
dmu_dX = np.empty((Xnew.shape[0],Xnew.shape[1],self.output_dim))
|
||||
if kern is None:
|
||||
kern = self.kern
|
||||
mean_jac = np.empty((Xnew.shape[0],Xnew.shape[1],self.output_dim))
|
||||
|
||||
for i in range(self.output_dim):
|
||||
dmu_dX[:,:,i] = self.kern.gradients_X(self.posterior.woodbury_vector[:,i:i+1].T, Xnew, self.X)
|
||||
mean_jac[:,:,i] = kern.gradients_X(self.posterior.woodbury_vector[:,i:i+1].T, Xnew, self._predictive_variable)
|
||||
|
||||
# gradients wrt the diagonal part k_{xx}
|
||||
dv_dX = self.kern.gradients_X(np.eye(Xnew.shape[0]), Xnew)
|
||||
dv_dX = kern.gradients_X(np.eye(Xnew.shape[0]), Xnew)
|
||||
#grads wrt 'Schur' part K_{xf}K_{ff}^{-1}K_{fx}
|
||||
alpha = -2.*np.dot(self.kern.K(Xnew, self.X),self.posterior.woodbury_inv)
|
||||
dv_dX += self.kern.gradients_X(alpha, Xnew, self.X)
|
||||
return dmu_dX, dv_dX
|
||||
alpha = -2.*np.dot(kern.K(Xnew, self._predictive_variable), self.posterior.woodbury_inv)
|
||||
dv_dX += kern.gradients_X(alpha, Xnew, self._predictive_variable)
|
||||
return mean_jac, dv_dX
|
||||
|
||||
|
||||
def predict_jacobian(self, Xnew, kern=None, full_cov=True):
|
||||
|
|
@ -433,7 +440,7 @@ class GP(Model):
|
|||
mag[n] = np.sqrt(np.linalg.det(G[n, :, :]))
|
||||
return mag
|
||||
|
||||
def posterior_samples_f(self,X,size=10, full_cov=True):
|
||||
def posterior_samples_f(self,X, size=10, full_cov=True, **predict_kwargs):
|
||||
"""
|
||||
Samples the posterior GP at the points X.
|
||||
|
||||
|
|
@ -444,20 +451,32 @@ class GP(Model):
|
|||
:param full_cov: whether to return the full covariance matrix, or just the diagonal.
|
||||
:type full_cov: bool.
|
||||
:returns: fsim: set of simulations
|
||||
:rtype: np.ndarray (N x samples)
|
||||
:rtype: np.ndarray (D x N x samples) (if D==1 we flatten out the first dimension)
|
||||
"""
|
||||
m, v = self._raw_predict(X, full_cov=full_cov)
|
||||
m, v = self._raw_predict(X, full_cov=full_cov, **predict_kwargs)
|
||||
if self.normalizer is not None:
|
||||
m, v = self.normalizer.inverse_mean(m), self.normalizer.inverse_variance(v)
|
||||
v = v.reshape(m.size,-1) if len(v.shape)==3 else v
|
||||
if not full_cov:
|
||||
fsim = np.random.multivariate_normal(m.flatten(), np.diag(v.flatten()), size).T
|
||||
else:
|
||||
fsim = np.random.multivariate_normal(m.flatten(), v, size).T
|
||||
|
||||
def sim_one_dim(m, v):
|
||||
if not full_cov:
|
||||
return np.random.multivariate_normal(m.flatten(), np.diag(v.flatten()), size).T
|
||||
else:
|
||||
return np.random.multivariate_normal(m.flatten(), v, size).T
|
||||
|
||||
if self.output_dim == 1:
|
||||
return sim_one_dim(m, v)
|
||||
else:
|
||||
fsim = np.empty((self.output_dim, self.num_data, size))
|
||||
for d in range(self.output_dim):
|
||||
if full_cov and v.ndim == 3:
|
||||
fsim[d] = sim_one_dim(m[:, d], v[:, :, d])
|
||||
elif (not full_cov) and v.ndim == 2:
|
||||
fsim[d] = sim_one_dim(m[:, d], v[:, d])
|
||||
else:
|
||||
fsim[d] = sim_one_dim(m[:, d], v)
|
||||
return fsim
|
||||
|
||||
def posterior_samples(self, X, size=10, full_cov=False, Y_metadata=None):
|
||||
def posterior_samples(self, X, size=10, full_cov=False, Y_metadata=None, likelihood=None, **predict_kwargs):
|
||||
"""
|
||||
Samples the posterior GP at the points X.
|
||||
|
||||
|
|
@ -469,226 +488,18 @@ class GP(Model):
|
|||
:type full_cov: bool.
|
||||
:param noise_model: for mixed noise likelihood, the noise model to use in the samples.
|
||||
:type noise_model: integer.
|
||||
:returns: Ysim: set of simulations, a Numpy array (N x samples).
|
||||
:returns: Ysim: set of simulations,
|
||||
:rtype: np.ndarray (D x N x samples) (if D==1 we flatten out the first dimension)
|
||||
"""
|
||||
fsim = self.posterior_samples_f(X, size, full_cov=full_cov)
|
||||
Ysim = self.likelihood.samples(fsim, Y_metadata=Y_metadata)
|
||||
return Ysim
|
||||
|
||||
def plot_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=None,fillcol=None, Y_metadata=None, data_symbol='kx',
|
||||
apply_link=False):
|
||||
"""
|
||||
Plot the GP's view of the world, where the data is normalized and before applying a likelihood.
|
||||
This is a call to plot with plot_raw=True.
|
||||
Data will not be plotted in this, as the GP's view of the world
|
||||
may live in another space, or units then the data.
|
||||
|
||||
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 model.X, model.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 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 levels: number of levels to plot in a contour plot.
|
||||
: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
|
||||
:type samples: int
|
||||
:param fignum: figure to plot on.
|
||||
:type fignum: figure number
|
||||
:param ax: axes to plot on.
|
||||
:type ax: axes handle
|
||||
:param linecol: color of line to plot [Tango.colorsHex['darkBlue']]
|
||||
:type linecol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib
|
||||
:param fillcol: color of fill [Tango.colorsHex['lightBlue']]
|
||||
:type fillcol: 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 data_symbol: symbol as used matplotlib, by default this is a black cross ('kx')
|
||||
:type data_symbol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) alongside marker type, as is standard in matplotlib.
|
||||
:param apply_link: if there is a link function of the likelihood, plot the link(f*) rather than f*
|
||||
:type apply_link: boolean
|
||||
"""
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import models_plots
|
||||
kw = {}
|
||||
if linecol is not None:
|
||||
kw['linecol'] = linecol
|
||||
if fillcol is not None:
|
||||
kw['fillcol'] = fillcol
|
||||
return models_plots.plot_fit(self, plot_limits, which_data_rows,
|
||||
which_data_ycols, fixed_inputs,
|
||||
levels, samples, fignum, ax, resolution,
|
||||
plot_raw=plot_raw, Y_metadata=Y_metadata,
|
||||
data_symbol=data_symbol, apply_link=apply_link, **kw)
|
||||
|
||||
def plot(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=None,fillcol=None, Y_metadata=None,
|
||||
data_symbol='kx', predict_kw=None, plot_training_data=True, samples_y=0, apply_link=False):
|
||||
"""
|
||||
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 model.X, model.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 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 levels: number of levels to plot in a contour plot.
|
||||
: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 linecol: color of line to plot [Tango.colorsHex['darkBlue']]
|
||||
:type linecol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib
|
||||
:param fillcol: color of fill [Tango.colorsHex['lightBlue']]
|
||||
:type fillcol: 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 data_symbol: symbol as used matplotlib, by default this is a black cross ('kx')
|
||||
:type data_symbol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) alongside marker type, as is standard in matplotlib.
|
||||
:param plot_training_data: whether or not to plot the training points
|
||||
:type plot_training_data: boolean
|
||||
:param samples_y: the number of a posteriori samples to plot, p(y*|y)
|
||||
:type samples_y: int
|
||||
: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
|
||||
"""
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import models_plots
|
||||
kw = {}
|
||||
if linecol is not None:
|
||||
kw['linecol'] = linecol
|
||||
if fillcol is not None:
|
||||
kw['fillcol'] = fillcol
|
||||
return models_plots.plot_fit(self, plot_limits, which_data_rows,
|
||||
which_data_ycols, fixed_inputs,
|
||||
levels, samples, fignum, ax, resolution,
|
||||
plot_raw=plot_raw, Y_metadata=Y_metadata,
|
||||
data_symbol=data_symbol, predict_kw=predict_kw,
|
||||
plot_training_data=plot_training_data, samples_y=samples_y, apply_link=apply_link, **kw)
|
||||
|
||||
|
||||
def plot_data(self, which_data_rows='all',
|
||||
which_data_ycols='all', visible_dims=None,
|
||||
fignum=None, ax=None, data_symbol='kx'):
|
||||
"""
|
||||
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 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 model.X, model.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 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 levels: number of levels to plot in a contour plot.
|
||||
: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 linecol: color of line to plot [Tango.colorsHex['darkBlue']]
|
||||
:type linecol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib
|
||||
:param fillcol: color of fill [Tango.colorsHex['lightBlue']]
|
||||
:type fillcol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib
|
||||
:param data_symbol: symbol as used matplotlib, by default this is a black cross ('kx')
|
||||
:type data_symbol: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) alongside marker type, as is standard in matplotlib.
|
||||
"""
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import models_plots
|
||||
kw = {}
|
||||
return models_plots.plot_data(self, which_data_rows,
|
||||
which_data_ycols, visible_dims,
|
||||
fignum, ax, data_symbol, **kw)
|
||||
|
||||
|
||||
def plot_errorbars_trainset(self, which_data_rows='all',
|
||||
which_data_ycols='all', fixed_inputs=[], fignum=None, ax=None,
|
||||
linecol=None, data_symbol='kx', predict_kw=None, plot_training_data=True,lw=None):
|
||||
|
||||
"""
|
||||
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
|
||||
"""
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import models_plots
|
||||
kw = {}
|
||||
if lw is not None:
|
||||
kw['lw'] = lw
|
||||
return models_plots.plot_errorbars_trainset(self, which_data_rows, which_data_ycols, fixed_inputs,
|
||||
fignum, ax, linecol, data_symbol,
|
||||
predict_kw, plot_training_data, **kw)
|
||||
|
||||
|
||||
def plot_magnification(self, labels=None, which_indices=None,
|
||||
resolution=50, ax=None, marker='o', s=40,
|
||||
fignum=None, legend=True,
|
||||
plot_limits=None,
|
||||
aspect='auto', updates=False, plot_inducing=True, kern=None, **kwargs):
|
||||
|
||||
import sys
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import dim_reduction_plots
|
||||
|
||||
return dim_reduction_plots.plot_magnification(self, labels, which_indices,
|
||||
resolution, ax, marker, s,
|
||||
fignum, plot_inducing, legend,
|
||||
plot_limits, aspect, updates, **kwargs)
|
||||
|
||||
fsim = self.posterior_samples_f(X, size, full_cov=full_cov, **predict_kwargs)
|
||||
if likelihood is None:
|
||||
likelihood = self.likelihood
|
||||
if fsim.ndim == 3:
|
||||
for d in range(fsim.shape[0]):
|
||||
fsim[d] = likelihood.samples(fsim[d], Y_metadata=Y_metadata)
|
||||
else:
|
||||
fsim = likelihood.samples(fsim, Y_metadata=Y_metadata)
|
||||
return fsim
|
||||
|
||||
def input_sensitivity(self, summarize=True):
|
||||
"""
|
||||
|
|
@ -696,6 +507,9 @@ class GP(Model):
|
|||
"""
|
||||
return self.kern.input_sensitivity(summarize=summarize)
|
||||
|
||||
def get_most_significant_input_dimensions(self, which_indices=None):
|
||||
return self.kern.get_most_significant_input_dimensions(which_indices)
|
||||
|
||||
def optimize(self, optimizer=None, start=None, **kwargs):
|
||||
"""
|
||||
Optimize the model using self.log_likelihood and self.log_likelihood_gradient, as well as self.priors.
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ class LogGaussian(Gaussian):
|
|||
return -((np.log(x) - self.mu) / self.sigma2 + 1.) / x
|
||||
|
||||
def rvs(self, n):
|
||||
return np.exp(np.random.randn(n) * self.sigma + self.mu)
|
||||
return np.exp(np.random.randn(int(n)) * self.sigma + self.mu)
|
||||
|
||||
|
||||
class MultivariateGaussian(Prior):
|
||||
|
|
|
|||
|
|
@ -28,3 +28,6 @@ working = True
|
|||
|
||||
[cython]
|
||||
working = True
|
||||
|
||||
[plotting]
|
||||
library = matplotlib
|
||||
|
|
@ -1,6 +1,11 @@
|
|||
# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
"""
|
||||
Examples for GPy.
|
||||
|
||||
The examples in this package usually depend on `pods <https://github.com/sods/ods>`_ so make sure
|
||||
you have that installed before running examples.
|
||||
"""
|
||||
from . import classification
|
||||
from . import regression
|
||||
from . import dimensionality_reduction
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
|
||||
"""
|
||||
Gaussian Processes classification examples
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
# Copyright (c) 2012-2014, GPy authors (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
import numpy as np
|
||||
try:
|
||||
from matplotlib import pyplot as pb
|
||||
except:
|
||||
pass
|
||||
import GPy
|
||||
pb.ion()
|
||||
pb.close('all')
|
||||
|
||||
X1 = np.arange(3)[:,None]
|
||||
X2 = np.arange(4)[:,None]
|
||||
I1 = np.zeros_like(X1)
|
||||
I2 = np.ones_like(X2)
|
||||
|
||||
_X = np.vstack([ X1, X2 ])
|
||||
_I = np.vstack([ I1, I2 ])
|
||||
|
||||
X = np.hstack([ _X, _I ])
|
||||
|
||||
Y1 = np.sin(X1/8.)
|
||||
Y2 = np.cos(X2/8.)
|
||||
|
||||
Bias = GPy.kern.Bias(1,active_dims=[0])
|
||||
Coreg = GPy.kern.Coregionalize(1,2,active_dims=[1])
|
||||
K = Bias.prod(Coreg,name='X')
|
||||
|
||||
#K.coregion.W = 0
|
||||
#print K.coregion.W
|
||||
#print Bias.K(_X,_X)
|
||||
#print K.K(X,X)
|
||||
#pb.matshow(K.K(X,X))
|
||||
|
||||
Mlist = [GPy.kern.Matern32(1,lengthscale=20.,name="Mat")]
|
||||
kern = GPy.util.multioutput.LCM(input_dim=1,num_outputs=2,kernels_list=Mlist,name='H')
|
||||
kern.B.W = 0
|
||||
kern.B.kappa = 1.
|
||||
#kern.B.W.fix()
|
||||
#kern.B.kappa.fix()
|
||||
#m = GPy.models.GPCoregionalizedRegression(X_list=[X1,X2], Y_list=[Y1,Y2], kernel=kern)
|
||||
|
||||
|
||||
Z1 = np.array([1.5,2.5])[:,None]
|
||||
|
||||
m = GPy.models.SparseGPCoregionalizedRegression(X_list=[X1], Y_list=[Y1], Z_list = [Z1], kernel=kern)
|
||||
#m.optimize()
|
||||
m.checkgrad(verbose=1)
|
||||
|
||||
"""
|
||||
fig = pb.figure()
|
||||
ax0 = fig.add_subplot(211)
|
||||
ax1 = fig.add_subplot(212)
|
||||
slices = GPy.util.multioutput.get_slices([Y1,Y2])
|
||||
m.plot(fixed_inputs=[(1,0)],which_data_rows=slices[0],ax=ax0)
|
||||
#m.plot(fixed_inputs=[(1,1)],which_data_rows=slices[1],ax=ax1)
|
||||
"""
|
||||
|
||||
|
||||
|
||||
"""
|
||||
|
||||
X1 = 100 * np.random.rand(100)[:,None]
|
||||
X2 = 100 * np.random.rand(100)[:,None]
|
||||
#X1.sort()
|
||||
#X2.sort()
|
||||
|
||||
Y1 = np.sin(X1/10.) + np.random.rand(100)[:,None]
|
||||
Y2 = np.cos(X2/10.) + np.random.rand(100)[:,None]
|
||||
|
||||
|
||||
|
||||
|
||||
Mlist = [GPy.kern.Matern32(1,lengthscale=20.,name="Mat")]
|
||||
kern = GPy.util.multioutput.LCM(input_dim=1,num_outputs=12,kernels_list=Mlist,name='H')
|
||||
|
||||
|
||||
m = GPy.models.GPCoregionalizedRegression(X_list=[X1,X2], Y_list=[Y1,Y2], kernel=kern)
|
||||
m.optimize()
|
||||
|
||||
fig = pb.figure()
|
||||
ax0 = fig.add_subplot(211)
|
||||
ax1 = fig.add_subplot(212)
|
||||
slices = GPy.util.multioutput.get_slices([Y1,Y2])
|
||||
m.plot(fixed_inputs=[(1,0)],which_data_rows=slices[0],ax=ax0)
|
||||
m.plot(fixed_inputs=[(1,1)],which_data_rows=slices[1],ax=ax1)
|
||||
|
||||
"""
|
||||
|
|
@ -343,6 +343,29 @@ def bgplvm_simulation(optimize=True, verbose=1,
|
|||
m.kern.plot_ARD('BGPLVM Simulation ARD Parameters')
|
||||
return m
|
||||
|
||||
def gplvm_simulation(optimize=True, verbose=1,
|
||||
plot=True, plot_sim=False,
|
||||
max_iters=2e4,
|
||||
):
|
||||
from GPy import kern
|
||||
from GPy.models import GPLVM
|
||||
|
||||
D1, D2, D3, N, num_inducing, Q = 13, 5, 8, 45, 3, 9
|
||||
_, _, Ylist = _simulate_matern(D1, D2, D3, N, num_inducing, plot_sim)
|
||||
Y = Ylist[0]
|
||||
k = kern.Linear(Q, ARD=True) # + kern.white(Q, _np.exp(-2)) # + kern.bias(Q)
|
||||
# k = kern.RBF(Q, ARD=True, lengthscale=10.)
|
||||
m = GPLVM(Y, Q, init="PCA", kernel=k)
|
||||
m.likelihood.variance = .1
|
||||
|
||||
if optimize:
|
||||
print("Optimizing model:")
|
||||
m.optimize('bfgs', messages=verbose, max_iters=max_iters,
|
||||
gtol=.05)
|
||||
if plot:
|
||||
m.X.plot("BGPLVM Latent Space 1D")
|
||||
m.kern.plot_ARD('BGPLVM Simulation ARD Parameters')
|
||||
return m
|
||||
def ssgplvm_simulation(optimize=True, verbose=1,
|
||||
plot=True, plot_sim=False,
|
||||
max_iters=2e4, useGPU=False
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ except ImportError:
|
|||
rasm_available = False
|
||||
from .scg import SCG
|
||||
|
||||
class Optimizer():
|
||||
class Optimizer(object):
|
||||
"""
|
||||
Superclass for all the optimizers.
|
||||
|
||||
|
|
@ -56,16 +56,6 @@ class Optimizer():
|
|||
def opt(self, f_fp=None, f=None, fp=None):
|
||||
raise NotImplementedError("this needs to be implemented to use the optimizer class")
|
||||
|
||||
def plot(self):
|
||||
"""
|
||||
See GPy.plotting.matplot_dep.inference_plots
|
||||
"""
|
||||
import sys
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ...plotting.matplot_dep import inference_plots
|
||||
inference_plots.plot_optimizer(self)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
diagnostics = "Optimizer: \t\t\t\t %s\n" % self.opt_name
|
||||
diagnostics += "f(x_opt): \t\t\t\t %.3f\n" % self.f_opt
|
||||
|
|
|
|||
|
|
@ -1,2 +1,18 @@
|
|||
# This is the local installation configuration file for GPy
|
||||
# For user specific changes edit $HOME/.config/GPy/user.cfg
|
||||
|
||||
# [parallel]
|
||||
# Enable openmp support. This speeds up some computations, depending on the number
|
||||
# of cores available. Setting up a compiler with openmp support can be difficult on
|
||||
# some platforms, hence by default it is off.
|
||||
# openmp = False # True
|
||||
|
||||
# [datasets]
|
||||
# location for the local data cache
|
||||
# dir=$HOME/tmp/GPy-datasets/ # Any other path you choose
|
||||
|
||||
# [cython]
|
||||
# working = True # False
|
||||
|
||||
|
||||
# [plotting]
|
||||
# library = matplotlib # plotly
|
||||
|
|
|
|||
|
|
@ -1,24 +1,31 @@
|
|||
from ._src.kern import Kern
|
||||
from ._src.rbf import RBF
|
||||
from ._src.linear import Linear, LinearFull
|
||||
from ._src.static import Bias, White, Fixed
|
||||
from ._src.brownian import Brownian
|
||||
from ._src.stationary import Exponential, OU, Matern32, Matern52, ExpQuad, RatQuad, Cosine
|
||||
from ._src.mlp import MLP
|
||||
from ._src.periodic import PeriodicExponential, PeriodicMatern32, PeriodicMatern52
|
||||
from ._src.standard_periodic import StdPeriodic
|
||||
from ._src.independent_outputs import IndependentOutputs, Hierarchical
|
||||
from ._src.coregionalize import Coregionalize
|
||||
from ._src.ODE_UY import ODE_UY
|
||||
from ._src.ODE_UYC import ODE_UYC
|
||||
from ._src.ODE_st import ODE_st
|
||||
from ._src.ODE_t import ODE_t
|
||||
from ._src.poly import Poly
|
||||
from ._src.eq_ode2 import EQ_ODE2
|
||||
from ._src.trunclinear import TruncLinear,TruncLinear_inf
|
||||
from ._src.splitKern import SplitKern,DEtime
|
||||
from ._src.splitKern import DEtime as DiffGenomeKern
|
||||
from ._src.spline import Spline
|
||||
from ._src.eq_ode2 import EQ_ODE2
|
||||
from ._src.basis_funcs import LinearSlopeBasisFuncKernel, BasisFuncKernel, ChangePointBasisFuncKernel, DomainKernel
|
||||
"""
|
||||
Kernel module the kernels to sit in.
|
||||
|
||||
.. automodule:: .src
|
||||
:members:
|
||||
:private-members:
|
||||
"""
|
||||
from .src.kern import Kern
|
||||
from .src.add import Add
|
||||
from .src.prod import Prod
|
||||
from .src.rbf import RBF
|
||||
from .src.linear import Linear, LinearFull
|
||||
from .src.static import Bias, White, Fixed
|
||||
from .src.brownian import Brownian
|
||||
from .src.stationary import Exponential, OU, Matern32, Matern52, ExpQuad, RatQuad, Cosine
|
||||
from .src.mlp import MLP
|
||||
from .src.periodic import PeriodicExponential, PeriodicMatern32, PeriodicMatern52
|
||||
from .src.standard_periodic import StdPeriodic
|
||||
from .src.independent_outputs import IndependentOutputs, Hierarchical
|
||||
from .src.coregionalize import Coregionalize
|
||||
from .src.ODE_UY import ODE_UY
|
||||
from .src.ODE_UYC import ODE_UYC
|
||||
from .src.ODE_st import ODE_st
|
||||
from .src.ODE_t import ODE_t
|
||||
from .src.poly import Poly
|
||||
from .src.eq_ode2 import EQ_ODE2
|
||||
from .src.trunclinear import TruncLinear,TruncLinear_inf
|
||||
from .src.splitKern import SplitKern,DEtime
|
||||
from .src.splitKern import DEtime as DiffGenomeKern
|
||||
from .src.spline import Spline
|
||||
from .src.basis_funcs import LinearSlopeBasisFuncKernel, BasisFuncKernel, ChangePointBasisFuncKernel, DomainKernel
|
||||
|
|
@ -2,10 +2,10 @@
|
|||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
from .kern import Kern
|
||||
from .independent_outputs import index_to_slices
|
||||
from ...core.parameterization import Param
|
||||
from ...core.parameterization.transformations import Logexp
|
||||
import numpy as np
|
||||
from .independent_outputs import index_to_slices
|
||||
|
||||
class ODE_UY(Kern):
|
||||
def __init__(self, input_dim, variance_U=3., variance_Y=1., lengthscale_U=1., lengthscale_Y=1., active_dims=None, name='ode_uy'):
|
||||
1
GPy/kern/src/__init__.py
Normal file
1
GPy/kern/src/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from . import psi_comp
|
||||
|
|
@ -121,7 +121,7 @@ class Add(CombinationKernel):
|
|||
#ffrom fixed import Fixed
|
||||
|
||||
for p1, p2 in itertools.combinations(self.parts, 2):
|
||||
# i1, i2 = p1.active_dims, p2.active_dims
|
||||
# i1, i2 = p1._all_dims_active, p2._all_dims_active
|
||||
# white doesn;t combine with anything
|
||||
if isinstance(p1, White) or isinstance(p2, White):
|
||||
pass
|
||||
|
|
@ -135,7 +135,7 @@ class Add(CombinationKernel):
|
|||
tmp = p1.psi1(Z, variational_posterior).sum(axis=0)
|
||||
psi2 += p2.variance * (tmp[:,None]+tmp[None,:]) #(tmp[:, :, None] + tmp[:, None, :])
|
||||
elif isinstance(p2, (RBF, Linear)) and isinstance(p1, (RBF, Linear)):
|
||||
assert np.intersect1d(p1.active_dims, p2.active_dims).size == 0, "only non overlapping kernel dimensions allowed so far"
|
||||
assert np.intersect1d(p1._all_dims_active, p2._all_dims_active).size == 0, "only non overlapping kernel dimensions allowed so far"
|
||||
tmp1 = p1.psi1(Z, variational_posterior)
|
||||
tmp2 = p2.psi1(Z, variational_posterior)
|
||||
psi2 += np.einsum('nm,no->mo',tmp1,tmp2)+np.einsum('nm,no->mo',tmp2,tmp1)
|
||||
|
|
@ -157,7 +157,7 @@ class Add(CombinationKernel):
|
|||
#ffrom fixed import Fixed
|
||||
|
||||
for p1, p2 in itertools.combinations(self.parts, 2):
|
||||
# i1, i2 = p1.active_dims, p2.active_dims
|
||||
# i1, i2 = p1._all_dims_active, p2._all_dims_active
|
||||
# white doesn;t combine with anything
|
||||
if isinstance(p1, White) or isinstance(p2, White):
|
||||
pass
|
||||
|
|
@ -171,7 +171,7 @@ class Add(CombinationKernel):
|
|||
tmp = p1.psi1(Z, variational_posterior)
|
||||
psi2 += p2.variance * (tmp[:, :, None] + tmp[:, None, :])
|
||||
elif isinstance(p2, (RBF, Linear)) and isinstance(p1, (RBF, Linear)):
|
||||
assert np.intersect1d(p1.active_dims, p2.active_dims).size == 0, "only non overlapping kernel dimensions allowed so far"
|
||||
assert np.intersect1d(p1._all_dims_active, p2._all_dims_active).size == 0, "only non overlapping kernel dimensions allowed so far"
|
||||
tmp1 = p1.psi1(Z, variational_posterior)
|
||||
tmp2 = p2.psi1(Z, variational_posterior)
|
||||
psi2 += np.einsum('nm,no->nmo',tmp1,tmp2)+np.einsum('nm,no->nmo',tmp2,tmp1)
|
||||
|
|
@ -193,7 +193,7 @@ class Add(CombinationKernel):
|
|||
continue
|
||||
elif isinstance(p2, Bias):
|
||||
eff_dL_dpsi1 += dL_dpsi2.sum(1) * p2.variance * 2.
|
||||
else:# np.setdiff1d(p1.active_dims, ar2, assume_unique): # TODO: Careful, not correct for overlapping active_dims
|
||||
else:# np.setdiff1d(p1._all_dims_active, ar2, assume_unique): # TODO: Careful, not correct for overlapping _all_dims_active
|
||||
eff_dL_dpsi1 += dL_dpsi2.sum(1) * p2.psi1(Z, variational_posterior) * 2.
|
||||
p1.update_gradients_expectations(dL_dpsi0, eff_dL_dpsi1, dL_dpsi2, Z, variational_posterior)
|
||||
|
||||
|
|
@ -244,17 +244,14 @@ class Add(CombinationKernel):
|
|||
self.link_parameters(*other_params)
|
||||
else:
|
||||
self.link_parameter(other)
|
||||
self.input_dim, self.active_dims = self.get_input_dim_active_dims(self.parts)
|
||||
self.input_dim, self._all_dims_active = self.get_input_dim_active_dims(self.parts)
|
||||
return self
|
||||
|
||||
def input_sensitivity(self, summarize=True):
|
||||
if summarize:
|
||||
i_s = np.zeros((self.input_dim))
|
||||
for k in self.parts:
|
||||
i_s[k.active_dims] += k.input_sensitivity(summarize)
|
||||
i_s[k._all_dims_active] += k.input_sensitivity(summarize)
|
||||
return i_s
|
||||
else:
|
||||
i_s = np.zeros((len(self.parts), self.input_dim))
|
||||
from operator import setitem
|
||||
[setitem(i_s, (i, k.active_dims), k.input_sensitivity(summarize)) for i, k in enumerate(self.parts)]
|
||||
return i_s
|
||||
return super(Add, self).input_sensitivity(summarize)
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
# #Copyright (c) 2012, Max Zwiessele (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
import numpy as np
|
||||
from .kern import Kern
|
||||
from ...core.parameterization.param import Param
|
||||
from ...core.parameterization.transformations import Logexp
|
||||
import numpy as np
|
||||
from ...util.caching import Cache_this
|
||||
from ...util.linalg import tdot, mdot
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
|
||||
from .kern import Kern, CombinationKernel
|
||||
from .kern import CombinationKernel
|
||||
import numpy as np
|
||||
import itertools
|
||||
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
import sys
|
||||
import numpy as np
|
||||
from ...core.parameterization.parameterized import Parameterized
|
||||
from .kernel_slice_operations import KernCallsViaSlicerMeta
|
||||
from ...core.parameterization.observable_array import ObsAr
|
||||
from ...util.caching import Cache_this
|
||||
from GPy.core.parameterization.observable_array import ObsAr
|
||||
from .kernel_slice_operations import KernCallsViaSlicerMeta
|
||||
from functools import reduce
|
||||
import six
|
||||
|
||||
|
|
@ -34,15 +33,15 @@ class Kern(Parameterized):
|
|||
If this is not an integer (!) we will work on the whole input matrix X,
|
||||
and not check whether dimensions match or not (!).
|
||||
|
||||
active_dims:
|
||||
_all_dims_active:
|
||||
|
||||
is the active_dimensions of inputs X we will work on.
|
||||
All kernels will get sliced Xes as inputs, if active_dims is not None
|
||||
Only positive integers are allowed in active_dims!
|
||||
if active_dims is None, slicing is switched off and all X will be passed through as given.
|
||||
All kernels will get sliced Xes as inputs, if _all_dims_active is not None
|
||||
Only positive integers are allowed in _all_dims_active!
|
||||
if _all_dims_active is None, slicing is switched off and all X will be passed through as given.
|
||||
|
||||
:param int input_dim: the number of input dimensions to the function
|
||||
:param array-like|None active_dims: list of indices on which dimensions this kernel works on, or none if no slicing
|
||||
:param array-like|None _all_dims_active: list of indices on which dimensions this kernel works on, or none if no slicing
|
||||
|
||||
Do not instantiate.
|
||||
"""
|
||||
|
|
@ -52,19 +51,20 @@ class Kern(Parameterized):
|
|||
if active_dims is None:
|
||||
active_dims = np.arange(input_dim)
|
||||
|
||||
self.active_dims = np.atleast_1d(active_dims).astype(int)
|
||||
self.active_dims = active_dims
|
||||
self._all_dims_active = np.atleast_1d(active_dims).astype(int)
|
||||
|
||||
assert self.active_dims.size == self.input_dim, "input_dim={} does not match len(active_dim)={}, active_dims={}".format(self.input_dim, self.active_dims.size, self.active_dims)
|
||||
assert self._all_dims_active.size == self.input_dim, "input_dim={} does not match len(active_dim)={}, _all_dims_active={}".format(self.input_dim, self._all_dims_active.size, self._all_dims_active)
|
||||
|
||||
self._sliced_X = 0
|
||||
self.useGPU = self._support_GPU and useGPU
|
||||
|
||||
from .psi_comp import PSICOMP_GH
|
||||
self.psicomp = PSICOMP_GH()
|
||||
self.psicomp = PSICOMP_GH()
|
||||
|
||||
@Cache_this(limit=20)
|
||||
def _slice_X(self, X):
|
||||
return X[:, self.active_dims]
|
||||
return X[:, self._all_dims_active]
|
||||
|
||||
def K(self, X, X2):
|
||||
"""
|
||||
|
|
@ -198,21 +198,43 @@ class Kern(Parameterized):
|
|||
from ...plotting.matplot_dep import kernel_plots
|
||||
kernel_plots.plot(self, x, fignum, ax, title, plot_limits, resolution, **mpl_kwargs)
|
||||
|
||||
def plot_ARD(self, *args, **kw):
|
||||
"""
|
||||
See :class:`~GPy.plotting.matplot_dep.kernel_plots`
|
||||
"""
|
||||
import sys
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ...plotting.matplot_dep import kernel_plots
|
||||
return kernel_plots.plot_ARD(self,*args,**kw)
|
||||
|
||||
def input_sensitivity(self, summarize=True):
|
||||
"""
|
||||
Returns the sensitivity for each dimension of this kernel.
|
||||
"""
|
||||
return np.zeros(self.input_dim)
|
||||
|
||||
def get_most_significant_input_dimensions(self, which_indices=None):
|
||||
"""
|
||||
Determine which dimensions should be plotted
|
||||
|
||||
Returns the top three most signification input dimensions
|
||||
|
||||
if less then three dimensions, the non existing dimensions are
|
||||
labeled as None, so for a 1 dimensional input this returns
|
||||
(0, None, None).
|
||||
|
||||
:param which_indices: force the indices to be the given indices.
|
||||
:type which_indices: int or tuple(int,int) or tuple(int,int,int)
|
||||
"""
|
||||
if which_indices is None:
|
||||
which_indices = np.argsort(self.input_sensitivity())[::-1][:3]
|
||||
try:
|
||||
input_1, input_2, input_3 = which_indices
|
||||
except ValueError:
|
||||
# which indices is tuple or int
|
||||
try:
|
||||
input_3 = None
|
||||
input_1, input_2 = which_indices
|
||||
except TypeError:
|
||||
# which_indices is an int
|
||||
input_1, input_2 = which_indices, None
|
||||
except ValueError:
|
||||
# which_indices was a list or array like with only one int
|
||||
input_1, input_2 = which_indices[0], None
|
||||
return input_1, input_2, input_3
|
||||
|
||||
|
||||
def __add__(self, other):
|
||||
""" Overloading of the '+' operator. for more control, see self.add """
|
||||
return self.add(other)
|
||||
|
|
@ -244,9 +266,9 @@ class Kern(Parameterized):
|
|||
"""
|
||||
Shortcut for tensor `prod`.
|
||||
"""
|
||||
assert np.all(self.active_dims == range(self.input_dim)), "Can only use kernels, which have their input_dims defined from 0"
|
||||
assert np.all(other.active_dims == range(other.input_dim)), "Can only use kernels, which have their input_dims defined from 0"
|
||||
other.active_dims += self.input_dim
|
||||
assert np.all(self._all_dims_active == range(self.input_dim)), "Can only use kernels, which have their input_dims defined from 0"
|
||||
assert np.all(other._all_dims_active == range(other.input_dim)), "Can only use kernels, which have their input_dims defined from 0"
|
||||
other._all_dims_active += self.input_dim
|
||||
return self.prod(other)
|
||||
|
||||
def prod(self, other, name='mul'):
|
||||
|
|
@ -268,10 +290,10 @@ class Kern(Parameterized):
|
|||
return Prod([self, other], name)
|
||||
|
||||
def _check_input_dim(self, X):
|
||||
assert X.shape[1] == self.input_dim, "{} did not specify active_dims and X has wrong shape: X_dim={}, whereas input_dim={}".format(self.name, X.shape[1], self.input_dim)
|
||||
assert X.shape[1] == self.input_dim, "{} did not specify _all_dims_active and X has wrong shape: X_dim={}, whereas input_dim={}".format(self.name, X.shape[1], self.input_dim)
|
||||
|
||||
def _check_active_dims(self, X):
|
||||
assert X.shape[1] >= len(self.active_dims), "At least {} dimensional X needed, X.shape={!s}".format(len(self.active_dims), X.shape)
|
||||
assert X.shape[1] >= len(self._all_dims_active), "At least {} dimensional X needed, X.shape={!s}".format(len(self._all_dims_active), X.shape)
|
||||
|
||||
|
||||
class CombinationKernel(Kern):
|
||||
|
|
@ -303,15 +325,15 @@ class CombinationKernel(Kern):
|
|||
return self.parameters
|
||||
|
||||
def get_input_dim_active_dims(self, kernels, extra_dims = None):
|
||||
#active_dims = reduce(np.union1d, (np.r_[x.active_dims] for x in kernels), np.array([], dtype=int))
|
||||
#active_dims = np.array(np.concatenate((active_dims, extra_dims if extra_dims is not None else [])), dtype=int)
|
||||
input_dim = reduce(max, (k.active_dims.max() for k in kernels)) + 1
|
||||
self.active_dims = reduce(np.union1d, (np.r_[x.active_dims] for x in kernels), np.array([], dtype=int))
|
||||
#_all_dims_active = np.array(np.concatenate((_all_dims_active, extra_dims if extra_dims is not None else [])), dtype=int)
|
||||
input_dim = reduce(max, (k._all_dims_active.max() for k in kernels)) + 1
|
||||
|
||||
if extra_dims is not None:
|
||||
input_dim += extra_dims.size
|
||||
|
||||
active_dims = np.arange(input_dim)
|
||||
return input_dim, active_dims
|
||||
_all_dims_active = np.arange(input_dim)
|
||||
return input_dim, _all_dims_active
|
||||
|
||||
def input_sensitivity(self, summarize=True):
|
||||
"""
|
||||
|
|
@ -319,7 +341,20 @@ class CombinationKernel(Kern):
|
|||
otherwise put everything into an array with shape (#kernels, input_dim)
|
||||
in the order of appearance of the kernels in the parameterized object.
|
||||
"""
|
||||
raise NotImplementedError("Choose the kernel you want to get the sensitivity for. You need to override the default behaviour for getting the input sensitivity to be able to get the input sensitivity. For sum kernel it is the sum of all sensitivities, TODO: product kernel? Other kernels?, also TODO: shall we return all the sensitivities here in the combination kernel? So we can combine them however we want? This could lead to just plot all the sensitivities here...")
|
||||
if not summarize:
|
||||
num_params = [0]
|
||||
parts = []
|
||||
def sum_params(x):
|
||||
if (not isinstance(x, CombinationKernel)) and isinstance(x, Kern):
|
||||
num_params[0] += 1
|
||||
parts.append(x)
|
||||
self.traverse(sum_params)
|
||||
i_s = np.zeros((num_params[0], self.input_dim))
|
||||
from operator import setitem
|
||||
[setitem(i_s, (i, k._all_dims_active), k.input_sensitivity(summarize)) for i, k in enumerate(parts)]
|
||||
return i_s
|
||||
else:
|
||||
raise NotImplementedError("Choose the kernel you want to get the sensitivity for. You need to override the default behaviour for getting the input sensitivity to be able to get the input sensitivity. For sum kernel it is the sum of all sensitivities, TODO: product kernel? Other kernels?, also TODO: shall we return all the sensitivities here in the combination kernel? So we can combine them however we want? This could lead to just plot all the sensitivities here...")
|
||||
|
||||
def _check_active_dims(self, X):
|
||||
return
|
||||
|
|
@ -5,7 +5,7 @@ Created on 11 Mar 2014
|
|||
|
||||
This module provides a meta class for the kernels. The meta class is for
|
||||
slicing the inputs (X, X2) for the kernels, before K (or any other method involving X)
|
||||
gets calls. The `active_dims` of a kernel decide which dimensions the kernel works on.
|
||||
gets calls. The `_all_dims_active` of a kernel decide which dimensions the kernel works on.
|
||||
'''
|
||||
from ...core.parameterization.parameterized import ParametersChangedMeta
|
||||
import numpy as np
|
||||
|
|
@ -13,7 +13,7 @@ from functools import wraps
|
|||
|
||||
def put_clean(dct, name, func):
|
||||
if name in dct:
|
||||
dct['_clean_{}'.format(name)] = dct[name]
|
||||
#dct['_clean_{}'.format(name)] = dct[name]
|
||||
dct[name] = func(dct[name])
|
||||
|
||||
class KernCallsViaSlicerMeta(ParametersChangedMeta):
|
||||
|
|
@ -47,7 +47,7 @@ class _Slice_wrap(object):
|
|||
assert X.ndim == 2, "only matrices are allowed as inputs to kernels for now, given X.shape={!s}".format(X.shape)
|
||||
if X2 is not None:
|
||||
assert X2.ndim == 2, "only matrices are allowed as inputs to kernels for now, given X2.shape={!s}".format(X2.shape)
|
||||
if (self.k.active_dims is not None) and (self.k._sliced_X == 0):
|
||||
if (self.k._all_dims_active is not None) and (self.k._sliced_X == 0):
|
||||
self.k._check_active_dims(X)
|
||||
self.X = self.k._slice_X(X)
|
||||
self.X2 = self.k._slice_X(X2) if X2 is not None else X2
|
||||
|
|
@ -66,9 +66,9 @@ class _Slice_wrap(object):
|
|||
if self.ret:
|
||||
ret = np.zeros(self.shape)
|
||||
if len(self.shape) == 2:
|
||||
ret[:, self.k.active_dims] = return_val
|
||||
ret[:, self.k._all_dims_active] = return_val
|
||||
elif len(self.shape) == 3:
|
||||
ret[:, :, self.k.active_dims] = return_val
|
||||
ret[:, :, self.k._all_dims_active] = return_val
|
||||
return ret
|
||||
return return_val
|
||||
|
||||
|
|
@ -8,7 +8,6 @@ from ...util.linalg import tdot
|
|||
from ...core.parameterization import Param
|
||||
from ...core.parameterization.transformations import Logexp
|
||||
from ...util.caching import Cache_this
|
||||
from ...util.config import *
|
||||
from .psi_comp import PSICOMP_Linear
|
||||
|
||||
class Linear(Kern):
|
||||
|
|
@ -109,6 +108,9 @@ class Linear(Kern):
|
|||
def gradients_X_diag(self, dL_dKdiag, X):
|
||||
return 2.*self.variances*dL_dKdiag[:,None]*X
|
||||
|
||||
def gradients_XX_diag(self, dL_dKdiag, X):
|
||||
return 2*np.ones(X.shape)*self.variances
|
||||
|
||||
def input_sensitivity(self, summarize=True):
|
||||
return np.ones(self.input_dim) * self.variances
|
||||
|
||||
|
|
@ -5,7 +5,6 @@ from .kern import Kern
|
|||
from ...core.parameterization import Param
|
||||
from ...core.parameterization.transformations import Logexp
|
||||
import numpy as np
|
||||
from ...util.linalg import tdot
|
||||
from ...util.caching import Cache_this
|
||||
four_over_tau = 2./np.pi
|
||||
|
||||
|
|
@ -8,7 +8,6 @@ from ...util.linalg import mdot
|
|||
from ...util.decorators import silence_errors
|
||||
from ...core.parameterization.param import Param
|
||||
from ...core.parameterization.transformations import Logexp
|
||||
from functools import reduce
|
||||
|
||||
class Periodic(Kern):
|
||||
def __init__(self, input_dim, variance, lengthscale, period, n_freq, lower, upper, active_dims, name):
|
||||
|
|
@ -97,4 +97,11 @@ class Prod(CombinationKernel):
|
|||
target += p.gradients_X_diag(k/p.Kdiag(X),X)
|
||||
return target
|
||||
|
||||
|
||||
def input_sensitivity(self, summarize=True):
|
||||
if summarize:
|
||||
i_s = np.zeros((self.input_dim))
|
||||
for k in self.parts:
|
||||
i_s[k._all_dims_active] *= k.input_sensitivity(summarize)
|
||||
return i_s
|
||||
else:
|
||||
return super(Prod, self).input_sensitivity(summarize)
|
||||
|
|
@ -2,13 +2,9 @@
|
|||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
from ....core.parameterization.parameter_core import Pickleable
|
||||
from GPy.util.caching import Cache_this
|
||||
from ....util.caching import Cache_this
|
||||
from ....core.parameterization import variational
|
||||
from . import rbf_psi_comp
|
||||
from . import ssrbf_psi_comp
|
||||
from . import sslinear_psi_comp
|
||||
from . import linear_psi_comp
|
||||
|
||||
#from linear_psi_comp import LINEAr
|
||||
|
||||
class PSICOMP(Pickleable):
|
||||
|
||||
|
|
@ -22,6 +18,7 @@ class PSICOMP(Pickleable):
|
|||
pass
|
||||
|
||||
from .gaussherm import PSICOMP_GH
|
||||
from . import rbf_psi_comp, linear_psi_comp, ssrbf_psi_comp, sslinear_psi_comp
|
||||
|
||||
class PSICOMP_RBF(PSICOMP):
|
||||
@Cache_this(limit=10, ignore_args=(0,))
|
||||
|
|
@ -67,3 +64,5 @@ class PSICOMP_Linear(PSICOMP):
|
|||
raise ValueError("unknown distriubtion received for psi-statistics")
|
||||
|
||||
|
||||
from . import ssrbf_psi_gpucomp
|
||||
from .rbf_psi_gpucomp import PSICOMP_RBF_GPU
|
||||
|
|
@ -8,10 +8,12 @@ An approximated psi-statistics implementation based on Gauss-Hermite Quadrature
|
|||
import numpy as np
|
||||
|
||||
from ....core.parameterization import Param
|
||||
from GPy.util.caching import Cache_this
|
||||
from ....util.caching import Cache_this
|
||||
from ....util.linalg import tdot
|
||||
from . import PSICOMP
|
||||
|
||||
|
||||
|
||||
class PSICOMP_GH(PSICOMP):
|
||||
|
||||
def __init__(self, degree=5, cache_K=True):
|
||||
|
|
@ -235,7 +235,6 @@ gpu_code = """
|
|||
class PSICOMP_RBF_GPU(PSICOMP_RBF):
|
||||
|
||||
def __init__(self, threadnum=256, blocknum=30, GPU_direct=False):
|
||||
from . import PSICOMP_RBF
|
||||
self.fall_back = PSICOMP_RBF()
|
||||
|
||||
from pycuda.compiler import SourceModule
|
||||
|
|
@ -4,11 +4,9 @@
|
|||
|
||||
import numpy as np
|
||||
from .stationary import Stationary
|
||||
from .psi_comp import PSICOMP_RBF
|
||||
from .psi_comp.rbf_psi_gpucomp import PSICOMP_RBF_GPU
|
||||
from ...util.config import *
|
||||
from .psi_comp import PSICOMP_RBF, PSICOMP_RBF_GPU
|
||||
from ...core import Param
|
||||
from GPy.core.parameterization.transformations import Logexp
|
||||
from ...core.parameterization.transformations import Logexp
|
||||
|
||||
class RBF(Stationary):
|
||||
"""
|
||||
|
|
@ -5,6 +5,7 @@ import numpy as np
|
|||
from .kern import Kern
|
||||
from ...core.parameterization import Param
|
||||
from ...core.parameterization.transformations import Logexp
|
||||
|
||||
class Spline(Kern):
|
||||
"""
|
||||
Linear spline kernel. You need to specify 2 parameters: the variance and c.
|
||||
|
|
@ -3,7 +3,7 @@ A new kernel
|
|||
"""
|
||||
|
||||
import numpy as np
|
||||
from .kern import Kern,CombinationKernel
|
||||
from .kern import Kern, CombinationKernel
|
||||
from .independent_outputs import index_to_slices
|
||||
import itertools
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ class DEtime(Kern):
|
|||
self.idx_p = idx_p
|
||||
self.index_dim=index_dim
|
||||
self.kern = SplitKern(kernel,Xp, index_dim=index_dim)
|
||||
super(DiffGenomeKern, self).__init__(input_dim=kernel.input_dim+1, active_dims=None, name=name)
|
||||
super(DEtime, self).__init__(input_dim=kernel.input_dim+1, active_dims=None, name=name)
|
||||
self.add_parameter(self.kern)
|
||||
|
||||
def K(self, X, X2=None):
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# Check Matthew Rocklin's blog post.
|
||||
import sympy as sym
|
||||
import numpy as np
|
||||
from .kern import Kern
|
||||
from GPy.kern.src import Kern
|
||||
from ...core.symbolic import Symbolic_core
|
||||
|
||||
|
||||
|
|
@ -7,7 +7,6 @@ from .kern import Kern
|
|||
from ...core.parameterization import Param
|
||||
from ...core.parameterization.transformations import Logexp
|
||||
from ...util.caching import Cache_this
|
||||
from ...util.config import *
|
||||
|
||||
class TruncLinear(Kern):
|
||||
"""
|
||||
|
|
@ -99,137 +99,3 @@ class BayesianGPLVM(SparseGP_MPI):
|
|||
self.variational_prior.update_gradients_KL(self.X)
|
||||
self._Xgrad = self.X.gradient.copy()
|
||||
|
||||
#super(BayesianGPLVM, self).parameters_changed()
|
||||
#self._log_marginal_likelihood -= self.variational_prior.KL_divergence(self.X)
|
||||
|
||||
#self.X.mean.gradient, self.X.variance.gradient = self.kern.gradients_qX_expectations(variational_posterior=self.X, Z=self.Z, dL_dpsi0=self.grad_dict['dL_dpsi0'], dL_dpsi1=self.grad_dict['dL_dpsi1'], dL_dpsi2=self.grad_dict['dL_dpsi2'])
|
||||
|
||||
# This is testing code -------------------------
|
||||
# i = np.random.randint(self.X.shape[0])
|
||||
# X_ = self.X.mean
|
||||
# which = np.sqrt(((X_ - X_[i:i+1])**2).sum(1)).argsort()>(max(0, self.X.shape[0]-51))
|
||||
# _, _, grad_dict = self.inference_method.inference(self.kern, self.X[which], self.Z, self.likelihood, self.Y[which], self.Y_metadata)
|
||||
# grad = self.kern.gradients_qX_expectations(variational_posterior=self.X[which], Z=self.Z, dL_dpsi0=grad_dict['dL_dpsi0'], dL_dpsi1=grad_dict['dL_dpsi1'], dL_dpsi2=grad_dict['dL_dpsi2'])
|
||||
#
|
||||
# self.X.mean.gradient[:] = 0
|
||||
# self.X.variance.gradient[:] = 0
|
||||
# self.X.mean.gradient[which] = grad[0]
|
||||
# self.X.variance.gradient[which] = grad[1]
|
||||
|
||||
# update for the KL divergence
|
||||
# self.variational_prior.update_gradients_KL(self.X, which)
|
||||
# -----------------------------------------------
|
||||
|
||||
# update for the KL divergence
|
||||
#self.variational_prior.update_gradients_KL(self.X)
|
||||
|
||||
def plot_latent(self, labels=None, which_indices=None,
|
||||
resolution=50, ax=None, marker='o', s=40,
|
||||
fignum=None, plot_inducing=True, legend=True,
|
||||
plot_limits=None,
|
||||
aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={}):
|
||||
import sys
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import dim_reduction_plots
|
||||
|
||||
return dim_reduction_plots.plot_latent(self, labels, which_indices,
|
||||
resolution, ax, marker, s,
|
||||
fignum, plot_inducing, legend,
|
||||
plot_limits, aspect, updates, predict_kwargs, imshow_kwargs)
|
||||
|
||||
def do_test_latents(self, Y):
|
||||
"""
|
||||
Compute the latent representation for a set of new points Y
|
||||
|
||||
Notes:
|
||||
This will only work with a univariate Gaussian likelihood (for now)
|
||||
"""
|
||||
N_test = Y.shape[0]
|
||||
input_dim = self.Z.shape[1]
|
||||
|
||||
means = np.zeros((N_test, input_dim))
|
||||
covars = np.zeros((N_test, input_dim))
|
||||
|
||||
dpsi0 = -0.5 * self.input_dim / self.likelihood.variance
|
||||
dpsi2 = self.grad_dict['dL_dpsi2'][0][None, :, :] # TODO: this may change if we ignore het. likelihoods
|
||||
V = Y/self.likelihood.variance
|
||||
|
||||
#compute CPsi1V
|
||||
#if self.Cpsi1V is None:
|
||||
# psi1V = np.dot(self.psi1.T, self.likelihood.V)
|
||||
# tmp, _ = linalg.dtrtrs(self._Lm, np.asfortranarray(psi1V), lower=1, trans=0)
|
||||
# tmp, _ = linalg.dpotrs(self.LB, tmp, lower=1)
|
||||
# self.Cpsi1V, _ = linalg.dtrtrs(self._Lm, tmp, lower=1, trans=1)
|
||||
|
||||
dpsi1 = np.dot(self.posterior.woodbury_vector, V.T)
|
||||
|
||||
#start = np.zeros(self.input_dim * 2)
|
||||
|
||||
|
||||
from scipy.optimize import minimize
|
||||
|
||||
for n, dpsi1_n in enumerate(dpsi1.T[:, :, None]):
|
||||
args = (input_dim, self.kern.copy(), self.Z, dpsi0, dpsi1_n.T, dpsi2)
|
||||
res = minimize(latent_cost_and_grad, jac=True, x0=np.hstack((means[n], covars[n])), args=args, method='BFGS')
|
||||
xopt = res.x
|
||||
mu, log_S = xopt.reshape(2, 1, -1)
|
||||
means[n] = mu[0].copy()
|
||||
covars[n] = np.exp(log_S[0]).copy()
|
||||
|
||||
X = NormalPosterior(means, covars)
|
||||
|
||||
return X
|
||||
|
||||
def dmu_dX(self, Xnew):
|
||||
"""
|
||||
Calculate the gradient of the prediction at Xnew w.r.t Xnew.
|
||||
"""
|
||||
dmu_dX = np.zeros_like(Xnew)
|
||||
for i in range(self.Z.shape[0]):
|
||||
dmu_dX += self.kern.gradients_X(self.grad_dict['dL_dpsi1'][i:i + 1, :], Xnew, self.Z[i:i + 1, :])
|
||||
return dmu_dX
|
||||
|
||||
def dmu_dXnew(self, Xnew):
|
||||
"""
|
||||
Individual gradient of prediction at Xnew w.r.t. each sample in Xnew
|
||||
"""
|
||||
gradients_X = np.zeros((Xnew.shape[0], self.num_inducing))
|
||||
ones = np.ones((1, 1))
|
||||
for i in range(self.Z.shape[0]):
|
||||
gradients_X[:, i] = self.kern.gradients_X(ones, Xnew, self.Z[i:i + 1, :]).sum(-1)
|
||||
return np.dot(gradients_X, self.grad_dict['dL_dpsi1'])
|
||||
|
||||
def plot_steepest_gradient_map(self, *args, ** kwargs):
|
||||
"""
|
||||
See GPy.plotting.matplot_dep.dim_reduction_plots.plot_steepest_gradient_map
|
||||
"""
|
||||
import sys
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import dim_reduction_plots
|
||||
|
||||
return dim_reduction_plots.plot_steepest_gradient_map(self,*args,**kwargs)
|
||||
|
||||
|
||||
def latent_cost_and_grad(mu_S, input_dim, kern, Z, dL_dpsi0, dL_dpsi1, dL_dpsi2):
|
||||
"""
|
||||
objective function for fitting the latent variables for test points
|
||||
(negative log-likelihood: should be minimised!)
|
||||
"""
|
||||
mu = mu_S[:input_dim][None]
|
||||
log_S = mu_S[input_dim:][None]
|
||||
S = np.exp(log_S)
|
||||
|
||||
X = NormalPosterior(mu, S)
|
||||
|
||||
psi0 = kern.psi0(Z, X)
|
||||
psi1 = kern.psi1(Z, X)
|
||||
psi2 = kern.psi2(Z, X)
|
||||
|
||||
lik = dL_dpsi0 * psi0.sum() + np.einsum('ij,kj->...', dL_dpsi1, psi1) + np.einsum('ijk,lkj->...', dL_dpsi2, psi2) - 0.5 * np.sum(np.square(mu) + S) + 0.5 * np.sum(log_S)
|
||||
|
||||
dLdmu, dLdS = kern.gradients_qX_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, X)
|
||||
dmu = dLdmu - mu
|
||||
# dS = S0 + S1 + S2 -0.5 + .5/S
|
||||
dlnS = S * (dLdS - 0.5) + .5
|
||||
|
||||
return -lik, -np.hstack((dmu.flatten(), dlnS.flatten()))
|
||||
|
|
|
|||
|
|
@ -128,115 +128,4 @@ class BayesianGPLVMMiniBatch(SparseGPMiniBatch):
|
|||
d = self.output_dim
|
||||
self._log_marginal_likelihood -= kl_fctr*self.variational_prior.KL_divergence(self.X)*self.stochastics.batchsize/d
|
||||
|
||||
self._Xgrad = self.X.gradient.copy()
|
||||
|
||||
def plot_latent(self, labels=None, which_indices=None,
|
||||
resolution=50, ax=None, marker='o', s=40,
|
||||
fignum=None, plot_inducing=True, legend=True,
|
||||
plot_limits=None,
|
||||
aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={}):
|
||||
import sys
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import dim_reduction_plots
|
||||
|
||||
return dim_reduction_plots.plot_latent(self, labels, which_indices,
|
||||
resolution, ax, marker, s,
|
||||
fignum, plot_inducing, legend,
|
||||
plot_limits, aspect, updates, predict_kwargs, imshow_kwargs)
|
||||
|
||||
def do_test_latents(self, Y):
|
||||
"""
|
||||
Compute the latent representation for a set of new points Y
|
||||
|
||||
Notes:
|
||||
This will only work with a univariate Gaussian likelihood (for now)
|
||||
"""
|
||||
N_test = Y.shape[0]
|
||||
input_dim = self.Z.shape[1]
|
||||
|
||||
means = np.zeros((N_test, input_dim))
|
||||
covars = np.zeros((N_test, input_dim))
|
||||
|
||||
dpsi0 = -0.5 * self.input_dim / self.likelihood.variance
|
||||
dpsi2 = self.grad_dict['dL_dpsi2'][0][None, :, :] # TODO: this may change if we ignore het. likelihoods
|
||||
V = Y/self.likelihood.variance
|
||||
|
||||
#compute CPsi1V
|
||||
#if self.Cpsi1V is None:
|
||||
# psi1V = np.dot(self.psi1.T, self.likelihood.V)
|
||||
# tmp, _ = linalg.dtrtrs(self._Lm, np.asfortranarray(psi1V), lower=1, trans=0)
|
||||
# tmp, _ = linalg.dpotrs(self.LB, tmp, lower=1)
|
||||
# self.Cpsi1V, _ = linalg.dtrtrs(self._Lm, tmp, lower=1, trans=1)
|
||||
|
||||
dpsi1 = np.dot(self.posterior.woodbury_vector, V.T)
|
||||
|
||||
#start = np.zeros(self.input_dim * 2)
|
||||
|
||||
|
||||
from scipy.optimize import minimize
|
||||
|
||||
for n, dpsi1_n in enumerate(dpsi1.T[:, :, None]):
|
||||
args = (input_dim, self.kern.copy(), self.Z, dpsi0, dpsi1_n.T, dpsi2)
|
||||
res = minimize(latent_cost_and_grad, jac=True, x0=np.hstack((means[n], covars[n])), args=args, method='BFGS')
|
||||
xopt = res.x
|
||||
mu, log_S = xopt.reshape(2, 1, -1)
|
||||
means[n] = mu[0].copy()
|
||||
covars[n] = np.exp(log_S[0]).copy()
|
||||
|
||||
X = NormalPosterior(means, covars)
|
||||
|
||||
return X
|
||||
|
||||
def dmu_dX(self, Xnew):
|
||||
"""
|
||||
Calculate the gradient of the prediction at Xnew w.r.t Xnew.
|
||||
"""
|
||||
dmu_dX = np.zeros_like(Xnew)
|
||||
for i in range(self.Z.shape[0]):
|
||||
dmu_dX += self.kern.gradients_X(self.grad_dict['dL_dpsi1'][i:i + 1, :], Xnew, self.Z[i:i + 1, :])
|
||||
return dmu_dX
|
||||
|
||||
def dmu_dXnew(self, Xnew):
|
||||
"""
|
||||
Individual gradient of prediction at Xnew w.r.t. each sample in Xnew
|
||||
"""
|
||||
gradients_X = np.zeros((Xnew.shape[0], self.num_inducing))
|
||||
ones = np.ones((1, 1))
|
||||
for i in range(self.Z.shape[0]):
|
||||
gradients_X[:, i] = self.kern.gradients_X(ones, Xnew, self.Z[i:i + 1, :]).sum(-1)
|
||||
return np.dot(gradients_X, self.grad_dict['dL_dpsi1'])
|
||||
|
||||
def plot_steepest_gradient_map(self, *args, ** kwargs):
|
||||
"""
|
||||
See GPy.plotting.matplot_dep.dim_reduction_plots.plot_steepest_gradient_map
|
||||
"""
|
||||
import sys
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import dim_reduction_plots
|
||||
|
||||
return dim_reduction_plots.plot_steepest_gradient_map(self,*args,**kwargs)
|
||||
|
||||
|
||||
def latent_cost_and_grad(mu_S, input_dim, kern, Z, dL_dpsi0, dL_dpsi1, dL_dpsi2):
|
||||
"""
|
||||
objective function for fitting the latent variables for test points
|
||||
(negative log-likelihood: should be minimised!)
|
||||
"""
|
||||
mu = mu_S[:input_dim][None]
|
||||
log_S = mu_S[input_dim:][None]
|
||||
S = np.exp(log_S)
|
||||
|
||||
X = NormalPosterior(mu, S)
|
||||
|
||||
psi0 = kern.psi0(Z, X)
|
||||
psi1 = kern.psi1(Z, X)
|
||||
psi2 = kern.psi2(Z, X)
|
||||
|
||||
lik = dL_dpsi0 * psi0.sum() + np.einsum('ij,kj->...', dL_dpsi1, psi1) + np.einsum('ijk,lkj->...', dL_dpsi2, psi2) - 0.5 * np.sum(np.square(mu) + S) + 0.5 * np.sum(log_S)
|
||||
|
||||
dLdmu, dLdS = kern.gradients_qX_expectations(dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, X)
|
||||
dmu = dLdmu - mu
|
||||
# dS = S0 + S1 + S2 -0.5 + .5/S
|
||||
dlnS = S * (dLdS - 0.5) + .5
|
||||
|
||||
return -lik, -np.hstack((dmu.flatten(), dlnS.flatten()))
|
||||
self._Xgrad = self.X.gradient.copy()
|
||||
|
|
@ -36,5 +36,3 @@ class GPHeteroscedasticRegression(GP):
|
|||
|
||||
super(GPHeteroscedasticRegression, self).__init__(X,Y,kernel,likelihood, Y_metadata=Y_metadata)
|
||||
|
||||
def plot(self,*args):
|
||||
return NotImplementedError
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import numpy as np
|
|||
from .. import kern
|
||||
from ..core import GP, Param
|
||||
from ..likelihoods import Gaussian
|
||||
from .. import util
|
||||
|
||||
|
||||
class GPLVM(GP):
|
||||
|
|
@ -42,43 +41,4 @@ class GPLVM(GP):
|
|||
|
||||
def parameters_changed(self):
|
||||
super(GPLVM, self).parameters_changed()
|
||||
self.X.gradient = self.kern.gradients_X(self.grad_dict['dL_dK'], self.X, None)
|
||||
|
||||
#def jacobian(self,X):
|
||||
# J = np.zeros((X.shape[0],X.shape[1],self.output_dim))
|
||||
# for i in range(self.output_dim):
|
||||
# J[:,:,i] = self.kern.gradients_X(self.posterior.woodbury_vector[:,i:i+1], X, self.X)
|
||||
# return J
|
||||
|
||||
#def magnification(self,X):
|
||||
# target=np.zeros(X.shape[0])
|
||||
# #J = np.zeros((X.shape[0],X.shape[1],self.output_dim))
|
||||
## J = self.jacobian(X)
|
||||
# for i in range(X.shape[0]):
|
||||
# target[i]=np.sqrt(np.linalg.det(np.dot(J[i,:,:],np.transpose(J[i,:,:]))))
|
||||
# return target
|
||||
|
||||
def plot(self):
|
||||
assert self.Y.shape[1] == 2, "too high dimensional to plot. Try plot_latent"
|
||||
from matplotlib import pyplot as plt
|
||||
plt.scatter(self.Y[:, 0],
|
||||
self.Y[:, 1],
|
||||
40, self.X[:, 0].copy(),
|
||||
linewidth=0, cmap=plt.cm.jet)
|
||||
Xnew = np.linspace(self.X.min(), self.X.max(), 200)[:, None]
|
||||
mu, _ = self.predict(Xnew)
|
||||
plt.plot(mu[:, 0], mu[:, 1], 'k', linewidth=1.5)
|
||||
|
||||
def plot_latent(self, labels=None, which_indices=None,
|
||||
resolution=50, ax=None, marker='o', s=40,
|
||||
fignum=None, legend=True,
|
||||
plot_limits=None,
|
||||
aspect='auto', updates=False, **kwargs):
|
||||
import sys
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import dim_reduction_plots
|
||||
|
||||
return dim_reduction_plots.plot_latent(self, labels, which_indices,
|
||||
resolution, ax, marker, s,
|
||||
fignum, False, legend,
|
||||
plot_limits, aspect, updates, **kwargs)
|
||||
self.X.gradient = self.kern.gradients_X(self.grad_dict['dL_dK'], self.X, None)
|
||||
|
|
@ -9,7 +9,7 @@ from ..core.parameterization import Param
|
|||
from ..likelihoods import Gaussian
|
||||
from ..core.parameterization.variational import SpikeAndSlabPrior, SpikeAndSlabPosterior,VariationalPrior
|
||||
from ..inference.latent_function_inference.var_dtc_parallel import update_gradients, VarDTC_minibatch
|
||||
from ..kern._src.psi_comp.ssrbf_psi_gpucomp import PSICOMP_SSRBF_GPU
|
||||
from ..kern.src.psi_comp.ssrbf_psi_gpucomp import PSICOMP_SSRBF_GPU
|
||||
|
||||
class IBPPosterior(SpikeAndSlabPosterior):
|
||||
'''
|
||||
|
|
@ -190,12 +190,4 @@ class SSGPLVM(SparseGP_MPI):
|
|||
if self.kern.ARD:
|
||||
return self.kern.input_sensitivity()
|
||||
else:
|
||||
return self.variational_prior.pi
|
||||
|
||||
def plot_latent(self, plot_inducing=True, *args, **kwargs):
|
||||
import sys
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import dim_reduction_plots
|
||||
|
||||
return dim_reduction_plots.plot_latent(self, plot_inducing=plot_inducing, *args, **kwargs)
|
||||
|
||||
return self.variational_prior.pi
|
||||
|
|
@ -1,30 +1,6 @@
|
|||
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
|
||||
import matplotlib as mpl
|
||||
from matplotlib import pyplot as pb
|
||||
import sys
|
||||
#sys.path.append('/home/james/mlprojects/sitran_cluster/')
|
||||
#from switch_pylab_backend import *
|
||||
|
||||
|
||||
#this stuff isn;t really Tango related: maybe it could be moved out? TODO
|
||||
def removeRightTicks(ax=None):
|
||||
ax = ax or pb.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 pb.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 pb.gca()
|
||||
ax.set_xticks(ax.get_xticks()[::divideby])
|
||||
|
||||
|
||||
colorsHex = {\
|
||||
"Aluminium6":"#2e3436",\
|
||||
"Aluminium5":"#555753",\
|
||||
|
|
@ -83,32 +59,6 @@ def reset():
|
|||
while not lightList[0]==colorsHex['lightBlue']:
|
||||
lightList.append(lightList.pop(0))
|
||||
|
||||
def setLightFigures():
|
||||
mpl.rcParams['axes.edgecolor']=colorsHex['Aluminium6']
|
||||
mpl.rcParams['axes.facecolor']=colorsHex['Aluminium2']
|
||||
mpl.rcParams['axes.labelcolor']=colorsHex['Aluminium6']
|
||||
mpl.rcParams['figure.edgecolor']=colorsHex['Aluminium6']
|
||||
mpl.rcParams['figure.facecolor']=colorsHex['Aluminium2']
|
||||
mpl.rcParams['grid.color']=colorsHex['Aluminium6']
|
||||
mpl.rcParams['savefig.edgecolor']=colorsHex['Aluminium2']
|
||||
mpl.rcParams['savefig.facecolor']=colorsHex['Aluminium2']
|
||||
mpl.rcParams['text.color']=colorsHex['Aluminium6']
|
||||
mpl.rcParams['xtick.color']=colorsHex['Aluminium6']
|
||||
mpl.rcParams['ytick.color']=colorsHex['Aluminium6']
|
||||
|
||||
def setDarkFigures():
|
||||
mpl.rcParams['axes.edgecolor']=colorsHex['Aluminium2']
|
||||
mpl.rcParams['axes.facecolor']=colorsHex['Aluminium6']
|
||||
mpl.rcParams['axes.labelcolor']=colorsHex['Aluminium2']
|
||||
mpl.rcParams['figure.edgecolor']=colorsHex['Aluminium2']
|
||||
mpl.rcParams['figure.facecolor']=colorsHex['Aluminium6']
|
||||
mpl.rcParams['grid.color']=colorsHex['Aluminium2']
|
||||
mpl.rcParams['savefig.edgecolor']=colorsHex['Aluminium6']
|
||||
mpl.rcParams['savefig.facecolor']=colorsHex['Aluminium6']
|
||||
mpl.rcParams['text.color']=colorsHex['Aluminium2']
|
||||
mpl.rcParams['xtick.color']=colorsHex['Aluminium2']
|
||||
mpl.rcParams['ytick.color']=colorsHex['Aluminium2']
|
||||
|
||||
def hex2rgb(hexcolor):
|
||||
hexcolor = [hexcolor[1+2*i:1+2*(i+1)] for i in range(3)]
|
||||
r,g,b = [int(n,16) for n in hexcolor]
|
||||
|
|
@ -154,13 +104,4 @@ cdict_Alu = {'red' :((0./5,colorsRGB['Aluminium1'][0]/256.,colorsRGB['Aluminium1
|
|||
(2./5,colorsRGB['Aluminium3'][2]/256.,colorsRGB['Aluminium3'][2]/256.),
|
||||
(3./5,colorsRGB['Aluminium4'][2]/256.,colorsRGB['Aluminium4'][2]/256.),
|
||||
(4./5,colorsRGB['Aluminium5'][2]/256.,colorsRGB['Aluminium5'][2]/256.),
|
||||
(5./5,colorsRGB['Aluminium6'][2]/256.,colorsRGB['Aluminium6'][2]/256.))}
|
||||
# cmap_Alu = mpl.colors.LinearSegmentedColormap('TangoAluminium',cdict_Alu,256)
|
||||
# cmap_BGR = mpl.colors.LinearSegmentedColormap('TangoRedBlue',cdict_BGR,256)
|
||||
# cmap_RB = mpl.colors.LinearSegmentedColormap('TangoRedBlue',cdict_RB,256)
|
||||
if __name__=='__main__':
|
||||
from matplotlib import pyplot as pb
|
||||
pb.figure()
|
||||
pb.pcolor(pb.rand(10,10),cmap=cmap_RB)
|
||||
pb.colorbar()
|
||||
pb.show()
|
||||
(5./5,colorsRGB['Aluminium6'][2]/256.,colorsRGB['Aluminium6'][2]/256.))}
|
||||
|
|
@ -1,12 +1,96 @@
|
|||
# Copyright (c) 2014, GPy authors (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
try:
|
||||
import matplotlib
|
||||
from . import matplot_dep
|
||||
except (ImportError, NameError):
|
||||
# Matplotlib not available
|
||||
import warnings
|
||||
warnings.warn(ImportWarning("Matplotlib not available, install newest version of Matplotlib for plotting"))
|
||||
#sys.modules['matplotlib'] =
|
||||
#sys.modules[__name__+'.matplot_dep'] = ImportWarning("Matplotlib not available, install newest version of Matplotlib for plotting")
|
||||
current_lib = [None]
|
||||
|
||||
def change_plotting_library(lib):
|
||||
try:
|
||||
#===========================================================================
|
||||
# Load in your plotting library here and
|
||||
# save it under the name plotting_library!
|
||||
# This is hooking the library in
|
||||
# for the usage in GPy:
|
||||
if lib == 'matplotlib':
|
||||
import matplotlib
|
||||
from .matplot_dep.plot_definitions import MatplotlibPlots
|
||||
current_lib[0] = MatplotlibPlots()
|
||||
if lib == 'plotly':
|
||||
import plotly
|
||||
from .plotly_dep.plot_definitions import PlotlyPlots
|
||||
current_lib[0] = PlotlyPlots()
|
||||
if lib == 'none':
|
||||
current_lib[0] = None
|
||||
#===========================================================================
|
||||
except (ImportError, NameError):
|
||||
config.set('plotting', 'library', 'none')
|
||||
import warnings
|
||||
warnings.warn(ImportWarning("{} not available, install newest version of {} for plotting".format(lib, lib)))
|
||||
|
||||
from ..util.config import config
|
||||
lib = config.get('plotting', 'library')
|
||||
change_plotting_library(lib)
|
||||
|
||||
def plotting_library():
|
||||
return current_lib[0]
|
||||
|
||||
def show(figure, **kwargs):
|
||||
"""
|
||||
Show the specific plotting library figure, returned by
|
||||
add_to_canvas().
|
||||
|
||||
kwargs are the plotting library specific options
|
||||
for showing/drawing a figure.
|
||||
"""
|
||||
return plotting_library().show_canvas(figure, **kwargs)
|
||||
|
||||
if config.get('plotting', 'library') is not 'none':
|
||||
# Inject the plots into classes here:
|
||||
|
||||
# Already converted to new style:
|
||||
from . import gpy_plot
|
||||
|
||||
from ..core import GP
|
||||
GP.plot_data = gpy_plot.data_plots.plot_data
|
||||
GP.plot_data_error = gpy_plot.data_plots.plot_data_error
|
||||
GP.plot_errorbars_trainset = gpy_plot.data_plots.plot_errorbars_trainset
|
||||
GP.plot_mean = gpy_plot.gp_plots.plot_mean
|
||||
GP.plot_confidence = gpy_plot.gp_plots.plot_confidence
|
||||
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_magnification = gpy_plot.latent_plots.plot_magnification
|
||||
|
||||
from ..core import SparseGP
|
||||
SparseGP.plot_inducing = gpy_plot.data_plots.plot_inducing
|
||||
|
||||
from ..models import GPLVM, BayesianGPLVM, bayesian_gplvm_minibatch, SSGPLVM, SSMRD
|
||||
GPLVM.plot_latent = gpy_plot.latent_plots.plot_latent
|
||||
GPLVM.plot_scatter = gpy_plot.latent_plots.plot_latent_scatter
|
||||
GPLVM.plot_inducing = gpy_plot.latent_plots.plot_latent_inducing
|
||||
GPLVM.plot_steepest_gradient_map = gpy_plot.latent_plots.plot_steepest_gradient_map
|
||||
BayesianGPLVM.plot_latent = gpy_plot.latent_plots.plot_latent
|
||||
BayesianGPLVM.plot_scatter = gpy_plot.latent_plots.plot_latent_scatter
|
||||
BayesianGPLVM.plot_inducing = gpy_plot.latent_plots.plot_latent_inducing
|
||||
BayesianGPLVM.plot_steepest_gradient_map = gpy_plot.latent_plots.plot_steepest_gradient_map
|
||||
bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch.plot_latent = gpy_plot.latent_plots.plot_latent
|
||||
bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch.plot_scatter = gpy_plot.latent_plots.plot_latent_scatter
|
||||
bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch.plot_inducing = gpy_plot.latent_plots.plot_latent_inducing
|
||||
bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch.plot_steepest_gradient_map = gpy_plot.latent_plots.plot_steepest_gradient_map
|
||||
SSGPLVM.plot_latent = gpy_plot.latent_plots.plot_latent
|
||||
SSGPLVM.plot_scatter = gpy_plot.latent_plots.plot_latent_scatter
|
||||
SSGPLVM.plot_inducing = gpy_plot.latent_plots.plot_latent_inducing
|
||||
SSGPLVM.plot_steepest_gradient_map = gpy_plot.latent_plots.plot_steepest_gradient_map
|
||||
|
||||
from ..kern import Kern
|
||||
Kern.plot_covariance = gpy_plot.kernel_plots.plot_covariance
|
||||
def deprecate_plot(self, *args, **kwargs):
|
||||
import warnings
|
||||
warnings.warn(DeprecationWarning('Kern.plot is being deprecated and will not be available in the 1.0 release. Use Kern.plot_covariance instead'))
|
||||
return self.plot_covariance(*args, **kwargs)
|
||||
Kern.plot = deprecate_plot
|
||||
Kern.plot_ARD = gpy_plot.kernel_plots.plot_ARD
|
||||
|
||||
from ..inference.optimization import Optimizer
|
||||
Optimizer.plot = gpy_plot.inference_plots.plot_optimizer
|
||||
# Variational plot!
|
||||
|
|
|
|||
280
GPy/plotting/abstract_plotting_library.py
Normal file
280
GPy/plotting/abstract_plotting_library.py
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
#===============================================================================
|
||||
# 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.abstract_plotting_library 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.
|
||||
#===============================================================================
|
||||
|
||||
#===============================================================================
|
||||
# Make sure that the necessary files and functions are
|
||||
# defined in the plotting library:
|
||||
class AbstractPlottingLibrary(object):
|
||||
def __init__(self):
|
||||
"""
|
||||
Set the defaults dictionary in the _defaults variable:
|
||||
|
||||
E.g. for matplotlib we define a file defaults.py and
|
||||
set the dictionary of it here:
|
||||
|
||||
from . import defaults
|
||||
_defaults = defaults.__dict__
|
||||
"""
|
||||
self._defaults = {}
|
||||
self.__defaults = None
|
||||
|
||||
@property
|
||||
def defaults(self):
|
||||
#===============================================================================
|
||||
if self.__defaults is None:
|
||||
from collections import defaultdict
|
||||
class defaultdict(defaultdict):
|
||||
def __getattr__(self, *args, **kwargs):
|
||||
return defaultdict.__getitem__(self, *args, **kwargs)
|
||||
self.__defaults = defaultdict(dict, self._defaults)
|
||||
return self.__defaults
|
||||
#===============================================================================
|
||||
|
||||
def figure(self, nrows, ncols, **kwargs):
|
||||
"""
|
||||
Get a new figure with nrows and ncolumns subplots.
|
||||
Does not initialize the canvases yet.
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def new_canvas(self, figure=None, col=1, row=1, projection='2d', xlabel=None, ylabel=None, zlabel=None, title=None, xlim=None, ylim=None, zlim=None, **kwargs):
|
||||
"""
|
||||
Return a canvas, kwargupdate for your plotting library.
|
||||
|
||||
if figure is not None, create a canvas in the figure
|
||||
at subplot position (col, row).
|
||||
|
||||
This method does two things, it creates an empty canvas
|
||||
and updates the kwargs (deletes the unnecessary kwargs)
|
||||
for further usage in normal plotting.
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
|
||||
:param {'2d'|'3d'} projection: The projection to use.
|
||||
|
||||
E.g. in matplotlib this means it deletes references to ax, as
|
||||
plotting is done on the axis itself and is not a kwarg.
|
||||
|
||||
: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: if True, plot a legend, if int make legend rows in the legend
|
||||
: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)
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def add_to_canvas(self, canvas, plots, legend=True, title=None, **kwargs):
|
||||
"""
|
||||
Add plots is a dictionary with the plots as the
|
||||
items or a list of plots as items to canvas.
|
||||
|
||||
The kwargs are plotting library specific kwargs!
|
||||
|
||||
E.g. in matplotlib this does not have to do anything to add stuff, but
|
||||
we set the legend and title.
|
||||
|
||||
!This function returns the updated canvas!
|
||||
|
||||
:param title: the title of the plot
|
||||
:param legend: whether to plot a legend or not
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def show_canvas(self, canvas, **kwargs):
|
||||
"""
|
||||
Draw/Plot the canvas given.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def plot(self, cavas, X, Y, Z=None, color=None, label=None, **kwargs):
|
||||
"""
|
||||
Make a line plot from for Y on X (Y = f(X)) on the canvas.
|
||||
If Z is not None, plot in 3d!
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def plot_axis_lines(self, ax, X, color=None, label=None, **kwargs):
|
||||
"""
|
||||
Plot lines at the bottom (lower boundary of yaxis) of the axis at input location X.
|
||||
|
||||
If X is two dimensional, plot in 3d and connect the axis lines to the bottom of the Z axis.
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
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.
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
|
||||
:param canvas: the plotting librarys specific canvas to plot on.
|
||||
:param array-like X: the inputs to plot.
|
||||
:param array-like Y: the outputs to plot.
|
||||
:param array-like Z: the Z level to plot (if plotting 3d).
|
||||
:param array-like c: the colorlevel for each point.
|
||||
:param float vmin: minimum colorscale
|
||||
:param float vmax: maximum colorscale
|
||||
:param kwargs: the specific kwargs for your plotting library
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def barplot(self, canvas, x, height, width=0.8, bottom=0, color=None, label=None, **kwargs):
|
||||
"""
|
||||
Plot vertical bar plot centered at x with height
|
||||
and width of bars. The y level is at bottom.
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
|
||||
:param array-like x: the center points of the bars
|
||||
:param array-like height: the height of the bars
|
||||
:param array-like width: the width of the bars
|
||||
:param array-like bottom: the start y level of the bars
|
||||
:param kwargs: kwargs for the specific library you are using.
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def xerrorbar(self, canvas, X, Y, error, color=None, label=None, **kwargs):
|
||||
"""
|
||||
Make an errorbar along the xaxis for points at (X,Y) on the canvas.
|
||||
if error is two dimensional, the lower error is error[:,0] and
|
||||
the upper error is error[:,1]
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def yerrorbar(self, canvas, X, Y, error, color=None, label=None, **kwargs):
|
||||
"""
|
||||
Make errorbars along the yaxis on the canvas given.
|
||||
if error is two dimensional, the lower error is error[0, :] and
|
||||
the upper error is error[1, :]
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def imshow(self, canvas, X, extent=None, label=None, vmin=None, vmax=None, **kwargs):
|
||||
"""
|
||||
Show the image stored in X on the canvas.
|
||||
|
||||
The origin of the image show is (0,0), such that X[0,0] gets plotted at [0,0] of the image!
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def imshow_interact(self, canvas, plot_function, extent=None, label=None, vmin=None, vmax=None, **kwargs):
|
||||
"""
|
||||
This function is optional!
|
||||
|
||||
Create an imshow controller to stream
|
||||
the image returned by the plot_function. There is an imshow controller written for
|
||||
mmatplotlib, which updates the imshow on changes in axis.
|
||||
|
||||
The origin of the image show is (0,0), such that X[0,0] gets plotted at [0,0] of the image!
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def annotation_heatmap(self, canvas, X, annotation, extent, label=None, **kwargs):
|
||||
"""
|
||||
Plot an annotation heatmap. That is like an imshow, but
|
||||
put the text of the annotation inside the cells of the heatmap (centered).
|
||||
|
||||
:param canvas: the canvas to plot on
|
||||
:param array-like annotation: the annotation labels for the heatmap
|
||||
:param [horizontal_min,horizontal_max,vertical_min,vertical_max] extent: the extent of where to place the heatmap
|
||||
:param str label: the label for the heatmap
|
||||
:return: a list of both the heatmap and annotation plots [heatmap, annotation], or the interactive update object (alone)
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def annotation_heatmap_interact(self, canvas, plot_function, extent, label=None, resolution=15, **kwargs):
|
||||
"""
|
||||
if plot_function is not None, return an interactive updated
|
||||
heatmap, which updates on axis events, so that one can zoom in
|
||||
and out and the heatmap gets updated. See the matplotlib implementation
|
||||
in matplot_dep.controllers.
|
||||
|
||||
the plot_function returns a pair (X, annotation) to plot, when called with
|
||||
a new input X (which would be the grid, which is visible on the plot
|
||||
right now)
|
||||
|
||||
:param canvas: the canvas to plot on
|
||||
:param array-like annotation: the annotation labels for the heatmap
|
||||
:param [horizontal_min,horizontal_max,vertical_min,vertical_max] extent: the extent of where to place the heatmap
|
||||
:param str label: the label for the heatmap
|
||||
:return: a list of both the heatmap and annotation plots [heatmap, annotation], or the interactive update object (alone)
|
||||
:param plot_function: the function, which generates new data for given input locations X
|
||||
:param int resolution: the resolution of the interactive plot redraw - this is only needed when giving a plot_function
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def contour(self, canvas, X, Y, C, Z=None, color=None, label=None, **kwargs):
|
||||
"""
|
||||
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")
|
||||
|
||||
def fill_between(self, canvas, X, lower, upper, color=None, label=None, **kwargs):
|
||||
"""
|
||||
Fill along the xaxis between lower and upper.
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
"""
|
||||
raise NotImplementedError("Implement all plot functions in AbstractPlottingLibrary in order to use your own plotting library")
|
||||
|
||||
def fill_gradient(self, canvas, X, percentiles, color=None, label=None, **kwargs):
|
||||
"""
|
||||
Plot a gradient (in alpha values) for the given percentiles.
|
||||
|
||||
the kwargs are plotting library specific kwargs!
|
||||
"""
|
||||
print("fill_gradient not implemented in this backend.")
|
||||
2
GPy/plotting/gpy_plot/__init__.py
Normal file
2
GPy/plotting/gpy_plot/__init__.py
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
from .. import plotting_library
|
||||
from . import data_plots, gp_plots, latent_plots, kernel_plots, plot_util, inference_plots
|
||||
277
GPy/plotting/gpy_plot/data_plots.py
Normal file
277
GPy/plotting/gpy_plot/data_plots.py
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
#===============================================================================
|
||||
# Copyright (c) 2012-2015, GPy authors (see AUTHORS.txt).
|
||||
# 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 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 plotting_library as pl
|
||||
#from .. import gpy_plot
|
||||
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, 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
|
||||
|
||||
:returns list: of plots created.
|
||||
"""
|
||||
canvas, plot_kwargs = pl().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().add_to_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)
|
||||
|
||||
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], 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], color=Y[rows, d], 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().new_canvas(projection=projection, **error_kwargs)
|
||||
plots = _plot_data_error(self, canvas, which_data_rows, which_data_ycols, visible_dims, projection, label, **error_kwargs)
|
||||
return pl().add_to_canvas(canvas, plots)
|
||||
|
||||
def _plot_data_error(self, canvas, which_data_rows='all',
|
||||
which_data_ycols='all', visible_dims=None,
|
||||
projection='2d', label=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 = {}
|
||||
|
||||
if X_variance is not None:
|
||||
plots['input_error'] = []
|
||||
#one dimensional plotting
|
||||
if len(free_dims) == 1:
|
||||
for d in ycols:
|
||||
update_not_existing_kwargs(error_kwargs, pl().defaults.xerrorbar)
|
||||
plots['input_error'].append(pl().xerrorbar(canvas, X[rows, free_dims].flatten(), Y[rows, d].flatten(),
|
||||
2 * np.sqrt(X_variance[rows, free_dims].flatten()), label=label,
|
||||
**error_kwargs))
|
||||
#2D plotting
|
||||
elif len(free_dims) == 2:
|
||||
update_not_existing_kwargs(error_kwargs, pl().defaults.xerrorbar) # @UndefinedVariable
|
||||
plots['input_error'].append(pl().xerrorbar(canvas, X[rows, free_dims[0]].flatten(), X[rows, free_dims[1]].flatten(),
|
||||
2 * np.sqrt(X_variance[rows, free_dims[0]].flatten()), label=label,
|
||||
**error_kwargs))
|
||||
plots['input_error'].append(pl().yerrorbar(canvas, X[rows, free_dims[0]].flatten(), X[rows, free_dims[1]].flatten(),
|
||||
2 * np.sqrt(X_variance[rows, free_dims[1]].flatten()), label=label,
|
||||
**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='inducing', **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().new_canvas(projection=projection, **plot_kwargs)
|
||||
plots = _plot_inducing(self, canvas, visible_dims, projection, label, **kwargs)
|
||||
return pl().add_to_canvas(canvas, plots, legend=label is not None)
|
||||
|
||||
def _plot_inducing(self, canvas, visible_dims, projection, label, **plot_kwargs):
|
||||
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]
|
||||
free_dims = get_free_dims(self, visible_dims, None)
|
||||
|
||||
Z = self.Z[:, free_dims]
|
||||
plots = {}
|
||||
|
||||
#one dimensional plotting
|
||||
if len(free_dims) == 1:
|
||||
update_not_existing_kwargs(plot_kwargs, pl().defaults.inducing_1d) # @UndefinedVariable
|
||||
plots['inducing'] = pl().plot_axis_lines(canvas, Z[:, free_dims], label=label, **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], label=label, **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]],
|
||||
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_errorbars_trainset(self, which_data_rows='all',
|
||||
which_data_ycols='all', fixed_inputs=None,
|
||||
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.
|
||||
These are the errorbars after the appropriate
|
||||
approximations according to the likelihood are done.
|
||||
|
||||
This also works for heteroscedastic likelihoods.
|
||||
|
||||
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 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
|
||||
"""
|
||||
canvas, kwargs = pl().new_canvas(projection=projection, **plot_kwargs)
|
||||
plots = _plot_errorbars_trainset(self, canvas, which_data_rows, which_data_ycols,
|
||||
fixed_inputs, plot_raw, apply_link, label, projection, predict_kw, **kwargs)
|
||||
return pl().add_to_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,
|
||||
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)
|
||||
|
||||
X, _, Y = get_x_y_var(self)
|
||||
|
||||
if fixed_inputs is None:
|
||||
fixed_inputs = []
|
||||
free_dims = get_free_dims(self, None, fixed_inputs)
|
||||
|
||||
Xgrid = X.copy()
|
||||
for i, v in fixed_inputs:
|
||||
Xgrid[:, i] = v
|
||||
|
||||
plots = []
|
||||
|
||||
if len(free_dims)<=2 and projection=='2d':
|
||||
update_not_existing_kwargs(plot_kwargs, pl().defaults.yerrorbar)
|
||||
if predict_kw is None:
|
||||
predict_kw = {}
|
||||
if 'Y_metadata' not in predict_kw:
|
||||
predict_kw['Y_metadata'] = self.Y_metadata or {}
|
||||
mu, percs, _ = helper_predict_with_model(self, Xgrid, plot_raw,
|
||||
apply_link, (2.5, 97.5),
|
||||
ycols, predict_kw)
|
||||
if len(free_dims)==1:
|
||||
for d in ycols:
|
||||
plots.append(pl().yerrorbar(canvas, X[rows,free_dims[0]], mu[rows,d],
|
||||
np.vstack([mu[rows, d] - percs[0][rows, d], percs[1][rows, d] - mu[rows,d]]),
|
||||
label=label,
|
||||
**plot_kwargs))
|
||||
# elif len(free_dims) == 2:
|
||||
# for d in ycols:
|
||||
# plots.append(pl().yerrorbar(canvas, X[rows,free_dims[0]], X[rows,free_dims[1]],
|
||||
# np.vstack([mu[rows, d] - percs[0][rows, d], percs[1][rows, d] - mu[rows,d]]),
|
||||
# #color=Y[rows,d],
|
||||
# label=label,
|
||||
# **plot_kwargs))
|
||||
# plots.append(pl().xerrorbar(canvas, X[rows,free_dims[0]], X[rows,free_dims[1]],
|
||||
# np.vstack([mu[rows, d] - percs[0][rows, d], percs[1][rows, d] - mu[rows,d]]),
|
||||
# #color=Y[rows,d],
|
||||
# label=label,
|
||||
# **plot_kwargs))
|
||||
else:
|
||||
raise NotImplementedError("Cannot plot in more then one dimensions, or 3d")
|
||||
return dict(yerrorbars=plots)
|
||||
|
||||
|
||||
415
GPy/plotting/gpy_plot/gp_plots.py
Normal file
415
GPy/plotting/gpy_plot/gp_plots.py
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
#===============================================================================
|
||||
# Copyright (c) 2012-2015, GPy authors (see AUTHORS.txt).
|
||||
# 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 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 plotting_library as pl
|
||||
from .plot_util import helper_for_plot_data, update_not_existing_kwargs, \
|
||||
helper_predict_with_model, get_which_data_ycols, get_x_y_var
|
||||
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, projection='2d',
|
||||
label='gp mean',
|
||||
predict_kw=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Plot the mean of the GP.
|
||||
|
||||
You can deactivate the legend for this one plot by supplying None to label.
|
||||
|
||||
Give the Y_metadata in the predict_kw if you need it.
|
||||
|
||||
|
||||
|
||||
: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.
|
||||
: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 which_data_ycols: which columns of y to plot (array-like or list of ints)
|
||||
: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().new_canvas(projection=projection, **kwargs)
|
||||
X = get_x_y_var(self)[0]
|
||||
helper_data = helper_for_plot_data(self, X, plot_limits, visible_dims, fixed_inputs, resolution)
|
||||
helper_prediction = helper_predict_with_model(self, helper_data[2], plot_raw,
|
||||
apply_link, None,
|
||||
get_which_data_ycols(self, which_data_ycols),
|
||||
predict_kw)
|
||||
plots = _plot_mean(self, canvas, helper_data, helper_prediction,
|
||||
levels, projection, label, **kwargs)
|
||||
return pl().add_to_canvas(canvas, plots)
|
||||
|
||||
def _plot_mean(self, canvas, helper_data, helper_prediction,
|
||||
levels=20, projection='2d', label=None,
|
||||
**kwargs):
|
||||
|
||||
_, free_dims, Xgrid, x, y, _, _, resolution = helper_data
|
||||
if len(free_dims)<=2:
|
||||
mu, _, _ = helper_prediction
|
||||
if len(free_dims)==1:
|
||||
# 1D plotting:
|
||||
update_not_existing_kwargs(kwargs, pl().defaults.meanplot_1d) # @UndefinedVariable
|
||||
plots = dict(gpmean=[pl().plot(canvas, Xgrid[:, free_dims], mu, label=label, **kwargs)])
|
||||
else:
|
||||
if projection == '2d':
|
||||
update_not_existing_kwargs(kwargs, pl().defaults.meanplot_2d) # @UndefinedVariable
|
||||
plots = dict(gpmean=[pl().contour(canvas, x[:,0], y[0,:],
|
||||
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,
|
||||
which_data_ycols='all', label='gp confidence',
|
||||
predict_kw=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Plot the confidence interval between the percentiles lower and upper.
|
||||
E.g. the 95% confidence interval is $2.5, 97.5$.
|
||||
Note: Only implemented for one dimension!
|
||||
|
||||
You can deactivate the legend for this one plot by supplying None to label.
|
||||
|
||||
Give the Y_metadata in the predict_kw if you need it.
|
||||
|
||||
|
||||
:param float lower: the lower percentile to plot
|
||||
:param float upper: the upper percentile to plot
|
||||
: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.
|
||||
:type fixed_inputs: a list of tuples
|
||||
:param int resolution: The resolution of the prediction [default:200]
|
||||
: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 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().new_canvas(**kwargs)
|
||||
ycols = get_which_data_ycols(self, which_data_ycols)
|
||||
X = get_x_y_var(self)[0]
|
||||
helper_data = helper_for_plot_data(self, X, plot_limits, visible_dims, fixed_inputs, resolution)
|
||||
helper_prediction = helper_predict_with_model(self, helper_data[2], plot_raw, apply_link,
|
||||
(lower, upper),
|
||||
ycols, predict_kw)
|
||||
plots = _plot_confidence(self, canvas, helper_data, helper_prediction, label, **kwargs)
|
||||
return pl().add_to_canvas(canvas, plots, legend=label is not None)
|
||||
|
||||
def _plot_confidence(self, canvas, helper_data, helper_prediction, label, **kwargs):
|
||||
_, free_dims, Xgrid, _, _, _, _, _ = helper_data
|
||||
update_not_existing_kwargs(kwargs, pl().defaults.confidence_interval) # @UndefinedVariable
|
||||
if len(free_dims)<=1:
|
||||
if len(free_dims)==1:
|
||||
percs = helper_prediction[1]
|
||||
fills = []
|
||||
for d in range(helper_prediction[0].shape[1]):
|
||||
fills.append(pl().fill_between(canvas, Xgrid[:,free_dims[0]], percs[0][:,d], percs[1][:,d], label=label, **kwargs))
|
||||
return dict(gpconfidence=fills)
|
||||
else:
|
||||
pass #Nothing to plot!
|
||||
else:
|
||||
raise RuntimeError('Can only plot confidence interval in one input dimension')
|
||||
|
||||
|
||||
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, projection='2d', label='gp_samples',
|
||||
predict_kw=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Plot the mean of the GP.
|
||||
|
||||
You can deactivate the legend for this one plot by supplying None to label.
|
||||
|
||||
Give the Y_metadata in the predict_kw if you need it.
|
||||
|
||||
|
||||
|
||||
: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.
|
||||
: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? This is usually what you want!
|
||||
: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 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
|
||||
"""
|
||||
canvas, kwargs = pl().new_canvas(projection=projection, **kwargs)
|
||||
ycols = get_which_data_ycols(self, which_data_ycols)
|
||||
X = get_x_y_var(self)[0]
|
||||
helper_data = helper_for_plot_data(self, X, plot_limits, visible_dims, fixed_inputs, resolution)
|
||||
helper_prediction = helper_predict_with_model(self, helper_data[2], plot_raw, apply_link,
|
||||
None,
|
||||
ycols, predict_kw, samples)
|
||||
plots = _plot_samples(self, canvas, helper_data, helper_prediction,
|
||||
projection, label, **kwargs)
|
||||
return pl().add_to_canvas(canvas, plots)
|
||||
|
||||
def _plot_samples(self, canvas, helper_data, helper_prediction, projection,
|
||||
label, **kwargs):
|
||||
_, free_dims, Xgrid, x, y, _, _, resolution = helper_data
|
||||
samples = helper_prediction[2]
|
||||
|
||||
if len(free_dims)<=2:
|
||||
if len(free_dims)==1:
|
||||
# 1D plotting:
|
||||
update_not_existing_kwargs(kwargs, pl().defaults.samples_1d) # @UndefinedVariable
|
||||
plots = [pl().plot(canvas, Xgrid[:, free_dims], samples[:, s], label=label if s==0 else None, **kwargs) for s in range(samples.shape[-1])]
|
||||
elif len(free_dims)==2 and projection=='3d':
|
||||
update_not_existing_kwargs(kwargs, pl().defaults.samples_3d) # @UndefinedVariable
|
||||
plots = [pl().surface(canvas, x, y, samples[:, s].reshape(resolution, resolution), **kwargs) for s in range(samples.shape[-1])]
|
||||
else:
|
||||
pass # Nothing to plot!
|
||||
return dict(gpmean=plots)
|
||||
else:
|
||||
raise RuntimeError('Cannot plot mean in more then 1 input dimensions')
|
||||
|
||||
|
||||
def plot_density(self, plot_limits=None, fixed_inputs=None,
|
||||
resolution=None, plot_raw=False,
|
||||
apply_link=False, visible_dims=None,
|
||||
which_data_ycols='all',
|
||||
levels=35, label='gp density',
|
||||
predict_kw=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Plot the confidence interval between the percentiles lower and upper.
|
||||
E.g. the 95% confidence interval is $2.5, 97.5$.
|
||||
Note: Only implemented for one dimension!
|
||||
|
||||
You can deactivate the legend for this one plot by supplying None to label.
|
||||
|
||||
Give the Y_metadata in the predict_kw if you need it.
|
||||
|
||||
|
||||
|
||||
: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.
|
||||
:type fixed_inputs: a list of tuples
|
||||
:param int resolution: The resolution of the prediction [default:200]
|
||||
: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 array-like which_data_ycols: which columns of y to plot (array-like or list of ints)
|
||||
: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().new_canvas(**kwargs)
|
||||
X = get_x_y_var(self)[0]
|
||||
helper_data = helper_for_plot_data(self, X, plot_limits, visible_dims, fixed_inputs, resolution)
|
||||
helper_prediction = helper_predict_with_model(self, helper_data[2], plot_raw,
|
||||
apply_link, np.linspace(2.5, 97.5, levels*2),
|
||||
get_which_data_ycols(self, which_data_ycols),
|
||||
predict_kw)
|
||||
plots = _plot_density(self, canvas, helper_data, helper_prediction, label, **kwargs)
|
||||
return pl().add_to_canvas(canvas, plots)
|
||||
|
||||
def _plot_density(self, canvas, helper_data, helper_prediction, label, **kwargs):
|
||||
_, free_dims, Xgrid, _, _, _, _, _ = helper_data
|
||||
mu, percs, _ = helper_prediction
|
||||
|
||||
update_not_existing_kwargs(kwargs, pl().defaults.density) # @UndefinedVariable
|
||||
|
||||
if len(free_dims)<=1:
|
||||
if len(free_dims)==1:
|
||||
# 1D plotting:
|
||||
fills = []
|
||||
for d in range(mu.shape[1]):
|
||||
fills.append(pl().fill_gradient(canvas, Xgrid[:, free_dims[0]], [p[:,d] for p in percs], label=label, **kwargs))
|
||||
return dict(gpdensity=fills)
|
||||
else:
|
||||
pass # Nothing to plot!
|
||||
else:
|
||||
raise RuntimeError('Can only plot density in one input dimension')
|
||||
|
||||
def plot(self, plot_limits=None, fixed_inputs=None,
|
||||
resolution=None,
|
||||
plot_raw=False, apply_link=False,
|
||||
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, projection='2d', legend=True, **kwargs):
|
||||
"""
|
||||
Convenience function for plotting the fit of a GP.
|
||||
|
||||
You can deactivate the legend for this one plot by supplying None to label.
|
||||
|
||||
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.
|
||||
:type fixed_inputs: a list of tuples
|
||||
:param int resolution: The resolution of the prediction [default:200]
|
||||
: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 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 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 visible_dims: which columns of the input X (!) to plot (array-like or list of ints)
|
||||
: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 int samples: the number of samples to draw from the GP and plot into the plot. This will allways be samples from the latent function.
|
||||
:param int samples_likelihood: the number of samples to draw from the GP and apply the likelihood noise. This is usually not what you want!
|
||||
:param float lower: the lower percentile to plot
|
||||
:param float upper: the upper percentile to plot
|
||||
:param bool plot_data: plot the data into the plot?
|
||||
: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 {2d|3d} projection: plot in 2d or 3d?
|
||||
:param bool legend: convenience, whether to put a legend on the plot or not.
|
||||
"""
|
||||
canvas, _ = pl().new_canvas(projection=projection, **kwargs)
|
||||
X = get_x_y_var(self)[0]
|
||||
helper_data = helper_for_plot_data(self, X, plot_limits, visible_dims, fixed_inputs, resolution)
|
||||
helper_prediction = helper_predict_with_model(self, helper_data[2], plot_raw,
|
||||
apply_link, np.linspace(2.5, 97.5, levels*2) if plot_density else (lower,upper),
|
||||
get_which_data_ycols(self, which_data_ycols),
|
||||
predict_kw, samples)
|
||||
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
|
||||
plots = {}
|
||||
if plot_data:
|
||||
plots.update(_plot_data(self, canvas, which_data_rows, which_data_ycols, visible_dims, projection, "Data"))
|
||||
plots.update(_plot_data_error(self, canvas, which_data_rows, which_data_ycols, visible_dims, projection, "Data Error"))
|
||||
plots.update(_plot(self, canvas, plots, helper_data, helper_prediction, levels, plot_inducing, plot_density, projection))
|
||||
if plot_raw and (samples_likelihood > 0):
|
||||
helper_prediction = helper_predict_with_model(self, helper_data[2], False,
|
||||
apply_link, None,
|
||||
get_which_data_ycols(self, which_data_ycols),
|
||||
predict_kw, samples_likelihood)
|
||||
plots.update(_plot_samples(canvas, helper_data, helper_prediction, projection, "Lik Samples"))
|
||||
if hasattr(self, 'Z') and plot_inducing:
|
||||
plots.update(_plot_inducing(self, canvas, visible_dims, projection, 'Inducing'))
|
||||
return pl().add_to_canvas(canvas, plots, legend=legend)
|
||||
|
||||
|
||||
def plot_f(self, plot_limits=None, fixed_inputs=None,
|
||||
resolution=None,
|
||||
apply_link=False,
|
||||
which_data_ycols='all', which_data_rows='all',
|
||||
visible_dims=None,
|
||||
levels=20, samples=0, lower=2.5, upper=97.5,
|
||||
plot_density=False,
|
||||
plot_data=True, plot_inducing=True,
|
||||
projection='2d', legend=True,
|
||||
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.
|
||||
|
||||
You can deactivate the legend for this one plot by supplying None to label.
|
||||
|
||||
Give the Y_metadata in the predict_kw if you need it.
|
||||
|
||||
|
||||
: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.
|
||||
:type fixed_inputs: a list of tuples
|
||||
:param int resolution: The resolution of the prediction [default:200]
|
||||
:param bool apply_link: whether to apply the link function of the GP to the raw prediction.
|
||||
: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 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 visible_dims: an array specifying the input dimensions to plot (maximum two)
|
||||
: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 int samples: the number of samples to draw from the GP and plot into the plot. This will allways be samples from the latent function.
|
||||
:param float lower: the lower percentile to plot
|
||||
:param float upper: the upper percentile to plot
|
||||
:param bool plot_data: plot the data into the plot?
|
||||
: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
|
||||
"""
|
||||
plot(self, 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, projection, legend)
|
||||
|
||||
|
||||
|
||||
def _plot(self, canvas, plots, helper_data, helper_prediction, levels, plot_inducing=True, plot_density=False, projection='2d'):
|
||||
plots.update(_plot_mean(self, canvas, helper_data, helper_prediction, levels, projection, 'Mean'))
|
||||
|
||||
try:
|
||||
if projection=='2d':
|
||||
if not plot_density:
|
||||
plots.update(_plot_confidence(self, canvas, helper_data, helper_prediction, "Confidence"))
|
||||
else:
|
||||
plots.update(_plot_density(self, canvas, helper_data, helper_prediction, "Density"))
|
||||
except RuntimeError:
|
||||
#plotting in 2d
|
||||
pass
|
||||
|
||||
if helper_prediction[2] is not None:
|
||||
plots.update(_plot_samples(self, canvas, helper_data, helper_prediction, projection, "Samples"))
|
||||
return plots
|
||||
27
GPy/plotting/gpy_plot/inference_plots.py
Normal file
27
GPy/plotting/gpy_plot/inference_plots.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
#import numpy as np
|
||||
#import Tango
|
||||
#from base_plots import gpplot, x_frame1D, x_frame2D
|
||||
|
||||
from . import plotting_library as pl
|
||||
|
||||
def plot_optimizer(optimizer, **kwargs):
|
||||
if optimizer.trace == None:
|
||||
print("No trace present so I can't plot it. Please check that the optimizer actually supplies a trace.")
|
||||
else:
|
||||
canvas, kwargs = pl().new_canvas(**kwargs)
|
||||
plots = dict(trace=pl().plot(range(len(optimizer.trace)), optimizer.trace))
|
||||
return pl().add_to_canvas(canvas, plots, xlabel='Iteration', ylabel='f(x)')
|
||||
|
||||
def plot_sgd_traces(optimizer):
|
||||
figure = pl().figure(2,1)
|
||||
canvas, _ = pl().new_canvas(figure, 1, 1, title="Parameters")
|
||||
plots = dict(lines=[])
|
||||
for k in optimizer.param_traces.keys():
|
||||
plots['lines'].append(pl().plot(canvas, range(len(optimizer.param_traces[k])), optimizer.param_traces[k], label=k))
|
||||
pl().add_to_canvas(canvas, legend=True)
|
||||
canvas, _ = pl().new_canvas(figure, 1, 2, title="Objective function")
|
||||
pl().plot(canvas, range(len(optimizer.fopt_trace)), optimizer.fopt_trace)
|
||||
return pl().add_to_canvas(canvas, plots, legend=True)
|
||||
139
GPy/plotting/gpy_plot/kernel_plots.py
Normal file
139
GPy/plotting/gpy_plot/kernel_plots.py
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
#===============================================================================
|
||||
# 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 plotting_library as pl
|
||||
from .. import Tango
|
||||
from .plot_util import update_not_existing_kwargs, helper_for_plot_data
|
||||
from ...kern.src.kern import Kern, CombinationKernel
|
||||
|
||||
def plot_ARD(kernel, filtering=None, legend=False, **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
|
||||
"""
|
||||
Tango.reset()
|
||||
|
||||
ard_params = np.atleast_2d(kernel.input_sensitivity(summarize=False))
|
||||
bottom = 0
|
||||
last_bottom = bottom
|
||||
|
||||
x = np.arange(kernel.input_dim)
|
||||
|
||||
parts = []
|
||||
def visit(x):
|
||||
if (not isinstance(x, CombinationKernel)) and isinstance(x, Kern):
|
||||
parts.append(x)
|
||||
kernel.traverse(visit)
|
||||
|
||||
if filtering is None:
|
||||
filtering = [k.name for k in parts]
|
||||
|
||||
bars = []
|
||||
kwargs = update_not_existing_kwargs(kwargs, pl().defaults.ard)
|
||||
canvas, kwargs = pl().new_canvas(xlim=(-.5, kernel.input_dim-.5), xlabel='input dimension', ylabel='sensitivity', **kwargs)
|
||||
for i in range(ard_params.shape[0]):
|
||||
if parts[i].name in filtering:
|
||||
c = Tango.nextMedium()
|
||||
bars.append(pl().barplot(canvas, x,
|
||||
ard_params[i,:], color=c,
|
||||
label=parts[i].name,
|
||||
bottom=bottom, **kwargs))
|
||||
last_bottom = ard_params[i,:]
|
||||
bottom += last_bottom
|
||||
else:
|
||||
print("filtering out {}".format(parts[i].name))
|
||||
|
||||
#add_bar_labels(fig, ax, [bars[-1]], bottom=bottom-last_bottom)
|
||||
|
||||
return pl().add_to_canvas(canvas, bars, legend=legend)
|
||||
|
||||
def plot_covariance(kernel, x=None, label=None,
|
||||
plot_limits=None, visible_dims=None, resolution=None,
|
||||
projection='2d', levels=20, **kwargs):
|
||||
"""
|
||||
Plot a kernel covariance w.r.t. another x.
|
||||
|
||||
:param array-like x: the value to use for the other kernel argument (kernels are a function of two variables!)
|
||||
:param plot_limits: the range over which to plot the kernel
|
||||
:type plot_limits: Either (xmin, xmax) for 1D or (xmin, xmax, ymin, ymax) / ((xmin, xmax), (ymin, ymax)) for 2D
|
||||
:param array-like visible_dims: input dimensions (!) to use for x. Make sure to select 2 or less dimensions to plot.
|
||||
:resolution: the resolution of the lines used in plotting. for 2D this defines the grid for kernel evaluation.
|
||||
:param {2d|3d} projection: What projection shall we use to plot the kernel?
|
||||
:param int levels: for 2D projection, how many levels for the contour plot to use?
|
||||
:param kwargs: valid kwargs for your specific plotting library
|
||||
"""
|
||||
X = np.ones((2, kernel.input_dim)) * [[-3], [3]]
|
||||
_, free_dims, Xgrid, xx, yy, _, _, resolution = helper_for_plot_data(kernel, X, plot_limits, visible_dims, None, resolution)
|
||||
|
||||
from numbers import Number
|
||||
if x is None:
|
||||
from ...kern.src.stationary import Stationary
|
||||
x = np.ones((1, kernel.input_dim)) * (not isinstance(kernel, Stationary))
|
||||
elif isinstance(x, Number):
|
||||
x = np.ones((1, kernel.input_dim))*x
|
||||
K = kernel.K(Xgrid, x)
|
||||
|
||||
if projection == '3d':
|
||||
xlabel = 'X[:,0]'
|
||||
ylabel = 'X[:,1]'
|
||||
zlabel = "k(X, {!s})".format(np.asanyarray(x).tolist())
|
||||
else:
|
||||
xlabel = 'X'
|
||||
ylabel = "k(X, {!s})".format(np.asanyarray(x).tolist())
|
||||
zlabel = None
|
||||
|
||||
canvas, kwargs = pl().new_canvas(projection=projection, xlabel=xlabel, ylabel=ylabel, zlabel=zlabel, **kwargs)
|
||||
|
||||
if len(free_dims)<=2:
|
||||
if len(free_dims)==1:
|
||||
# 1D plotting:
|
||||
update_not_existing_kwargs(kwargs, pl().defaults.meanplot_1d) # @UndefinedVariable
|
||||
plots = dict(covariance=[pl().plot(canvas, Xgrid[:, free_dims], K, label=label, **kwargs)])
|
||||
else:
|
||||
if projection == '2d':
|
||||
update_not_existing_kwargs(kwargs, pl().defaults.meanplot_2d) # @UndefinedVariable
|
||||
plots = dict(covariance=[pl().contour(canvas, xx[:, 0], yy[0, :],
|
||||
K.reshape(resolution, resolution),
|
||||
levels=levels, label=label, **kwargs)])
|
||||
elif projection == '3d':
|
||||
update_not_existing_kwargs(kwargs, pl().defaults.meanplot_3d) # @UndefinedVariable
|
||||
plots = dict(covariance=[pl().surface(canvas, xx, yy,
|
||||
K.reshape(resolution, resolution),
|
||||
label=label,
|
||||
**kwargs)])
|
||||
return pl().add_to_canvas(canvas, plots)
|
||||
|
||||
else:
|
||||
raise NotImplementedError("Cannot plot a kernel with more than two input dimensions")
|
||||
335
GPy/plotting/gpy_plot/latent_plots.py
Normal file
335
GPy/plotting/gpy_plot/latent_plots.py
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
#===============================================================================
|
||||
# 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 plotting_library as pl
|
||||
from .plot_util import get_x_y_var,\
|
||||
update_not_existing_kwargs, \
|
||||
helper_for_plot_data, scatter_label_generator, subsample_X,\
|
||||
find_best_layout_for_subplots
|
||||
|
||||
def _wait_for_updates(view, updates):
|
||||
if view is not None:
|
||||
try:
|
||||
if updates:
|
||||
clear = raw_input('yes or enter to deactivate updates - otherwise still do updates - use plots[imshow].deactivate() to clear')
|
||||
if clear.lower() in 'yes' or clear == '':
|
||||
view.deactivate()
|
||||
else:
|
||||
view.deactivate()
|
||||
except AttributeError:
|
||||
# No updateable view:
|
||||
pass
|
||||
except TypeError:
|
||||
# No updateable view:
|
||||
pass
|
||||
|
||||
|
||||
def _plot_latent_scatter(canvas, X, visible_dims, labels, marker, num_samples, projection='2d', **kwargs):
|
||||
from .. import Tango
|
||||
Tango.reset()
|
||||
X, labels = subsample_X(X, labels, num_samples)
|
||||
scatters = []
|
||||
generate_colors = 'color' not in kwargs
|
||||
for x, y, z, this_label, _, m in scatter_label_generator(labels, X, visible_dims, marker):
|
||||
update_not_existing_kwargs(kwargs, pl().defaults.latent_scatter)
|
||||
if generate_colors:
|
||||
kwargs['color'] = Tango.nextMedium()
|
||||
if projection == '3d':
|
||||
scatters.append(pl().scatter(canvas, x, y, Z=z, marker=m, label=this_label, **kwargs))
|
||||
else: scatters.append(pl().scatter(canvas, x, y, marker=m, label=this_label, **kwargs))
|
||||
return scatters
|
||||
|
||||
def plot_latent_scatter(self, labels=None,
|
||||
which_indices=None,
|
||||
legend=True,
|
||||
plot_limits=None,
|
||||
marker='<>^vsd',
|
||||
num_samples=1000,
|
||||
projection='2d',
|
||||
**kwargs):
|
||||
"""
|
||||
Plot a scatter plot of the latent space.
|
||||
|
||||
:param array-like labels: a label for each data point (row) of the inputs
|
||||
:param (int, int) which_indices: which input dimensions to plot against each other
|
||||
:param bool legend: whether to plot the legend on the figure
|
||||
:param plot_limits: the plot limits for the plot
|
||||
:type plot_limits: (xmin, xmax, ymin, ymax) or ((xmin, xmax), (ymin, ymax))
|
||||
:param str marker: markers to use - cycle if more labels then markers are given
|
||||
:param kwargs: the kwargs for the scatter plots
|
||||
"""
|
||||
input_1, input_2, input_3 = sig_dims = self.get_most_significant_input_dimensions(which_indices)
|
||||
|
||||
canvas, kwargs = pl().new_canvas(projection=projection,
|
||||
xlabel='latent dimension %i' % input_1,
|
||||
ylabel='latent dimension %i' % input_2,
|
||||
zlabel='latent dimension %i' % input_3, **kwargs)
|
||||
X, _, _ = get_x_y_var(self)
|
||||
if labels is None:
|
||||
labels = np.ones(self.num_data)
|
||||
legend = False
|
||||
else:
|
||||
legend = find_best_layout_for_subplots(len(np.unique(labels)))[1]
|
||||
scatters = _plot_latent_scatter(canvas, X, sig_dims, labels, marker, num_samples, projection=projection, **kwargs)
|
||||
return pl().add_to_canvas(canvas, dict(scatter=scatters), legend=legend)
|
||||
|
||||
|
||||
|
||||
|
||||
def plot_latent_inducing(self,
|
||||
which_indices=None,
|
||||
legend=False,
|
||||
plot_limits=None,
|
||||
marker='^',
|
||||
num_samples=1000,
|
||||
projection='2d',
|
||||
**kwargs):
|
||||
"""
|
||||
Plot a scatter plot of the inducing inputs.
|
||||
|
||||
:param array-like labels: a label for each data point (row) of the inputs
|
||||
:param (int, int) which_indices: which input dimensions to plot against each other
|
||||
:param bool legend: whether to plot the legend on the figure
|
||||
:param plot_limits: the plot limits for the plot
|
||||
:type plot_limits: (xmin, xmax, ymin, ymax) or ((xmin, xmax), (ymin, ymax))
|
||||
:param str marker: markers to use - cycle if more labels then markers are given
|
||||
:param kwargs: the kwargs for the scatter plots
|
||||
"""
|
||||
input_1, input_2, input_3 = sig_dims = self.get_most_significant_input_dimensions(which_indices)
|
||||
|
||||
if 'color' not in kwargs:
|
||||
kwargs['color'] = 'white'
|
||||
canvas, kwargs = pl().new_canvas(projection=projection,
|
||||
xlabel='latent dimension %i' % input_1,
|
||||
ylabel='latent dimension %i' % input_2,
|
||||
zlabel='latent dimension %i' % input_3, **kwargs)
|
||||
Z = self.Z.values
|
||||
labels = np.array(['inducing'] * Z.shape[0])
|
||||
scatters = _plot_latent_scatter(canvas, Z, sig_dims, labels, marker, num_samples, projection=projection, **kwargs)
|
||||
return pl().add_to_canvas(canvas, dict(scatter=scatters), legend=legend)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def _plot_magnification(self, canvas, which_indices, Xgrid,
|
||||
xmin, xmax, resolution, updates,
|
||||
mean=True, covariance=True,
|
||||
kern=None,
|
||||
**imshow_kwargs):
|
||||
def plot_function(x):
|
||||
Xtest_full = np.zeros((x.shape[0], Xgrid.shape[1]))
|
||||
Xtest_full[:, which_indices] = x
|
||||
mf = self.predict_magnification(Xtest_full, kern=kern, mean=mean, covariance=covariance)
|
||||
return mf.reshape(resolution, resolution).T
|
||||
imshow_kwargs = update_not_existing_kwargs(imshow_kwargs, pl().defaults.magnification)
|
||||
try:
|
||||
if updates:
|
||||
return pl().imshow_interact(canvas, plot_function, (xmin[0], xmax[0], xmin[1], xmax[1]), resolution=resolution, **imshow_kwargs)
|
||||
else: raise NotImplementedError
|
||||
except NotImplementedError:
|
||||
return pl().imshow(canvas, plot_function(Xgrid[:, which_indices]), (xmin[0], xmax[0], xmin[1], xmax[1]), **imshow_kwargs)
|
||||
|
||||
def plot_magnification(self, labels=None, which_indices=None,
|
||||
resolution=60, marker='<>^vsd', legend=True,
|
||||
plot_limits=None,
|
||||
updates=False,
|
||||
mean=True, covariance=True,
|
||||
kern=None, num_samples=1000,
|
||||
scatter_kwargs=None, **imshow_kwargs):
|
||||
"""
|
||||
Plot the magnification factor of the GP on the inputs. This is the
|
||||
density of the GP as a gray scale.
|
||||
|
||||
:param array-like labels: a label for each data point (row) of the inputs
|
||||
:param (int, int) which_indices: which input dimensions to plot against each other
|
||||
:param int resolution: the resolution at which we predict the magnification factor
|
||||
:param str marker: markers to use - cycle if more labels then markers are given
|
||||
:param bool legend: whether to plot the legend on the figure
|
||||
:param plot_limits: the plot limits for the plot
|
||||
:type plot_limits: (xmin, xmax, ymin, ymax) or ((xmin, xmax), (ymin, ymax))
|
||||
:param bool updates: if possible, make interactive updates using the specific library you are using
|
||||
:param bool mean: use the mean of the Wishart embedding for the magnification factor
|
||||
:param bool covariance: use the covariance of the Wishart embedding for the magnification factor
|
||||
:param :py:class:`~GPy.kern.Kern` kern: the kernel to use for prediction
|
||||
:param int num_samples: the number of samples to plot maximally. We do a stratified subsample from the labels, if the number of samples (in X) is higher then num_samples.
|
||||
:param imshow_kwargs: the kwargs for the imshow (magnification factor)
|
||||
:param kwargs: the kwargs for the scatter plots
|
||||
"""
|
||||
input_1, input_2 = which_indices = self.get_most_significant_input_dimensions(which_indices)[:2]
|
||||
X = get_x_y_var(self)[0]
|
||||
_, _, Xgrid, _, _, xmin, xmax, resolution = helper_for_plot_data(self, X, plot_limits, which_indices, None, resolution)
|
||||
canvas, imshow_kwargs = pl().new_canvas(xlim=(xmin[0], xmax[0]), ylim=(xmin[1], xmax[1]),
|
||||
xlabel='latent dimension %i' % input_1, ylabel='latent dimension %i' % input_2, **imshow_kwargs)
|
||||
if (labels is not None):
|
||||
legend = find_best_layout_for_subplots(len(np.unique(labels)))[1]
|
||||
else:
|
||||
labels = np.ones(self.num_data)
|
||||
legend = False
|
||||
scatters = _plot_latent_scatter(canvas, X, which_indices, labels, marker, num_samples, projection='2d', **scatter_kwargs or {})
|
||||
view = _plot_magnification(self, canvas, which_indices[:2], Xgrid, xmin, xmax, resolution, updates, mean, covariance, kern, **imshow_kwargs)
|
||||
retval = pl().add_to_canvas(canvas, dict(scatter=scatters, imshow=view),
|
||||
legend=legend,
|
||||
)
|
||||
_wait_for_updates(view, updates)
|
||||
return retval
|
||||
|
||||
|
||||
|
||||
|
||||
def _plot_latent(self, canvas, which_indices, Xgrid,
|
||||
xmin, xmax, resolution, updates,
|
||||
kern=None,
|
||||
**imshow_kwargs):
|
||||
def plot_function(x):
|
||||
Xtest_full = np.zeros((x.shape[0], Xgrid.shape[1]))
|
||||
Xtest_full[:, which_indices] = x
|
||||
mf = np.log(self.predict(Xtest_full, kern=kern)[1])
|
||||
return mf.reshape(resolution, resolution).T
|
||||
|
||||
imshow_kwargs = update_not_existing_kwargs(imshow_kwargs, pl().defaults.latent)
|
||||
try:
|
||||
if updates:
|
||||
return pl().imshow_interact(canvas, plot_function, (xmin[0], xmax[0], xmin[1], xmax[1]), resolution=resolution, **imshow_kwargs)
|
||||
else: raise NotImplementedError
|
||||
except NotImplementedError:
|
||||
return pl().imshow(canvas, plot_function(Xgrid[:, which_indices]), (xmin[0], xmax[0], xmin[1], xmax[1]), **imshow_kwargs)
|
||||
|
||||
def plot_latent(self, labels=None, which_indices=None,
|
||||
resolution=60, legend=True,
|
||||
plot_limits=None,
|
||||
updates=False,
|
||||
kern=None, marker='<>^vsd',
|
||||
num_samples=1000,
|
||||
scatter_kwargs=None, **imshow_kwargs):
|
||||
"""
|
||||
Plot the latent space of the GP on the inputs. This is the
|
||||
density of the GP posterior as a grey scale and the
|
||||
scatter plot of the input dimemsions selected by which_indices.
|
||||
|
||||
:param array-like labels: a label for each data point (row) of the inputs
|
||||
:param (int, int) which_indices: which input dimensions to plot against each other
|
||||
:param int resolution: the resolution at which we predict the magnification factor
|
||||
:param bool legend: whether to plot the legend on the figure
|
||||
:param plot_limits: the plot limits for the plot
|
||||
:type plot_limits: (xmin, xmax, ymin, ymax) or ((xmin, xmax), (ymin, ymax))
|
||||
:param bool updates: if possible, make interactive updates using the specific library you are using
|
||||
:param :py:class:`~GPy.kern.Kern` kern: the kernel to use for prediction
|
||||
:param str marker: markers to use - cycle if more labels then markers are given
|
||||
:param int num_samples: the number of samples to plot maximally. We do a stratified subsample from the labels, if the number of samples (in X) is higher then num_samples.
|
||||
:param imshow_kwargs: the kwargs for the imshow (magnification factor)
|
||||
:param scatter_kwargs: the kwargs for the scatter plots
|
||||
"""
|
||||
input_1, input_2 = which_indices = self.get_most_significant_input_dimensions(which_indices)[:2]
|
||||
X = get_x_y_var(self)[0]
|
||||
_, _, Xgrid, _, _, xmin, xmax, resolution = helper_for_plot_data(self, X, plot_limits, which_indices, None, resolution)
|
||||
canvas, imshow_kwargs = pl().new_canvas(xlim=(xmin[0], xmax[0]), ylim=(xmin[1], xmax[1]),
|
||||
xlabel='latent dimension %i' % input_1, ylabel='latent dimension %i' % input_2, **imshow_kwargs)
|
||||
if (labels is not None):
|
||||
legend = find_best_layout_for_subplots(len(np.unique(labels)))[1]
|
||||
else:
|
||||
labels = np.ones(self.num_data)
|
||||
legend = False
|
||||
scatters = _plot_latent_scatter(canvas, X, which_indices, labels, marker, num_samples, projection='2d', **scatter_kwargs or {})
|
||||
view = _plot_latent(self, canvas, which_indices, Xgrid, xmin, xmax, resolution, updates, kern, **imshow_kwargs)
|
||||
retval = pl().add_to_canvas(canvas, dict(scatter=scatters, imshow=view), legend=legend)
|
||||
_wait_for_updates(view, updates)
|
||||
return retval
|
||||
|
||||
def _plot_steepest_gradient_map(self, canvas, which_indices, Xgrid,
|
||||
xmin, xmax, resolution, output_labels, updates,
|
||||
kern=None, annotation_kwargs=None,
|
||||
**imshow_kwargs):
|
||||
if output_labels is None:
|
||||
output_labels = range(self.output_dim)
|
||||
def plot_function(x):
|
||||
Xgrid[:, which_indices] = x
|
||||
dmu_dX = np.sqrt(((self.predictive_gradients(Xgrid, kern=kern)[0])**2).sum(1))
|
||||
#dmu_dX = self.predictive_gradients(Xgrid, kern=kern)[0].sum(1)
|
||||
argmax = np.argmax(dmu_dX, 1).astype(int)
|
||||
return dmu_dX.max(1).reshape(resolution, resolution).T, np.array(output_labels)[argmax].reshape(resolution, resolution).T
|
||||
annotation_kwargs = update_not_existing_kwargs(annotation_kwargs or {}, pl().defaults.annotation)
|
||||
imshow_kwargs = update_not_existing_kwargs(imshow_kwargs or {}, pl().defaults.gradient)
|
||||
try:
|
||||
if updates:
|
||||
return dict(annotation=pl().annotation_heatmap_interact(canvas, plot_function, (xmin[0], xmax[0], xmin[1], xmax[1]), resolution=resolution, imshow_kwargs=imshow_kwargs, **annotation_kwargs))
|
||||
else:
|
||||
raise NotImplementedError
|
||||
except NotImplementedError:
|
||||
imshow, annotation = pl().annotation_heatmap(canvas, *plot_function(Xgrid[:, which_indices]), extent=(xmin[0], xmax[0], xmin[1], xmax[1]), imshow_kwargs=imshow_kwargs, **annotation_kwargs)
|
||||
return dict(heatmap=imshow, annotation=annotation)
|
||||
|
||||
def plot_steepest_gradient_map(self, output_labels=None, data_labels=None, which_indices=None,
|
||||
resolution=15, legend=True,
|
||||
plot_limits=None,
|
||||
updates=False,
|
||||
kern=None, marker='<>^vsd',
|
||||
num_samples=1000,
|
||||
annotation_kwargs=None, scatter_kwargs=None, **imshow_kwargs):
|
||||
|
||||
"""
|
||||
Plot the latent space of the GP on the inputs. This is the
|
||||
density of the GP posterior as a grey scale and the
|
||||
scatter plot of the input dimemsions selected by which_indices.
|
||||
|
||||
:param array-like labels: a label for each data point (row) of the inputs
|
||||
:param (int, int) which_indices: which input dimensions to plot against each other
|
||||
:param int resolution: the resolution at which we predict the magnification factor
|
||||
:param bool legend: whether to plot the legend on the figure, if int plot legend columns on legend
|
||||
:param plot_limits: the plot limits for the plot
|
||||
:type plot_limits: (xmin, xmax, ymin, ymax) or ((xmin, xmax), (ymin, ymax))
|
||||
:param bool updates: if possible, make interactive updates using the specific library you are using
|
||||
:param :py:class:`~GPy.kern.Kern` kern: the kernel to use for prediction
|
||||
:param str marker: markers to use - cycle if more labels then markers are given
|
||||
:param int num_samples: the number of samples to plot maximally. We do a stratified subsample from the labels, if the number of samples (in X) is higher then num_samples.
|
||||
:param imshow_kwargs: the kwargs for the imshow (magnification factor)
|
||||
:param annotation_kwargs: the kwargs for the annotation plot
|
||||
:param scatter_kwargs: the kwargs for the scatter plots
|
||||
"""
|
||||
input_1, input_2 = which_indices = self.get_most_significant_input_dimensions(which_indices)[:2]
|
||||
X = get_x_y_var(self)[0]
|
||||
_, _, Xgrid, _, _, xmin, xmax, resolution = helper_for_plot_data(self, X, plot_limits, which_indices, None, resolution)
|
||||
canvas, imshow_kwargs = pl().new_canvas(xlim=(xmin[0], xmax[0]), ylim=(xmin[1], xmax[1]),
|
||||
xlabel='latent dimension %i' % input_1, ylabel='latent dimension %i' % input_2, **imshow_kwargs)
|
||||
if (data_labels is not None):
|
||||
legend = find_best_layout_for_subplots(len(np.unique(data_labels)))[1]
|
||||
else:
|
||||
data_labels = np.ones(self.num_data)
|
||||
legend = False
|
||||
plots = dict(scatter=_plot_latent_scatter(canvas, X, which_indices, data_labels, marker, num_samples, **scatter_kwargs or {}))
|
||||
plots.update(_plot_steepest_gradient_map(self, canvas, which_indices, Xgrid, xmin, xmax, resolution, output_labels, updates, kern, annotation_kwargs=annotation_kwargs, **imshow_kwargs))
|
||||
retval = pl().add_to_canvas(canvas, plots, legend=legend)
|
||||
_wait_for_updates(plots['annotation'], updates)
|
||||
return retval
|
||||
|
||||
|
||||
|
||||
|
||||
375
GPy/plotting/gpy_plot/plot_util.py
Normal file
375
GPy/plotting/gpy_plot/plot_util.py
Normal file
|
|
@ -0,0 +1,375 @@
|
|||
#===============================================================================
|
||||
# Copyright (c) 2012-2015, GPy authors (see AUTHORS.txt).
|
||||
# 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 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 scipy import sparse
|
||||
import itertools
|
||||
|
||||
def in_ipynb():
|
||||
try:
|
||||
cfg = get_ipython().config
|
||||
return 'IPKernelApp' in cfg
|
||||
except NameError:
|
||||
return False
|
||||
|
||||
def find_best_layout_for_subplots(num_subplots):
|
||||
r, c = 1, 1
|
||||
while (r*c) < num_subplots:
|
||||
if (c==(r+1)) or (r==c):
|
||||
c += 1
|
||||
elif c==(r+2):
|
||||
r += 1
|
||||
c -= 1
|
||||
return r, c
|
||||
|
||||
def helper_predict_with_model(self, Xgrid, plot_raw, apply_link, percentiles, which_data_ycols, predict_kw, samples=0):
|
||||
"""
|
||||
Make the right decisions for prediction with a model
|
||||
based on the standard arguments of plotting.
|
||||
|
||||
This is quite complex and will take a while to understand,
|
||||
so do not change anything in here lightly!!!
|
||||
"""
|
||||
# Put some standards into the predict_kw so that prediction is done automatically:
|
||||
if predict_kw is None:
|
||||
predict_kw = {}
|
||||
if 'likelihood' not in predict_kw:
|
||||
if plot_raw:
|
||||
from ...likelihoods import Gaussian
|
||||
from ...likelihoods.link_functions import Identity
|
||||
lik = Gaussian(Identity(), 1e-9) # Make the likelihood not add any noise
|
||||
else:
|
||||
lik = None
|
||||
predict_kw['likelihood'] = lik
|
||||
if 'Y_metadata' not in predict_kw:
|
||||
predict_kw['Y_metadata'] = {}
|
||||
if 'output_index' not in predict_kw['Y_metadata']:
|
||||
predict_kw['Y_metadata']['output_index'] = Xgrid[:,-1:].astype(np.int)
|
||||
|
||||
mu, _ = self.predict(Xgrid, **predict_kw)
|
||||
|
||||
if percentiles is not None:
|
||||
percentiles = self.predict_quantiles(Xgrid, quantiles=percentiles, **predict_kw)
|
||||
else: percentiles = []
|
||||
|
||||
if samples > 0:
|
||||
fsamples = self.posterior_samples(Xgrid, full_cov=True, size=samples, **predict_kw)
|
||||
fsamples = fsamples[which_data_ycols] if fsamples.ndim == 3 else fsamples
|
||||
else:
|
||||
fsamples = None
|
||||
|
||||
# Filter out the ycolums which we want to plot:
|
||||
retmu = mu[:, which_data_ycols]
|
||||
percs = [p[:, which_data_ycols] for p in percentiles]
|
||||
|
||||
if plot_raw and apply_link:
|
||||
for i in range(len(which_data_ycols)):
|
||||
retmu[:, [i]] = self.likelihood.gp_link.transf(mu[:, [i]])
|
||||
for perc in percs:
|
||||
perc[:, [i]] = self.likelihood.gp_link.transf(perc[:, [i]])
|
||||
if fsamples is not None and fsamples.ndim == 3:
|
||||
for s in range(fsamples.shape[-1]):
|
||||
fsamples[i, :, s] = self.likelihood.gp_link.transf(fsamples[i, :, s])
|
||||
elif fsamples is not None:
|
||||
for s in range(fsamples.shape[-1]):
|
||||
fsamples[:, s] = self.likelihood.gp_link.transf(fsamples[:, s])
|
||||
return retmu, percs, fsamples
|
||||
|
||||
def helper_for_plot_data(self, X, plot_limits, visible_dims, fixed_inputs, resolution):
|
||||
"""
|
||||
Figure out the data, free_dims and create an Xgrid for
|
||||
the prediction.
|
||||
|
||||
This is only implemented for two dimensions for now!
|
||||
"""
|
||||
#work out what the inputs are for plotting (1D or 2D)
|
||||
if fixed_inputs is None:
|
||||
fixed_inputs = []
|
||||
fixed_dims = get_fixed_dims(fixed_inputs)
|
||||
free_dims = get_free_dims(self, visible_dims, fixed_dims)
|
||||
|
||||
if len(free_dims) == 1:
|
||||
#define the frame on which to plot
|
||||
resolution = resolution or 200
|
||||
Xnew, xmin, xmax = x_frame1D(X[:,free_dims], plot_limits=plot_limits, resolution=resolution)
|
||||
Xgrid = np.zeros((Xnew.shape[0],self.input_dim))
|
||||
Xgrid[:,free_dims] = Xnew
|
||||
for i,v in fixed_inputs:
|
||||
Xgrid[:,i] = v
|
||||
x = Xgrid
|
||||
y = None
|
||||
elif len(free_dims) == 2:
|
||||
#define the frame for plotting on
|
||||
resolution = resolution or 35
|
||||
Xnew, x, y, xmin, xmax = x_frame2D(X[:,free_dims], plot_limits, resolution)
|
||||
Xgrid = np.zeros((Xnew.shape[0], self.input_dim))
|
||||
Xgrid[:,free_dims] = Xnew
|
||||
for i,v in fixed_inputs:
|
||||
Xgrid[:,i] = v
|
||||
else:
|
||||
raise TypeError("calculated free_dims {} from visible_dims {} and fixed_dims {} is neither 1D nor 2D".format(free_dims, visible_dims, fixed_dims))
|
||||
return fixed_dims, free_dims, Xgrid, x, y, xmin, xmax, resolution
|
||||
|
||||
def scatter_label_generator(labels, X, visible_dims, marker=None):
|
||||
ulabels = []
|
||||
for lab in labels:
|
||||
if not lab in ulabels:
|
||||
ulabels.append(lab)
|
||||
if marker is not None:
|
||||
marker = itertools.cycle(list(marker))
|
||||
else:
|
||||
m = None
|
||||
|
||||
try:
|
||||
input_1, input_2, input_3 = visible_dims
|
||||
except:
|
||||
try:
|
||||
# tuple or int?
|
||||
input_1, input_2 = visible_dims
|
||||
input_3 = None
|
||||
except:
|
||||
input_1 = visible_dims
|
||||
input_2 = input_3 = None
|
||||
|
||||
for ul in ulabels:
|
||||
from numbers import Number
|
||||
if isinstance(ul, str):
|
||||
try:
|
||||
this_label = unicode(ul)
|
||||
except NameError:
|
||||
#python3
|
||||
this_label = ul
|
||||
elif isinstance(ul, Number):
|
||||
this_label = 'class {!s}'.format(ul)
|
||||
else:
|
||||
this_label = ul
|
||||
|
||||
if marker is not None:
|
||||
m = next(marker)
|
||||
|
||||
index = np.nonzero(labels == ul)[0]
|
||||
|
||||
if input_2 is None:
|
||||
x = X[index, input_1]
|
||||
y = np.zeros(index.size)
|
||||
z = None
|
||||
elif input_3 is None:
|
||||
x = X[index, input_1]
|
||||
y = X[index, input_2]
|
||||
z = None
|
||||
else:
|
||||
x = X[index, input_1]
|
||||
y = X[index, input_2]
|
||||
z = X[index, input_3]
|
||||
yield x, y, z, this_label, index, m
|
||||
|
||||
def subsample_X(X, labels, num_samples=1000):
|
||||
"""
|
||||
Stratified subsampling if labels are given.
|
||||
This means due to rounding errors you might get a little differences between the
|
||||
num_samples and the returned subsampled X.
|
||||
"""
|
||||
if X.shape[0] > num_samples:
|
||||
print("Warning: subsampling X, as it has more samples then 1000. X.shape={!s}".format(X.shape))
|
||||
if labels is not None:
|
||||
subsample = []
|
||||
for _, _, _, _, index, _ in scatter_label_generator(labels, X, (0, None, None)):
|
||||
subsample.append(np.random.choice(index, size=max(2, int(index.size*(float(num_samples)/X.shape[0]))), replace=False))
|
||||
subsample = np.hstack(subsample)
|
||||
else:
|
||||
subsample = np.random.choice(X.shape[0], size=1000, replace=False)
|
||||
X = X[subsample]
|
||||
labels = labels[subsample]
|
||||
#=======================================================================
|
||||
# <<<WORK IN PROGRESS>>>
|
||||
# <<<DO NOT DELETE>>>
|
||||
# plt.close('all')
|
||||
# fig, ax = plt.subplots(1,1)
|
||||
# from GPy.plotting.matplot_dep.dim_reduction_plots import most_significant_input_dimensions
|
||||
# import matplotlib.patches as mpatches
|
||||
# i1, i2 = most_significant_input_dimensions(m, None)
|
||||
# xmin, xmax = 100, -100
|
||||
# ymin, ymax = 100, -100
|
||||
# legend_handles = []
|
||||
#
|
||||
# X = m.X.mean[:, [i1, i2]]
|
||||
# X = m.X.variance[:, [i1, i2]]
|
||||
#
|
||||
# xmin = X[:,0].min(); xmax = X[:,0].max()
|
||||
# ymin = X[:,1].min(); ymax = X[:,1].max()
|
||||
# range_ = [[xmin, xmax], [ymin, ymax]]
|
||||
# ul = np.unique(labels)
|
||||
#
|
||||
# for i, l in enumerate(ul):
|
||||
# #cdict = dict(red =[(0., colors[i][0], colors[i][0]), (1., colors[i][0], colors[i][0])],
|
||||
# # green=[(0., colors[i][0], colors[i][1]), (1., colors[i][1], colors[i][1])],
|
||||
# # blue =[(0., colors[i][0], colors[i][2]), (1., colors[i][2], colors[i][2])],
|
||||
# # alpha=[(0., 0., .0), (.5, .5, .5), (1., .5, .5)])
|
||||
# #cmap = LinearSegmentedColormap('{}'.format(l), cdict)
|
||||
# cmap = LinearSegmentedColormap.from_list('cmap_{}'.format(str(l)), [colors[i], colors[i]], 255)
|
||||
# cmap._init()
|
||||
# #alphas = .5*(1+scipy.special.erf(np.linspace(-2,2, cmap.N+3)))#np.log(np.linspace(np.exp(0), np.exp(1.), cmap.N+3))
|
||||
# alphas = (scipy.special.erf(np.linspace(0,2.4, cmap.N+3)))#np.log(np.linspace(np.exp(0), np.exp(1.), cmap.N+3))
|
||||
# cmap._lut[:, -1] = alphas
|
||||
# print l
|
||||
# x, y = X[labels==l].T
|
||||
#
|
||||
# heatmap, xedges, yedges = np.histogram2d(x, y, bins=300, range=range_)
|
||||
# #heatmap, xedges, yedges = np.histogram2d(x, y, bins=100)
|
||||
#
|
||||
# im = ax.imshow(heatmap, extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]], cmap=cmap, aspect='auto', interpolation='nearest', label=str(l))
|
||||
# legend_handles.append(mpatches.Patch(color=colors[i], label=l))
|
||||
# ax.set_xlim(xmin, xmax)
|
||||
# ax.set_ylim(ymin, ymax)
|
||||
# plt.legend(legend_handles, [l.get_label() for l in legend_handles])
|
||||
# plt.draw()
|
||||
# plt.show()
|
||||
#=======================================================================
|
||||
return X, labels
|
||||
|
||||
|
||||
def update_not_existing_kwargs(to_update, update_from):
|
||||
"""
|
||||
This function updates the keyword aguments from update_from in
|
||||
to_update, only if the keys are not set in to_update.
|
||||
|
||||
This is used for updated kwargs from the default dicts.
|
||||
"""
|
||||
if to_update is None:
|
||||
to_update = {}
|
||||
to_update.update({k:v for k,v in update_from.items() if k not in to_update})
|
||||
return to_update
|
||||
|
||||
def get_x_y_var(model):
|
||||
"""
|
||||
Either the the data from a model as
|
||||
X the inputs,
|
||||
X_variance the variance of the inputs ([default: None])
|
||||
and Y the outputs
|
||||
|
||||
If (X, X_variance, Y) is given, this just returns.
|
||||
|
||||
:returns: (X, X_variance, Y)
|
||||
"""
|
||||
# model given
|
||||
if hasattr(model, 'has_uncertain_inputs') and model.has_uncertain_inputs():
|
||||
X = model.X.mean.values
|
||||
X_variance = model.X.variance.values
|
||||
else:
|
||||
X = model.X.values
|
||||
X_variance = None
|
||||
Y = model.Y.values
|
||||
if sparse.issparse(Y): Y = Y.todense().view(np.ndarray)
|
||||
return X, X_variance, Y
|
||||
|
||||
def get_free_dims(model, visible_dims, fixed_dims):
|
||||
"""
|
||||
work out what the inputs are for plotting (1D or 2D)
|
||||
|
||||
The visible dimensions are the dimensions, which are visible.
|
||||
the fixed_dims are the fixed dimensions for this.
|
||||
|
||||
The free_dims are then the visible dims without the fixed dims.
|
||||
"""
|
||||
if visible_dims is None:
|
||||
visible_dims = np.arange(model.input_dim)
|
||||
dims = np.asanyarray(visible_dims)
|
||||
if fixed_dims is not None:
|
||||
dims = np.setdiff1d(dims, fixed_dims)
|
||||
return np.asanyarray([dim for dim in dims if dim is not None])
|
||||
|
||||
|
||||
def get_fixed_dims(fixed_inputs):
|
||||
"""
|
||||
Work out the fixed dimensions from the fixed_inputs list of tuples.
|
||||
"""
|
||||
return np.array([i for i,_ in fixed_inputs])
|
||||
|
||||
def get_which_data_ycols(model, which_data_ycols):
|
||||
"""
|
||||
Helper to get the data columns to plot.
|
||||
"""
|
||||
if which_data_ycols == 'all' or which_data_ycols is None:
|
||||
return np.arange(model.output_dim)
|
||||
return which_data_ycols
|
||||
|
||||
def get_which_data_rows(model, which_data_rows):
|
||||
"""
|
||||
Helper to get the data rows to plot.
|
||||
"""
|
||||
if which_data_rows == 'all' or which_data_rows is None:
|
||||
return slice(None)
|
||||
return which_data_rows
|
||||
|
||||
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.25*(xmax-xmin), xmax+0.25*(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.075*(xmax-xmin), xmax+0.075*(xmax-xmin)
|
||||
elif len(plot_limits) == 2:
|
||||
xmin, xmax = plot_limits
|
||||
try:
|
||||
xmin = xmin[0], xmin[1]
|
||||
except:
|
||||
# only one limit given, copy over to other lim
|
||||
xmin = [plot_limits[0], plot_limits[0]]
|
||||
xmax = [plot_limits[1], plot_limits[1]]
|
||||
elif len(plot_limits) == 4:
|
||||
xmin, xmax = (plot_limits[0], plot_limits[2]), (plot_limits[1], plot_limits[3])
|
||||
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
|
||||
|
|
@ -1,18 +1,21 @@
|
|||
# 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 . import Tango
|
||||
from . import visualize
|
||||
from . import latent_space_visualizations
|
||||
from . import netpbmfile
|
||||
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
|
||||
from . import controllers
|
||||
|
|
@ -1,181 +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 pb
|
||||
import numpy as np
|
||||
|
||||
def ax_default(fignum, ax):
|
||||
if ax is None:
|
||||
fig = pb.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 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 pb.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 pb.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 pb.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):
|
||||
pb.subplot(N,M,i+1)
|
||||
xlim[0] = min(xlim[0],pb.xlim()[0])
|
||||
xlim[1] = max(xlim[1],pb.xlim()[1])
|
||||
if ylim is None:
|
||||
ylim = [np.inf,-np.inf]
|
||||
for i in range(N*M):
|
||||
pb.subplot(N,M,i+1)
|
||||
ylim[0] = min(ylim[0],pb.ylim()[0])
|
||||
ylim[1] = max(ylim[1],pb.ylim()[1])
|
||||
|
||||
for i in range(N*M):
|
||||
pb.subplot(N,M,i+1)
|
||||
pb.xlim(xlim)
|
||||
pb.ylim(ylim)
|
||||
if (i)%M:
|
||||
pb.yticks([])
|
||||
else:
|
||||
removeRightTicks()
|
||||
if i<(M*(N-1)):
|
||||
pb.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 pb.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
|
||||
1
GPy/plotting/matplot_dep/controllers/__init__.py
Normal file
1
GPy/plotting/matplot_dep/controllers/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
from .imshow_controller import ImshowController, ImAnnotateController
|
||||
|
|
@ -14,7 +14,7 @@ class AxisEventController(object):
|
|||
return self
|
||||
def deactivate(self):
|
||||
for cb_class in self.ax.callbacks.callbacks.values():
|
||||
for cb_num in cb_class.keys():
|
||||
for cb_num in dict(cb_class).keys():
|
||||
self.ax.callbacks.disconnect(cb_num)
|
||||
def activate(self):
|
||||
self.ax.callbacks.connect('xlim_changed', self.xlim_changed)
|
||||
|
|
@ -97,22 +97,19 @@ class BufferedAxisChangedController(AxisChangedController):
|
|||
:param kwargs: additional kwargs are for pyplot.imshow(**kwargs)
|
||||
"""
|
||||
super(BufferedAxisChangedController, self).__init__(ax, update_lim=update_lim)
|
||||
self.resolution = resolution
|
||||
self.plot_function = plot_function
|
||||
xmin, ymin, xmax, ymax = plot_limits#self._x_lim # self._compute_buffered(*self._x_lim)
|
||||
xmin, xmax, ymin, ymax = plot_limits#self._x_lim # self._compute_buffered(*self._x_lim)
|
||||
# imshow acts on the limits of the plot, this is why we need to override the limits here, to make sure the right plot limits are used:
|
||||
self._x_lim = xmin, xmax
|
||||
self._y_lim = ymin, ymax
|
||||
self.resolution = resolution
|
||||
self._not_init = False
|
||||
self.view = self._init_view(self.ax, self.recompute_X(buffered=False), xmin, xmax, ymin, ymax, **kwargs)
|
||||
self._not_init = True
|
||||
|
||||
def update(self, ax):
|
||||
super(BufferedAxisChangedController, self).update(ax)
|
||||
if self._not_init:
|
||||
xmin, xmax = self._compute_buffered(*self._x_lim)
|
||||
ymin, ymax = self._compute_buffered(*self._y_lim)
|
||||
self.update_view(self.view, self.recompute_X(), xmin, xmax, ymin, ymax)
|
||||
xmin, xmax = self._compute_buffered(*self._x_lim)
|
||||
ymin, ymax = self._compute_buffered(*self._y_lim)
|
||||
self.update_view(self.view, self.recompute_X(), xmin, xmax, ymin, ymax)
|
||||
|
||||
def _init_view(self, ax, X, xmin, xmax, ymin, ymax):
|
||||
raise NotImplementedError('return view for this controller')
|
||||
|
|
@ -129,13 +126,7 @@ class BufferedAxisChangedController(AxisChangedController):
|
|||
return numpy.hstack((x.flatten()[:, None], y.flatten()[:, None]))
|
||||
|
||||
def recompute_X(self, buffered=True):
|
||||
X = self.plot_function(self.get_grid(buffered))
|
||||
if isinstance(X, (tuple, list)):
|
||||
for x in X:
|
||||
x.shape = [self.resolution, self.resolution]
|
||||
x[:, :] = x.T[::-1, :]
|
||||
return X
|
||||
return X.reshape(self.resolution, self.resolution).T[::-1, :]
|
||||
return self.plot_function(self.get_grid(buffered))
|
||||
|
||||
def _compute_buffered(self, mi, ma):
|
||||
buffersize = self._buffersize()
|
||||
|
|
@ -9,7 +9,7 @@ import numpy
|
|||
|
||||
|
||||
class ImshowController(BufferedAxisChangedController):
|
||||
def __init__(self, ax, plot_function, plot_limits, resolution=50, update_lim=.8, **kwargs):
|
||||
def __init__(self, ax, plot_function, plot_limits, resolution=50, update_lim=.9, **kwargs):
|
||||
"""
|
||||
:param plot_function:
|
||||
function to use for creating image for plotting (return ndarray-like)
|
||||
|
|
@ -22,19 +22,25 @@ class ImshowController(BufferedAxisChangedController):
|
|||
"""
|
||||
super(ImshowController, self).__init__(ax, plot_function, plot_limits, resolution, update_lim, **kwargs)
|
||||
|
||||
def _init_view(self, ax, X, xmin, xmax, ymin, ymax, **kwargs):
|
||||
return ax.imshow(X, extent=(xmin, xmax,
|
||||
ymin, ymax),
|
||||
vmin=X.min(),
|
||||
vmax=X.max(),
|
||||
**kwargs)
|
||||
def _init_view(self, canvas, X, xmin, xmax, ymin, ymax, vmin=None, vmax=None, **kwargs):
|
||||
#xoffset, yoffset = 0, 0#self._offsets(xmin, xmax, ymin, ymax)
|
||||
return canvas.imshow(X, extent=(xmin, xmax,
|
||||
ymin, ymax),
|
||||
vmin=vmin, vmax=vmax,
|
||||
**kwargs)
|
||||
|
||||
def update_view(self, view, X, xmin, xmax, ymin, ymax):
|
||||
view.set_data(X)
|
||||
view.set_extent((xmin, xmax, ymin, ymax))
|
||||
xoffset, yoffset = 0, 0#self._offsets(xmin, xmax, ymin, ymax)
|
||||
view.set_extent((xmin-xoffset, xmax+xoffset,
|
||||
ymin-yoffset, ymax+yoffset))
|
||||
|
||||
def _offsets(self, xmin, xmax, ymin, ymax):
|
||||
return float(xmax - xmin) / (2 * self.resolution), float(ymax - ymin) / (2 * self.resolution)
|
||||
|
||||
|
||||
class ImAnnotateController(ImshowController):
|
||||
def __init__(self, ax, plot_function, plot_limits, resolution=20, update_lim=.99, **kwargs):
|
||||
def __init__(self, ax, plot_function, plot_limits, resolution=20, update_lim=.99, imshow_kwargs=None, **kwargs):
|
||||
"""
|
||||
:param plot_function:
|
||||
function to use for creating image for plotting (return ndarray-like)
|
||||
|
|
@ -45,15 +51,16 @@ class ImAnnotateController(ImshowController):
|
|||
:param text_props: kwargs for pyplot.text(**text_props)
|
||||
:param kwargs: additional kwargs are for pyplot.imshow(**kwargs)
|
||||
"""
|
||||
self.imshow_kwargs = imshow_kwargs or {}
|
||||
super(ImAnnotateController, self).__init__(ax, plot_function, plot_limits, resolution, update_lim, **kwargs)
|
||||
|
||||
def _init_view(self, ax, X, xmin, xmax, ymin, ymax, text_props={}, **kwargs):
|
||||
view = [super(ImAnnotateController, self)._init_view(ax, X[0], xmin, xmax, ymin, ymax, **kwargs)]
|
||||
def _init_view(self, ax, X, xmin, xmax, ymin, ymax, **kwargs):
|
||||
view = [super(ImAnnotateController, self)._init_view(ax, X[0], xmin, xmax, ymin, ymax, **self.imshow_kwargs)]
|
||||
xoffset, yoffset = self._offsets(xmin, xmax, ymin, ymax)
|
||||
xlin = numpy.linspace(xmin, xmax, self.resolution, endpoint=False)
|
||||
ylin = numpy.linspace(ymin, ymax, self.resolution, endpoint=False)
|
||||
for [i, x], [j, y] in itertools.product(enumerate(xlin), enumerate(ylin[::-1])):
|
||||
view.append(ax.text(x + xoffset, y + yoffset, "{}".format(X[1][j, i]), ha='center', va='center', **text_props))
|
||||
for [i, x], [j, y] in itertools.product(enumerate(xlin), enumerate(ylin)):
|
||||
view.append(ax.text(x+xoffset, y+yoffset, "{}".format(X[1][j, i]), ha='center', va='center', **kwargs))
|
||||
return view
|
||||
|
||||
def update_view(self, view, X, xmin, xmax, ymin, ymax):
|
||||
|
|
@ -61,11 +68,8 @@ class ImAnnotateController(ImshowController):
|
|||
xoffset, yoffset = self._offsets(xmin, xmax, ymin, ymax)
|
||||
xlin = numpy.linspace(xmin, xmax, self.resolution, endpoint=False)
|
||||
ylin = numpy.linspace(ymin, ymax, self.resolution, endpoint=False)
|
||||
for [[i, x], [j, y]], text in itertools.izip(itertools.product(enumerate(xlin), enumerate(ylin[::-1])), view[1:]):
|
||||
text.set_x(x + xoffset)
|
||||
text.set_y(y + yoffset)
|
||||
for [[i, x], [j, y]], text in zip(itertools.product(enumerate(xlin), enumerate(ylin)), view[1:]):
|
||||
text.set_x(x+xoffset)
|
||||
text.set_y(y+yoffset)
|
||||
text.set_text("{}".format(X[1][j, i]))
|
||||
return view
|
||||
|
||||
def _offsets(self, xmin, xmax, ymin, ymax):
|
||||
return (xmax - xmin) / (2 * self.resolution), (ymax - ymin) / (2 * self.resolution)
|
||||
return view
|
||||
75
GPy/plotting/matplot_dep/defaults.py
Normal file
75
GPy/plotting/matplot_dep/defaults.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#===============================================================================
|
||||
# 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 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 cm
|
||||
from .. import Tango
|
||||
|
||||
'''
|
||||
This file is for defaults for the gpy plot, specific to the plotting library.
|
||||
|
||||
Create a kwargs dictionary with the right name for the plotting function
|
||||
you are implementing. If you do not provide defaults, the default behaviour of
|
||||
the plotting library will be used.
|
||||
|
||||
In the code, always ise plotting.gpy_plots.defaults to get the defaults, as
|
||||
it gives back an empty default, when defaults are not defined.
|
||||
'''
|
||||
|
||||
# Data plots:
|
||||
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, marker='^')
|
||||
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['lightBlue'])
|
||||
|
||||
# GPLVM plots:
|
||||
data_y_1d = dict(linewidth=0, cmap='RdBu', s=40)
|
||||
data_y_1d_plot = dict(color='k', linewidth=1.5)
|
||||
|
||||
# Kernel plots:
|
||||
ard = dict(edgecolor='k', linewidth=1.2)
|
||||
|
||||
# Input plots:
|
||||
latent = dict(aspect='auto', cmap='Greys', interpolation='bicubic')
|
||||
gradient = dict(aspect='auto', cmap='RdBu', interpolation='nearest', alpha=.7)
|
||||
magnification = dict(aspect='auto', cmap='Greys', interpolation='bicubic')
|
||||
latent_scatter = dict(s=40, linewidth=.2, edgecolor='k', alpha=.9)
|
||||
annotation = dict(fontdict=dict(family='sans-serif', weight='light', fontsize=9), zorder=.3, alpha=.7)
|
||||
|
|
@ -1,423 +0,0 @@
|
|||
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
import numpy as np
|
||||
from .latent_space_visualizations.controllers.imshow_controller import ImshowController,ImAnnotateController
|
||||
from ...core.parameterization.variational import VariationalPosterior
|
||||
from .base_plots import x_frame2D
|
||||
import itertools
|
||||
try:
|
||||
from . import Tango
|
||||
from matplotlib.cm import get_cmap
|
||||
from matplotlib import pyplot as pb
|
||||
from matplotlib import cm
|
||||
except:
|
||||
pass
|
||||
|
||||
def most_significant_input_dimensions(model, which_indices):
|
||||
"""
|
||||
Determine which dimensions should be plotted
|
||||
"""
|
||||
if which_indices is None:
|
||||
if model.input_dim == 1:
|
||||
input_1 = 0
|
||||
input_2 = None
|
||||
if model.input_dim == 2:
|
||||
input_1, input_2 = 0, 1
|
||||
else:
|
||||
try:
|
||||
input_1, input_2 = np.argsort(model.input_sensitivity())[::-1][:2]
|
||||
except:
|
||||
raise ValueError("cannot automatically determine which dimensions to plot, please pass 'which_indices'")
|
||||
else:
|
||||
input_1, input_2 = which_indices
|
||||
return input_1, input_2
|
||||
|
||||
def plot_latent(model, labels=None, which_indices=None,
|
||||
resolution=50, ax=None, marker='o', s=40,
|
||||
fignum=None, plot_inducing=False, legend=True,
|
||||
plot_limits=None,
|
||||
aspect='auto', updates=False, predict_kwargs={}, imshow_kwargs={}):
|
||||
"""
|
||||
:param labels: a np.array of size model.num_data containing labels for the points (can be number, strings, etc)
|
||||
:param resolution: the resolution of the grid on which to evaluate the predictive variance
|
||||
"""
|
||||
if ax is None:
|
||||
fig = pb.figure(num=fignum)
|
||||
ax = fig.add_subplot(111)
|
||||
else:
|
||||
fig = ax.figure
|
||||
Tango.reset()
|
||||
|
||||
if labels is None:
|
||||
labels = np.ones(model.num_data)
|
||||
|
||||
input_1, input_2 = most_significant_input_dimensions(model, which_indices)
|
||||
|
||||
#fethch the data points X that we'd like to plot
|
||||
X = model.X
|
||||
if isinstance(X, VariationalPosterior):
|
||||
X = X.mean
|
||||
else:
|
||||
X = X
|
||||
|
||||
|
||||
if X.shape[0] > 1000:
|
||||
print("Warning: subsampling X, as it has more samples then 1000. X.shape={!s}".format(X.shape))
|
||||
subsample = np.random.choice(X.shape[0], size=1000, replace=False)
|
||||
X = X[subsample]
|
||||
labels = labels[subsample]
|
||||
#=======================================================================
|
||||
# <<<WORK IN PROGRESS>>>
|
||||
# <<<DO NOT DELETE>>>
|
||||
# plt.close('all')
|
||||
# fig, ax = plt.subplots(1,1)
|
||||
# from GPy.plotting.matplot_dep.dim_reduction_plots import most_significant_input_dimensions
|
||||
# import matplotlib.patches as mpatches
|
||||
# i1, i2 = most_significant_input_dimensions(m, None)
|
||||
# xmin, xmax = 100, -100
|
||||
# ymin, ymax = 100, -100
|
||||
# legend_handles = []
|
||||
#
|
||||
# X = m.X.mean[:, [i1, i2]]
|
||||
# X = m.X.variance[:, [i1, i2]]
|
||||
#
|
||||
# xmin = X[:,0].min(); xmax = X[:,0].max()
|
||||
# ymin = X[:,1].min(); ymax = X[:,1].max()
|
||||
# range_ = [[xmin, xmax], [ymin, ymax]]
|
||||
# ul = np.unique(labels)
|
||||
#
|
||||
# for i, l in enumerate(ul):
|
||||
# #cdict = dict(red =[(0., colors[i][0], colors[i][0]), (1., colors[i][0], colors[i][0])],
|
||||
# # green=[(0., colors[i][0], colors[i][1]), (1., colors[i][1], colors[i][1])],
|
||||
# # blue =[(0., colors[i][0], colors[i][2]), (1., colors[i][2], colors[i][2])],
|
||||
# # alpha=[(0., 0., .0), (.5, .5, .5), (1., .5, .5)])
|
||||
# #cmap = LinearSegmentedColormap('{}'.format(l), cdict)
|
||||
# cmap = LinearSegmentedColormap.from_list('cmap_{}'.format(str(l)), [colors[i], colors[i]], 255)
|
||||
# cmap._init()
|
||||
# #alphas = .5*(1+scipy.special.erf(np.linspace(-2,2, cmap.N+3)))#np.log(np.linspace(np.exp(0), np.exp(1.), cmap.N+3))
|
||||
# alphas = (scipy.special.erf(np.linspace(0,2.4, cmap.N+3)))#np.log(np.linspace(np.exp(0), np.exp(1.), cmap.N+3))
|
||||
# cmap._lut[:, -1] = alphas
|
||||
# print l
|
||||
# x, y = X[labels==l].T
|
||||
#
|
||||
# heatmap, xedges, yedges = np.histogram2d(x, y, bins=300, range=range_)
|
||||
# #heatmap, xedges, yedges = np.histogram2d(x, y, bins=100)
|
||||
#
|
||||
# im = ax.imshow(heatmap, extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]], cmap=cmap, aspect='auto', interpolation='nearest', label=str(l))
|
||||
# legend_handles.append(mpatches.Patch(color=colors[i], label=l))
|
||||
# ax.set_xlim(xmin, xmax)
|
||||
# ax.set_ylim(ymin, ymax)
|
||||
# plt.legend(legend_handles, [l.get_label() for l in legend_handles])
|
||||
# plt.draw()
|
||||
# plt.show()
|
||||
#=======================================================================
|
||||
|
||||
# create a function which computes the shading of latent space according to the output variance
|
||||
def plot_function(x):
|
||||
Xtest_full = np.zeros((x.shape[0], X.shape[1]))
|
||||
Xtest_full[:, [input_1, input_2]] = x
|
||||
_, var = model.predict(Xtest_full, **predict_kwargs)
|
||||
var = var[:, :1]
|
||||
return np.log(var)
|
||||
|
||||
#Create an IMshow controller that can re-plot the latent space shading at a good resolution
|
||||
if plot_limits is None:
|
||||
xmin, ymin = X[:, [input_1, input_2]].min(0)
|
||||
xmax, ymax = X[:, [input_1, input_2]].max(0)
|
||||
x_r, y_r = xmax-xmin, ymax-ymin
|
||||
xmin -= .1*x_r
|
||||
xmax += .1*x_r
|
||||
ymin -= .1*y_r
|
||||
ymax += .1*y_r
|
||||
else:
|
||||
try:
|
||||
xmin, xmax, ymin, ymax = plot_limits
|
||||
except (TypeError, ValueError) as e:
|
||||
raise e.__class__("Wrong plot limits: {} given -> need (xmin, xmax, ymin, ymax)".format(plot_limits))
|
||||
view = ImshowController(ax, plot_function,
|
||||
(xmin, ymin, xmax, ymax),
|
||||
resolution, aspect=aspect, interpolation='bilinear',
|
||||
cmap=cm.binary, **imshow_kwargs)
|
||||
|
||||
# make sure labels are in order of input:
|
||||
labels = np.asarray(labels)
|
||||
ulabels = []
|
||||
for lab in labels:
|
||||
if not lab in ulabels:
|
||||
ulabels.append(lab)
|
||||
|
||||
marker = itertools.cycle(list(marker))
|
||||
|
||||
for i, ul in enumerate(ulabels):
|
||||
if type(ul) is np.string_:
|
||||
this_label = ul
|
||||
elif type(ul) is np.int64:
|
||||
this_label = 'class %i' % ul
|
||||
else:
|
||||
this_label = unicode(ul)
|
||||
m = marker.next()
|
||||
|
||||
index = np.nonzero(labels == ul)[0]
|
||||
if model.input_dim == 1:
|
||||
x = X[index, input_1]
|
||||
y = np.zeros(index.size)
|
||||
else:
|
||||
x = X[index, input_1]
|
||||
y = X[index, input_2]
|
||||
ax.scatter(x, y, marker=m, s=s, c=Tango.nextMedium(), label=this_label, linewidth=.2, edgecolor='k', alpha=.9)
|
||||
|
||||
ax.set_xlabel('latent dimension %i' % input_1)
|
||||
ax.set_ylabel('latent dimension %i' % input_2)
|
||||
|
||||
if not np.all(labels == 1.) and legend:
|
||||
ax.legend(loc=0, numpoints=1)
|
||||
|
||||
ax.grid(b=False) # remove the grid if present, it doesn't look good
|
||||
ax.set_aspect('auto') # set a nice aspect ratio
|
||||
|
||||
if plot_inducing:
|
||||
Z = model.Z
|
||||
ax.scatter(Z[:, input_1], Z[:, input_2], c='w', s=14, marker="^", edgecolor='k', linewidth=.3, alpha=.6)
|
||||
|
||||
ax.set_xlim((xmin, xmax))
|
||||
ax.set_ylim((ymin, ymax))
|
||||
|
||||
try:
|
||||
fig.canvas.draw()
|
||||
fig.tight_layout()
|
||||
fig.canvas.draw()
|
||||
except Exception as e:
|
||||
print("Could not invoke tight layout: {}".format(e))
|
||||
pass
|
||||
|
||||
if updates:
|
||||
try:
|
||||
fig.canvas.show()
|
||||
except Exception as e:
|
||||
print("Could not invoke show: {}".format(e))
|
||||
#raw_input('Enter to continue')
|
||||
return view
|
||||
return ax
|
||||
|
||||
def plot_magnification(model, labels=None, which_indices=None,
|
||||
resolution=60, ax=None, marker='o', s=40,
|
||||
fignum=None, plot_inducing=False, legend=True,
|
||||
plot_limits=None,
|
||||
aspect='auto', updates=False, mean=True, covariance=True, kern=None):
|
||||
"""
|
||||
:param labels: a np.array of size model.num_data containing labels for the points (can be number, strings, etc)
|
||||
:param resolution: the resolution of the grid on which to evaluate the predictive variance
|
||||
"""
|
||||
if ax is None:
|
||||
fig = pb.figure(num=fignum)
|
||||
ax = fig.add_subplot(111)
|
||||
else:
|
||||
fig = ax.figure
|
||||
Tango.reset()
|
||||
|
||||
if labels is None:
|
||||
labels = np.ones(model.num_data)
|
||||
|
||||
input_1, input_2 = most_significant_input_dimensions(model, which_indices)
|
||||
|
||||
#fethch the data points X that we'd like to plot
|
||||
X = model.X
|
||||
if isinstance(X, VariationalPosterior):
|
||||
X = X.mean
|
||||
else:
|
||||
X = X
|
||||
|
||||
if X.shape[0] > 1000:
|
||||
print("Warning: subsampling X, as it has more samples then 1000. X.shape={!s}".format(X.shape))
|
||||
subsample = np.random.choice(X.shape[0], size=1000, replace=False)
|
||||
X = X[subsample]
|
||||
labels = labels[subsample]
|
||||
#=======================================================================
|
||||
# <<<WORK IN PROGRESS>>>
|
||||
# <<<DO NOT DELETE>>>
|
||||
# plt.close('all')
|
||||
# fig, ax = plt.subplots(1,1)
|
||||
# from GPy.plotting.matplot_dep.dim_reduction_plots import most_significant_input_dimensions
|
||||
# import matplotlib.patches as mpatches
|
||||
# i1, i2 = most_significant_input_dimensions(m, None)
|
||||
# xmin, xmax = 100, -100
|
||||
# ymin, ymax = 100, -100
|
||||
# legend_handles = []
|
||||
#
|
||||
# X = m.X.mean[:, [i1, i2]]
|
||||
# X = m.X.variance[:, [i1, i2]]
|
||||
#
|
||||
# xmin = X[:,0].min(); xmax = X[:,0].max()
|
||||
# ymin = X[:,1].min(); ymax = X[:,1].max()
|
||||
# range_ = [[xmin, xmax], [ymin, ymax]]
|
||||
# ul = np.unique(labels)
|
||||
#
|
||||
# for i, l in enumerate(ul):
|
||||
# #cdict = dict(red =[(0., colors[i][0], colors[i][0]), (1., colors[i][0], colors[i][0])],
|
||||
# # green=[(0., colors[i][0], colors[i][1]), (1., colors[i][1], colors[i][1])],
|
||||
# # blue =[(0., colors[i][0], colors[i][2]), (1., colors[i][2], colors[i][2])],
|
||||
# # alpha=[(0., 0., .0), (.5, .5, .5), (1., .5, .5)])
|
||||
# #cmap = LinearSegmentedColormap('{}'.format(l), cdict)
|
||||
# cmap = LinearSegmentedColormap.from_list('cmap_{}'.format(str(l)), [colors[i], colors[i]], 255)
|
||||
# cmap._init()
|
||||
# #alphas = .5*(1+scipy.special.erf(np.linspace(-2,2, cmap.N+3)))#np.log(np.linspace(np.exp(0), np.exp(1.), cmap.N+3))
|
||||
# alphas = (scipy.special.erf(np.linspace(0,2.4, cmap.N+3)))#np.log(np.linspace(np.exp(0), np.exp(1.), cmap.N+3))
|
||||
# cmap._lut[:, -1] = alphas
|
||||
# print l
|
||||
# x, y = X[labels==l].T
|
||||
#
|
||||
# heatmap, xedges, yedges = np.histogram2d(x, y, bins=300, range=range_)
|
||||
# #heatmap, xedges, yedges = np.histogram2d(x, y, bins=100)
|
||||
#
|
||||
# im = ax.imshow(heatmap, extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]], cmap=cmap, aspect='auto', interpolation='nearest', label=str(l))
|
||||
# legend_handles.append(mpatches.Patch(color=colors[i], label=l))
|
||||
# ax.set_xlim(xmin, xmax)
|
||||
# ax.set_ylim(ymin, ymax)
|
||||
# plt.legend(legend_handles, [l.get_label() for l in legend_handles])
|
||||
# plt.draw()
|
||||
# plt.show()
|
||||
#=======================================================================
|
||||
|
||||
#Create an IMshow controller that can re-plot the latent space shading at a good resolution
|
||||
if plot_limits is None:
|
||||
xmin, ymin = X[:, [input_1, input_2]].min(0)
|
||||
xmax, ymax = X[:, [input_1, input_2]].max(0)
|
||||
x_r, y_r = xmax-xmin, ymax-ymin
|
||||
xmin -= .1*x_r
|
||||
xmax += .1*x_r
|
||||
ymin -= .1*y_r
|
||||
ymax += .1*y_r
|
||||
else:
|
||||
try:
|
||||
xmin, xmax, ymin, ymax = plot_limits
|
||||
except (TypeError, ValueError) as e:
|
||||
raise e.__class__("Wrong plot limits: {} given -> need (xmin, xmax, ymin, ymax)".format(plot_limits))
|
||||
|
||||
|
||||
def plot_function(x):
|
||||
Xtest_full = np.zeros((x.shape[0], X.shape[1]))
|
||||
Xtest_full[:, [input_1, input_2]] = x
|
||||
mf = model.predict_magnification(Xtest_full, kern=kern, mean=mean, covariance=covariance)
|
||||
return mf
|
||||
|
||||
view = ImshowController(ax, plot_function,
|
||||
(xmin, ymin, xmax, ymax),
|
||||
resolution, aspect=aspect, interpolation='bilinear',
|
||||
cmap=cm.get_cmap('Greys'))
|
||||
|
||||
# make sure labels are in order of input:
|
||||
ulabels = []
|
||||
for lab in labels:
|
||||
if not lab in ulabels:
|
||||
ulabels.append(lab)
|
||||
|
||||
marker = itertools.cycle(list(marker))
|
||||
|
||||
for i, ul in enumerate(ulabels):
|
||||
if type(ul) is np.string_:
|
||||
this_label = ul
|
||||
elif type(ul) is np.int64:
|
||||
this_label = 'class %i' % ul
|
||||
else:
|
||||
this_label = unicode(ul)
|
||||
m = marker.next()
|
||||
|
||||
index = np.nonzero(labels == ul)[0]
|
||||
if model.input_dim == 1:
|
||||
x = X[index, input_1]
|
||||
y = np.zeros(index.size)
|
||||
else:
|
||||
x = X[index, input_1]
|
||||
y = X[index, input_2]
|
||||
ax.scatter(x, y, marker=m, s=s, c=Tango.nextMedium(), label=this_label, linewidth=.2, edgecolor='k', alpha=.9)
|
||||
|
||||
ax.set_xlabel('latent dimension %i' % input_1)
|
||||
ax.set_ylabel('latent dimension %i' % input_2)
|
||||
|
||||
if not np.all(labels == 1.) and legend:
|
||||
ax.legend(loc=0, numpoints=1)
|
||||
|
||||
ax.set_xlim((xmin, xmax))
|
||||
ax.set_ylim((ymin, ymax))
|
||||
|
||||
if plot_inducing and hasattr(model, 'Z'):
|
||||
Z = model.Z
|
||||
ax.scatter(Z[:, input_1], Z[:, input_2], c='w', s=18, marker="^", edgecolor='k', linewidth=.3, alpha=.7)
|
||||
|
||||
try:
|
||||
fig.canvas.draw()
|
||||
fig.tight_layout()
|
||||
fig.canvas.draw()
|
||||
except Exception as e:
|
||||
print("Could not invoke tight layout: {}".format(e))
|
||||
pass
|
||||
|
||||
if updates:
|
||||
try:
|
||||
fig.canvas.draw()
|
||||
fig.canvas.show()
|
||||
except Exception as e:
|
||||
print("Could not invoke show: {}".format(e))
|
||||
#raw_input('Enter to continue')
|
||||
return view
|
||||
return ax
|
||||
|
||||
|
||||
def plot_steepest_gradient_map(model, fignum=None, ax=None, which_indices=None, labels=None, data_labels=None, data_marker='o', data_s=40, resolution=20, aspect='auto', updates=False, ** kwargs):
|
||||
|
||||
input_1, input_2 = significant_dims = most_significant_input_dimensions(model, which_indices)
|
||||
|
||||
X = np.zeros((resolution ** 2, model.input_dim))
|
||||
indices = np.r_[:X.shape[0]]
|
||||
if labels is None:
|
||||
labels = range(model.output_dim)
|
||||
|
||||
def plot_function(x):
|
||||
X[:, significant_dims] = x
|
||||
dmu_dX = model.dmu_dXnew(X)
|
||||
argmax = np.argmax(dmu_dX, 1)
|
||||
return dmu_dX[indices, argmax], np.array(labels)[argmax]
|
||||
|
||||
if ax is None:
|
||||
fig = pb.figure(num=fignum)
|
||||
ax = fig.add_subplot(111)
|
||||
|
||||
if data_labels is None:
|
||||
data_labels = np.ones(model.num_data)
|
||||
ulabels = []
|
||||
for lab in data_labels:
|
||||
if not lab in ulabels:
|
||||
ulabels.append(lab)
|
||||
marker = itertools.cycle(list(data_marker))
|
||||
for i, ul in enumerate(ulabels):
|
||||
if type(ul) is np.string_:
|
||||
this_label = ul
|
||||
elif type(ul) is np.int64:
|
||||
this_label = 'class %i' % ul
|
||||
else:
|
||||
this_label = 'class %i' % i
|
||||
m = marker.next()
|
||||
index = np.nonzero(data_labels == ul)[0]
|
||||
x = X[index, input_1]
|
||||
y = X[index, input_2]
|
||||
ax.scatter(x, y, marker=m, s=data_s, color=Tango.nextMedium(), label=this_label)
|
||||
|
||||
ax.set_xlabel('latent dimension %i' % input_1)
|
||||
ax.set_ylabel('latent dimension %i' % input_2)
|
||||
|
||||
controller = ImAnnotateController(ax,
|
||||
plot_function,
|
||||
tuple(X.min(0)[:, significant_dims]) + tuple(X.max(0)[:, significant_dims]),
|
||||
resolution=resolution,
|
||||
aspect=aspect,
|
||||
cmap=get_cmap('jet'),
|
||||
**kwargs)
|
||||
ax.legend()
|
||||
ax.figure.tight_layout()
|
||||
if updates:
|
||||
pb.show()
|
||||
clear = raw_input('Enter to continue')
|
||||
if clear.lower() in 'yes' or clear == '':
|
||||
controller.deactivate()
|
||||
return controller.view
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
try:
|
||||
from matplotlib import pyplot as pb
|
||||
except:
|
||||
pass
|
||||
#import numpy as np
|
||||
#import Tango
|
||||
#from base_plots import gpplot, x_frame1D, x_frame2D
|
||||
|
||||
|
||||
def plot_optimizer(optimizer):
|
||||
if optimizer.trace == None:
|
||||
print("No trace present so I can't plot it. Please check that the optimizer actually supplies a trace.")
|
||||
else:
|
||||
pb.figure()
|
||||
pb.plot(optimizer.trace)
|
||||
pb.xlabel('Iteration')
|
||||
pb.ylabel('f(x)')
|
||||
|
||||
def plot_sgd_traces(optimizer):
|
||||
pb.figure()
|
||||
pb.subplot(211)
|
||||
pb.title('Parameters')
|
||||
for k in optimizer.param_traces.keys():
|
||||
pb.plot(optimizer.param_traces[k], label=k)
|
||||
pb.legend(loc=0)
|
||||
pb.subplot(212)
|
||||
pb.title('Objective function')
|
||||
pb.plot(optimizer.fopt_trace)
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
# Copyright (c) 2012, GPy authors (see AUTHORS.txt).
|
||||
# Licensed under the BSD 3-clause license (see LICENSE.txt)
|
||||
|
||||
import numpy as np
|
||||
from matplotlib import pyplot as pb
|
||||
from . import Tango
|
||||
from matplotlib.textpath import TextPath
|
||||
from matplotlib.transforms import offset_copy
|
||||
from .base_plots import ax_default
|
||||
|
||||
|
||||
|
||||
def add_bar_labels(fig, ax, bars, bottom=0):
|
||||
transOffset = offset_copy(ax.transData, fig=fig,
|
||||
x=0., y= -2., units='points')
|
||||
transOffsetUp = offset_copy(ax.transData, fig=fig,
|
||||
x=0., y=1., units='points')
|
||||
for bar in bars:
|
||||
for i, [patch, num] in enumerate(zip(bar.patches, np.arange(len(bar.patches)))):
|
||||
if len(bottom) == len(bar): b = bottom[i]
|
||||
else: b = bottom
|
||||
height = patch.get_height() + b
|
||||
xi = patch.get_x() + patch.get_width() / 2.
|
||||
va = 'top'
|
||||
c = 'w'
|
||||
t = TextPath((0, 0), "${xi}$".format(xi=xi), rotation=0, ha='center')
|
||||
transform = transOffset
|
||||
if patch.get_extents().height <= t.get_extents().height + 5:
|
||||
va = 'bottom'
|
||||
c = 'k'
|
||||
transform = transOffsetUp
|
||||
ax.text(xi, height, "${xi}$".format(xi=int(num)), color=c, rotation=0, ha='center', va=va, transform=transform)
|
||||
|
||||
ax.set_xticks([])
|
||||
|
||||
|
||||
def plot_bars(fig, ax, x, ard_params, color, name, bottom=0):
|
||||
return ax.bar(left=x, height=ard_params.view(np.ndarray), width=.8,
|
||||
bottom=bottom, align='center',
|
||||
color=color, edgecolor='k', linewidth=1.2,
|
||||
label=name.replace("_"," "))
|
||||
|
||||
def plot_ARD(kernel, fignum=None, ax=None, title='', legend=False, filtering=None):
|
||||
"""
|
||||
If an ARD kernel is present, plot a bar representation using matplotlib
|
||||
|
||||
:param fignum: figure number of the plot
|
||||
:param ax: matplotlib axis to plot on
|
||||
:param title:
|
||||
title of the plot,
|
||||
pass '' to not print a title
|
||||
pass None for a generic title
|
||||
: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
|
||||
"""
|
||||
fig, ax = ax_default(fignum,ax)
|
||||
|
||||
if title is None:
|
||||
ax.set_title('ARD parameters, %s kernel' % kernel.name)
|
||||
else:
|
||||
ax.set_title(title)
|
||||
|
||||
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(plot_bars(fig, ax, x, ard_params[i,:], c, kernel.parameters[i].name, bottom=bottom))
|
||||
last_bottom = ard_params[i,:]
|
||||
bottom += last_bottom
|
||||
else:
|
||||
print("filtering out {}".format(kernel.parameters[i].name))
|
||||
|
||||
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 ax
|
||||
|
||||
|
||||
|
||||
def plot(kernel,x=None, fignum=None, ax=None, title=None, plot_limits=None, resolution=None, **mpl_kwargs):
|
||||
"""
|
||||
plot a kernel.
|
||||
:param x: the value to use for the other kernel argument (kernels are a function of two variables!)
|
||||
:param fignum: figure number of the plot
|
||||
:param ax: matplotlib axis to plot on
|
||||
:param title: the matplotlib title
|
||||
:param plot_limits: the range over which to plot the kernel
|
||||
:resolution: the resolution of the lines used in plotting
|
||||
:mpl_kwargs avalid keyword arguments to pass through to matplotlib (e.g. lw=7)
|
||||
"""
|
||||
fig, ax = ax_default(fignum,ax)
|
||||
|
||||
if title is None:
|
||||
ax.set_title('%s kernel' % kernel.name)
|
||||
else:
|
||||
ax.set_title(title)
|
||||
|
||||
|
||||
if kernel.input_dim == 1:
|
||||
if x is None:
|
||||
x = np.zeros((1, 1))
|
||||
else:
|
||||
x = np.asarray(x)
|
||||
assert x.size == 1, "The size of the fixed variable x is not 1"
|
||||
x = x.reshape((1, 1))
|
||||
|
||||
if plot_limits == None:
|
||||
xmin, xmax = (x - 5).flatten(), (x + 5).flatten()
|
||||
elif len(plot_limits) == 2:
|
||||
xmin, xmax = plot_limits
|
||||
else:
|
||||
raise ValueError("Bad limits for plotting")
|
||||
|
||||
Xnew = np.linspace(xmin, xmax, resolution or 201)[:, None]
|
||||
Kx = kernel.K(Xnew, x)
|
||||
ax.plot(Xnew, Kx, **mpl_kwargs)
|
||||
ax.set_xlim(xmin, xmax)
|
||||
ax.set_xlabel("x")
|
||||
ax.set_ylabel("k(x,%0.1f)" % x)
|
||||
|
||||
elif kernel.input_dim == 2:
|
||||
if x is None:
|
||||
x = np.zeros((1, 2))
|
||||
else:
|
||||
x = np.asarray(x)
|
||||
assert x.size == 2, "The size of the fixed variable x is not 2"
|
||||
x = x.reshape((1, 2))
|
||||
|
||||
if plot_limits is None:
|
||||
xmin, xmax = (x - 5).flatten(), (x + 5).flatten()
|
||||
elif len(plot_limits) == 2:
|
||||
xmin, xmax = plot_limits
|
||||
else:
|
||||
raise ValueError("Bad limits for plotting")
|
||||
|
||||
resolution = resolution or 51
|
||||
xx, yy = np.mgrid[xmin[0]:xmax[0]:1j * resolution, xmin[1]:xmax[1]:1j * resolution]
|
||||
Xnew = np.vstack((xx.flatten(), yy.flatten())).T
|
||||
Kx = kernel.K(Xnew, x)
|
||||
Kx = Kx.reshape(resolution, resolution).T
|
||||
ax.contour(xx, yy, Kx, vmin=Kx.min(), vmax=Kx.max(), cmap=pb.cm.jet, **mpl_kwargs) # @UndefinedVariable
|
||||
ax.set_xlim(xmin[0], xmax[0])
|
||||
ax.set_ylim(xmin[1], xmax[1])
|
||||
ax.set_xlabel("x1")
|
||||
ax.set_ylabel("x2")
|
||||
ax.set_title("k(x1,x2 ; %0.1f,%0.1f)" % (x[0, 0], x[0, 1]))
|
||||
else:
|
||||
raise NotImplementedError("Cannot plot a kernel with more than two input dimensions")
|
||||
|
|
@ -1 +0,0 @@
|
|||
from .import controllers
|
||||
|
|
@ -1 +0,0 @@
|
|||
from . import axis_event_controller, imshow_controller
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import numpy as np
|
||||
try:
|
||||
from . import Tango
|
||||
from GPy.plotting import Tango
|
||||
from matplotlib import pyplot as pb
|
||||
except:
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -1,426 +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 . import Tango
|
||||
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
|
||||
|
||||
|
||||
def plot_data(model, which_data_rows='all',
|
||||
which_data_ycols='all', visible_dims=None,
|
||||
fignum=None, ax=None, data_symbol='kx',mew=1.5):
|
||||
"""
|
||||
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 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 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(model.output_dim)
|
||||
|
||||
if ax is None:
|
||||
fig = plt.figure(num=fignum)
|
||||
ax = fig.add_subplot(111)
|
||||
|
||||
if hasattr(model, 'has_uncertain_inputs') and model.has_uncertain_inputs():
|
||||
X = model.X.mean
|
||||
X_variance = model.X.variance
|
||||
else:
|
||||
X = model.X
|
||||
X_variance = None
|
||||
Y = model.Y
|
||||
|
||||
#work out what the inputs are for plotting (1D or 2D)
|
||||
if visible_dims is None:
|
||||
visible_dims = np.arange(model.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(model, 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 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 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(model.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(model, 'has_uncertain_inputs') and model.has_uncertain_inputs():
|
||||
X = model.X.mean
|
||||
X_variance = model.X.variance
|
||||
else:
|
||||
X = model.X
|
||||
Y = model.Y
|
||||
if sparse.issparse(Y): Y = Y.todense().view(np.ndarray)
|
||||
|
||||
if hasattr(model, 'Z'): Z = model.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(model.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],model.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 = model._raw_predict(Xgrid, **predict_kw)
|
||||
if apply_link:
|
||||
lower = model.likelihood.gp_link.transf(m - 2*np.sqrt(v))
|
||||
upper = model.likelihood.gp_link.transf(m + 2*np.sqrt(v))
|
||||
#Once transformed this is now the median of the function
|
||||
m = model.likelihood.gp_link.transf(m)
|
||||
else:
|
||||
lower = m - 2*np.sqrt(v)
|
||||
upper = m + 2*np.sqrt(v)
|
||||
else:
|
||||
if isinstance(model,GPCoregionalizedRegression) or isinstance(model,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 = model.predict(Xgrid, full_cov=False, Y_metadata=Y_metadata, **predict_kw)
|
||||
fmu, fv = model._raw_predict(Xgrid, full_cov=False, **predict_kw)
|
||||
lower, upper = model.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(model=model, 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 = model.posterior_samples_f(Xgrid, samples)
|
||||
if apply_link:
|
||||
Fsim = model.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 = model.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(model,"has_uncertain_inputs") and model.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 = model.X.mean.values.copy()
|
||||
for i,v in fixed_inputs:
|
||||
vs[:,i] = v
|
||||
m_X, _ = model._raw_predict(vs)
|
||||
if apply_link:
|
||||
m_X = model.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(model,"Z"):
|
||||
#Zu = model.Z[:,free_dims] * model._Xscale[:,free_dims] + model._Xoffset[:,free_dims]
|
||||
if isinstance(model,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, _, _, xmin, xmax = x_frame2D(X[:,free_dims], plot_limits, resolution)
|
||||
Xgrid = np.empty((Xnew.shape[0],model.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, _ = model._raw_predict(Xgrid, **predict_kw)
|
||||
else:
|
||||
if isinstance(model,GPCoregionalizedRegression) or isinstance(model,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 = model.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 model is used)
|
||||
if hasattr(model,"Z"):
|
||||
#Zu = model.Z[:,free_dims] * model._Xscale[:,free_dims] + model._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_fit_f(model, *args, **kwargs):
|
||||
"""
|
||||
Plot the GP's view of the world, where the data is normalized and before applying a likelihood.
|
||||
|
||||
All args and kwargs are passed on to models_plots.plot.
|
||||
"""
|
||||
kwargs['plot_raw'] = True
|
||||
plot_fit(model,*args, **kwargs)
|
||||
|
||||
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(model=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
|
||||
|
|
@ -1,331 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# netpbmfile.py
|
||||
|
||||
# Copyright (c) 2011-2013, Christoph Gohlke
|
||||
# Copyright (c) 2011-2013, The Regents of the University of California
|
||||
# Produced at the Laboratory for Fluorescence Dynamics.
|
||||
# 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 the copyright holders nor the names of any
|
||||
# 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 OWNER 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.
|
||||
|
||||
"""Read and write image data from respectively to Netpbm files.
|
||||
|
||||
This implementation follows the Netpbm format specifications at
|
||||
http://netpbm.sourceforge.net/doc/. No gamma correction is performed.
|
||||
|
||||
The following image formats are supported: PBM (bi-level), PGM (grayscale),
|
||||
PPM (color), PAM (arbitrary), XV thumbnail (RGB332, read-only).
|
||||
|
||||
:Author:
|
||||
`Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/>`_
|
||||
|
||||
:Organization:
|
||||
Laboratory for Fluorescence Dynamics, University of California, Irvine
|
||||
|
||||
:Version: 2013.01.18
|
||||
|
||||
Requirements
|
||||
------------
|
||||
* `CPython 2.7, 3.2 or 3.3 <http://www.python.org>`_
|
||||
* `Numpy 1.7 <http://www.numpy.org>`_
|
||||
* `Matplotlib 1.2 <http://www.matplotlib.org>`_ (optional for plotting)
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> im1 = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16)
|
||||
>>> imsave('_tmp.pgm', im1)
|
||||
>>> im2 = imread('_tmp.pgm')
|
||||
>>> assert numpy.all(im1 == im2)
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import division, print_function
|
||||
|
||||
import sys
|
||||
import re
|
||||
import math
|
||||
from copy import deepcopy
|
||||
|
||||
import numpy
|
||||
|
||||
__version__ = '2013.01.18'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
__all__ = ['imread', 'imsave', 'NetpbmFile']
|
||||
|
||||
|
||||
def imread(filename, *args, **kwargs):
|
||||
"""Return image data from Netpbm file as numpy array.
|
||||
|
||||
`args` and `kwargs` are arguments to NetpbmFile.asarray().
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> image = imread('_tmp.pgm')
|
||||
|
||||
"""
|
||||
try:
|
||||
netpbm = NetpbmFile(filename)
|
||||
image = netpbm.asarray()
|
||||
finally:
|
||||
netpbm.close()
|
||||
return image
|
||||
|
||||
|
||||
def imsave(filename, data, maxval=None, pam=False):
|
||||
"""Write image data to Netpbm file.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> image = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16)
|
||||
>>> imsave('_tmp.pgm', image)
|
||||
|
||||
"""
|
||||
try:
|
||||
netpbm = NetpbmFile(data, maxval=maxval)
|
||||
netpbm.write(filename, pam=pam)
|
||||
finally:
|
||||
netpbm.close()
|
||||
|
||||
|
||||
class NetpbmFile(object):
|
||||
"""Read and write Netpbm PAM, PBM, PGM, PPM, files."""
|
||||
|
||||
_types = {b'P1': b'BLACKANDWHITE', b'P2': b'GRAYSCALE', b'P3': b'RGB',
|
||||
b'P4': b'BLACKANDWHITE', b'P5': b'GRAYSCALE', b'P6': b'RGB',
|
||||
b'P7 332': b'RGB', b'P7': b'RGB_ALPHA'}
|
||||
|
||||
def __init__(self, arg=None, **kwargs):
|
||||
"""Initialize instance from filename, open file, or numpy array."""
|
||||
for attr in ('header', 'magicnum', 'width', 'height', 'maxval',
|
||||
'depth', 'tupltypes', '_filename', '_fh', '_data'):
|
||||
setattr(self, attr, None)
|
||||
if arg is None:
|
||||
self._fromdata([], **kwargs)
|
||||
elif isinstance(arg, basestring):
|
||||
self._fh = open(arg, 'rb')
|
||||
self._filename = arg
|
||||
self._fromfile(self._fh, **kwargs)
|
||||
elif hasattr(arg, 'seek'):
|
||||
self._fromfile(arg, **kwargs)
|
||||
self._fh = arg
|
||||
else:
|
||||
self._fromdata(arg, **kwargs)
|
||||
|
||||
def asarray(self, copy=True, cache=False, **kwargs):
|
||||
"""Return image data from file as numpy array."""
|
||||
data = self._data
|
||||
if data is None:
|
||||
data = self._read_data(self._fh, **kwargs)
|
||||
if cache:
|
||||
self._data = data
|
||||
else:
|
||||
return data
|
||||
return deepcopy(data) if copy else data
|
||||
|
||||
def write(self, arg, **kwargs):
|
||||
"""Write instance to file."""
|
||||
if hasattr(arg, 'seek'):
|
||||
self._tofile(arg, **kwargs)
|
||||
else:
|
||||
with open(arg, 'wb') as fid:
|
||||
self._tofile(fid, **kwargs)
|
||||
|
||||
def close(self):
|
||||
"""Close open file. Future asarray calls might fail."""
|
||||
if self._filename and self._fh:
|
||||
self._fh.close()
|
||||
self._fh = None
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
def _fromfile(self, fh):
|
||||
"""Initialize instance from open file."""
|
||||
fh.seek(0)
|
||||
data = fh.read(4096)
|
||||
if (len(data) < 7) or not (b'0' < data[1:2] < b'8'):
|
||||
raise ValueError("Not a Netpbm file:\n%s" % data[:32])
|
||||
try:
|
||||
self._read_pam_header(data)
|
||||
except Exception:
|
||||
try:
|
||||
self._read_pnm_header(data)
|
||||
except Exception:
|
||||
raise ValueError("Not a Netpbm file:\n%s" % data[:32])
|
||||
|
||||
def _read_pam_header(self, data):
|
||||
"""Read PAM header and initialize instance."""
|
||||
regroups = re.search(
|
||||
b"(^P7[\n\r]+(?:(?:[\n\r]+)|(?:#.*)|"
|
||||
b"(HEIGHT\s+\d+)|(WIDTH\s+\d+)|(DEPTH\s+\d+)|(MAXVAL\s+\d+)|"
|
||||
b"(?:TUPLTYPE\s+\w+))*ENDHDR\n)", data).groups()
|
||||
self.header = regroups[0]
|
||||
self.magicnum = b'P7'
|
||||
for group in regroups[1:]:
|
||||
key, value = group.split()
|
||||
setattr(self, unicode(key).lower(), int(value))
|
||||
matches = re.findall(b"(TUPLTYPE\s+\w+)", self.header)
|
||||
self.tupltypes = [s.split(None, 1)[1] for s in matches]
|
||||
|
||||
def _read_pnm_header(self, data):
|
||||
"""Read PNM header and initialize instance."""
|
||||
bpm = data[1:2] in b"14"
|
||||
regroups = re.search(b"".join((
|
||||
b"(^(P[123456]|P7 332)\s+(?:#.*[\r\n])*",
|
||||
b"\s*(\d+)\s+(?:#.*[\r\n])*",
|
||||
b"\s*(\d+)\s+(?:#.*[\r\n])*" * (not bpm),
|
||||
b"\s*(\d+)\s(?:\s*#.*[\r\n]\s)*)")), data).groups() + (1, ) * bpm
|
||||
self.header = regroups[0]
|
||||
self.magicnum = regroups[1]
|
||||
self.width = int(regroups[2])
|
||||
self.height = int(regroups[3])
|
||||
self.maxval = int(regroups[4])
|
||||
self.depth = 3 if self.magicnum in b"P3P6P7 332" else 1
|
||||
self.tupltypes = [self._types[self.magicnum]]
|
||||
|
||||
def _read_data(self, fh, byteorder='>'):
|
||||
"""Return image data from open file as numpy array."""
|
||||
fh.seek(len(self.header))
|
||||
data = fh.read()
|
||||
dtype = 'u1' if self.maxval < 256 else byteorder + 'u2'
|
||||
depth = 1 if self.magicnum == b"P7 332" else self.depth
|
||||
shape = [-1, self.height, self.width, depth]
|
||||
size = numpy.prod(shape[1:])
|
||||
if self.magicnum in b"P1P2P3":
|
||||
data = numpy.array(data.split(None, size)[:size], dtype)
|
||||
data = data.reshape(shape)
|
||||
elif self.maxval == 1:
|
||||
shape[2] = int(math.ceil(self.width / 8))
|
||||
data = numpy.frombuffer(data, dtype).reshape(shape)
|
||||
data = numpy.unpackbits(data, axis=-2)[:, :, :self.width, :]
|
||||
else:
|
||||
data = numpy.frombuffer(data, dtype)
|
||||
data = data[:size * (data.size // size)].reshape(shape)
|
||||
if data.shape[0] < 2:
|
||||
data = data.reshape(data.shape[1:])
|
||||
if data.shape[-1] < 2:
|
||||
data = data.reshape(data.shape[:-1])
|
||||
if self.magicnum == b"P7 332":
|
||||
rgb332 = numpy.array(list(numpy.ndindex(8, 8, 4)), numpy.uint8)
|
||||
rgb332 *= [36, 36, 85]
|
||||
data = numpy.take(rgb332, data, axis=0)
|
||||
return data
|
||||
|
||||
def _fromdata(self, data, maxval=None):
|
||||
"""Initialize instance from numpy array."""
|
||||
data = numpy.array(data, ndmin=2, copy=True)
|
||||
if data.dtype.kind not in "uib":
|
||||
raise ValueError("not an integer type: %s" % data.dtype)
|
||||
if data.dtype.kind == 'i' and numpy.min(data) < 0:
|
||||
raise ValueError("data out of range: %i" % numpy.min(data))
|
||||
if maxval is None:
|
||||
maxval = numpy.max(data)
|
||||
maxval = 255 if maxval < 256 else 65535
|
||||
if maxval < 0 or maxval > 65535:
|
||||
raise ValueError("data out of range: %i" % maxval)
|
||||
data = data.astype('u1' if maxval < 256 else '>u2')
|
||||
self._data = data
|
||||
if data.ndim > 2 and data.shape[-1] in (3, 4):
|
||||
self.depth = data.shape[-1]
|
||||
self.width = data.shape[-2]
|
||||
self.height = data.shape[-3]
|
||||
self.magicnum = b'P7' if self.depth == 4 else b'P6'
|
||||
else:
|
||||
self.depth = 1
|
||||
self.width = data.shape[-1]
|
||||
self.height = data.shape[-2]
|
||||
self.magicnum = b'P5' if maxval > 1 else b'P4'
|
||||
self.maxval = maxval
|
||||
self.tupltypes = [self._types[self.magicnum]]
|
||||
self.header = self._header()
|
||||
|
||||
def _tofile(self, fh, pam=False):
|
||||
"""Write Netbm file."""
|
||||
fh.seek(0)
|
||||
fh.write(self._header(pam))
|
||||
data = self.asarray(copy=False)
|
||||
if self.maxval == 1:
|
||||
data = numpy.packbits(data, axis=-1)
|
||||
data.tofile(fh)
|
||||
|
||||
def _header(self, pam=False):
|
||||
"""Return file header as byte string."""
|
||||
if pam or self.magicnum == b'P7':
|
||||
header = "\n".join((
|
||||
"P7",
|
||||
"HEIGHT %i" % self.height,
|
||||
"WIDTH %i" % self.width,
|
||||
"DEPTH %i" % self.depth,
|
||||
"MAXVAL %i" % self.maxval,
|
||||
"\n".join("TUPLTYPE %s" % unicode(i) for i in self.tupltypes),
|
||||
"ENDHDR\n"))
|
||||
elif self.maxval == 1:
|
||||
header = "P4 %i %i\n" % (self.width, self.height)
|
||||
elif self.depth == 1:
|
||||
header = "P5 %i %i %i\n" % (self.width, self.height, self.maxval)
|
||||
else:
|
||||
header = "P6 %i %i %i\n" % (self.width, self.height, self.maxval)
|
||||
if sys.version_info[0] > 2:
|
||||
header = bytes(header, 'ascii')
|
||||
return header
|
||||
|
||||
def __str__(self):
|
||||
"""Return information about instance."""
|
||||
return unicode(self.header)
|
||||
|
||||
|
||||
if sys.version_info[0] > 2:
|
||||
basestring = str
|
||||
unicode = lambda x: str(x, 'ascii')
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Show images specified on command line or all images in current directory
|
||||
from glob import glob
|
||||
from matplotlib import pyplot
|
||||
files = sys.argv[1:] if len(sys.argv) > 1 else glob('*.p*m')
|
||||
for fname in files:
|
||||
try:
|
||||
pam = NetpbmFile(fname)
|
||||
img = pam.asarray(copy=False)
|
||||
if False:
|
||||
pam.write('_tmp.pgm.out', pam=True)
|
||||
img2 = imread('_tmp.pgm.out')
|
||||
assert numpy.all(img == img2)
|
||||
imsave('_tmp.pgm.out', img)
|
||||
img2 = imread('_tmp.pgm.out')
|
||||
assert numpy.all(img == img2)
|
||||
pam.close()
|
||||
except ValueError as e:
|
||||
print(fname, e)
|
||||
continue
|
||||
_shape = img.shape
|
||||
if img.ndim > 3 or (img.ndim > 2 and img.shape[-1] not in (3, 4)):
|
||||
img = img[0]
|
||||
cmap = 'gray' if pam.maxval > 1 else 'binary'
|
||||
pyplot.imshow(img, cmap, interpolation='nearest')
|
||||
pyplot.title("%s %s %s %s" % (fname, unicode(pam.magicnum),
|
||||
_shape, img.dtype))
|
||||
pyplot.show()
|
||||
300
GPy/plotting/matplot_dep/plot_definitions.py
Normal file
300
GPy/plotting/matplot_dep/plot_definitions.py
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
#===============================================================================
|
||||
# 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.plot_definitions 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 matplotlib import pyplot as plt
|
||||
from ..abstract_plotting_library import AbstractPlottingLibrary
|
||||
from .. import Tango
|
||||
from . import defaults
|
||||
from matplotlib.colors import LinearSegmentedColormap
|
||||
from .controllers import ImshowController, ImAnnotateController
|
||||
import itertools
|
||||
from .util import legend_ontop
|
||||
|
||||
class MatplotlibPlots(AbstractPlottingLibrary):
|
||||
def __init__(self):
|
||||
super(MatplotlibPlots, self).__init__()
|
||||
self._defaults = defaults.__dict__
|
||||
|
||||
def figure(self, rows=1, cols=1, **kwargs):
|
||||
fig = plt.figure(**kwargs)
|
||||
fig.rows = rows
|
||||
fig.cols = cols
|
||||
return fig
|
||||
|
||||
def new_canvas(self, figure=None, col=1, row=1, projection='2d', xlabel=None, ylabel=None, zlabel=None, title=None, xlim=None, ylim=None, zlim=None, **kwargs):
|
||||
if projection == '3d':
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
elif projection == '2d':
|
||||
projection = None
|
||||
if 'ax' in kwargs:
|
||||
ax = kwargs.pop('ax')
|
||||
else:
|
||||
if 'num' in kwargs and 'figsize' in kwargs:
|
||||
fig = self.figure(num=kwargs.pop('num'), figsize=kwargs.pop('figsize'))
|
||||
elif 'num' in kwargs:
|
||||
fig = self.figure(num=kwargs.pop('num'))
|
||||
elif 'figsize' in kwargs:
|
||||
fig = self.figure(figsize=kwargs.pop('figsize'))
|
||||
else:
|
||||
fig = self.figure()
|
||||
|
||||
#if hasattr(fig, 'rows') and hasattr(fig, 'cols'):
|
||||
ax = fig.add_subplot(fig.rows, fig.cols, (col,row), projection=projection)
|
||||
|
||||
if xlim is not None: ax.set_xlim(xlim)
|
||||
if ylim is not None: ax.set_ylim(ylim)
|
||||
if xlabel is not None: ax.set_xlabel(xlabel)
|
||||
if ylabel is not None: ax.set_ylabel(ylabel)
|
||||
if title is not None: ax.set_title(title)
|
||||
if projection == '3d':
|
||||
if zlim is not None: ax.set_zlim(zlim)
|
||||
if zlabel is not None: ax.set_zlabel(zlabel)
|
||||
return ax, kwargs
|
||||
|
||||
def add_to_canvas(self, ax, plots, legend=False, title=None, **kwargs):
|
||||
ax.autoscale_view()
|
||||
fontdict=dict(family='sans-serif', weight='light', size=9)
|
||||
if legend is True:
|
||||
ax.legend(*ax.get_legend_handles_labels())
|
||||
elif legend >= 1:
|
||||
#ax.legend(prop=fontdict)
|
||||
legend_ontop(ax, ncol=legend, fontdict=fontdict)
|
||||
if title is not None: ax.figure.suptitle(title)
|
||||
return ax
|
||||
|
||||
def show_canvas(self, ax, tight_layout=False, **kwargs):
|
||||
if tight_layout:
|
||||
ax.figure.tight_layout()
|
||||
ax.figure.canvas.draw()
|
||||
return ax.figure
|
||||
|
||||
def scatter(self, ax, X, Y, Z=None, color=Tango.colorsHex['mediumBlue'], label=None, marker='o', **kwargs):
|
||||
if Z is not None:
|
||||
return ax.scatter(X, Y, c=color, zs=Z, label=label, marker=marker, **kwargs)
|
||||
return ax.scatter(X, Y, c=color, label=label, marker=marker, **kwargs)
|
||||
|
||||
def plot(self, ax, X, Y, Z=None, color=None, label=None, **kwargs):
|
||||
if Z is not None:
|
||||
return ax.plot(X, Y, color=color, zs=Z, label=label, **kwargs)
|
||||
return ax.plot(X, Y, color=color, label=label, **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 '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=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=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, 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, extent=None, label=None, vmin=None, vmax=None, **imshow_kwargs):
|
||||
if 'origin' not in imshow_kwargs:
|
||||
imshow_kwargs['origin'] = 'lower'
|
||||
#xmin, xmax, ymin, ymax = extent
|
||||
#xoffset, yoffset = (xmax - xmin) / (2. * X.shape[0]), (ymax - ymin) / (2. * X.shape[1])
|
||||
#xmin, xmax, ymin, ymax = extent = xmin-xoffset, xmax+xoffset, ymin-yoffset, ymax+yoffset
|
||||
return ax.imshow(X, label=label, extent=extent, vmin=vmin, vmax=vmax, **imshow_kwargs)
|
||||
|
||||
def imshow_interact(self, ax, plot_function, extent, label=None, resolution=None, vmin=None, vmax=None, **imshow_kwargs):
|
||||
if imshow_kwargs is None: imshow_kwargs = {}
|
||||
if 'origin' not in imshow_kwargs:
|
||||
imshow_kwargs['origin'] = 'lower'
|
||||
return ImshowController(ax, plot_function, extent, resolution=resolution, vmin=vmin, vmax=vmax, **imshow_kwargs)
|
||||
|
||||
def annotation_heatmap(self, ax, X, annotation, extent=None, label=None, imshow_kwargs=None, **annotation_kwargs):
|
||||
if imshow_kwargs is None: imshow_kwargs = {}
|
||||
if 'origin' not in imshow_kwargs:
|
||||
imshow_kwargs['origin'] = 'lower'
|
||||
if ('ha' not in annotation_kwargs) and ('horizontalalignment' not in annotation_kwargs):
|
||||
annotation_kwargs['ha'] = 'center'
|
||||
if ('va' not in annotation_kwargs) and ('verticalalignment' not in annotation_kwargs):
|
||||
annotation_kwargs['va'] = 'center'
|
||||
imshow = self.imshow(ax, X, extent, label, **imshow_kwargs)
|
||||
if extent is None:
|
||||
extent = (0, X.shape[0], 0, X.shape[1])
|
||||
xmin, xmax, ymin, ymax = extent
|
||||
xoffset, yoffset = (xmax - xmin) / (2. * X.shape[0]), (ymax - ymin) / (2. * X.shape[1])
|
||||
xlin = np.linspace(xmin, xmax, X.shape[0], endpoint=False)
|
||||
ylin = np.linspace(ymin, ymax, X.shape[1], endpoint=False)
|
||||
annotations = []
|
||||
for [i, x], [j, y] in itertools.product(enumerate(xlin), enumerate(ylin)):
|
||||
annotations.append(ax.text(x+xoffset, y+yoffset, "{}".format(annotation[j, i]), **annotation_kwargs))
|
||||
return imshow, annotations
|
||||
|
||||
def annotation_heatmap_interact(self, ax, plot_function, extent, label=None, resolution=15, imshow_kwargs=None, **annotation_kwargs):
|
||||
if imshow_kwargs is None: imshow_kwargs = {}
|
||||
if 'origin' not in imshow_kwargs:
|
||||
imshow_kwargs['origin'] = 'lower'
|
||||
return ImAnnotateController(ax, plot_function, extent, resolution=resolution, imshow_kwargs=imshow_kwargs or {}, **annotation_kwargs)
|
||||
|
||||
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 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=Tango.colorsHex['mediumBlue'], label=None, **kwargs):
|
||||
ax = canvas
|
||||
plots = []
|
||||
|
||||
if 'edgecolors' not in kwargs:
|
||||
kwargs['edgecolors'] = 'none'
|
||||
|
||||
if 'facecolors' in kwargs:
|
||||
color = kwargs.pop('facecolors')
|
||||
|
||||
if 'array' in kwargs:
|
||||
array = kwargs.pop('array')
|
||||
else:
|
||||
array = 1.-np.abs(np.linspace(-.97, .97, len(percentiles)-1))
|
||||
|
||||
if 'alpha' in kwargs:
|
||||
alpha = kwargs.pop('alpha')
|
||||
else:
|
||||
alpha = .8
|
||||
|
||||
if 'cmap' in kwargs:
|
||||
cmap = kwargs.pop('cmap')
|
||||
else:
|
||||
cmap = LinearSegmentedColormap.from_list('WhToColor', (color, color), N=array.size)
|
||||
cmap._init()
|
||||
cmap._lut[:-3, -1] = alpha*array
|
||||
|
||||
kwargs['facecolors'] = [cmap(i) for i in np.linspace(0,1,cmap.N)]
|
||||
|
||||
# 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(iterable):
|
||||
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
|
||||
from itertools import tee
|
||||
#try:
|
||||
# from itertools import izip as zip
|
||||
#except ImportError:
|
||||
# pass
|
||||
a, b = tee(iterable)
|
||||
next(b, None)
|
||||
return zip(a, b)
|
||||
|
||||
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")
|
||||
|
||||
from functools import reduce
|
||||
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)
|
||||
p = 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]
|
||||
|
||||
p[0] = start
|
||||
p[N + 1] = end
|
||||
|
||||
p[1:N + 1, 0] = xslice
|
||||
p[1:N + 1, 1] = y1slice
|
||||
p[N + 2:, 0] = xslice[::-1]
|
||||
p[N + 2:, 1] = y2slice[::-1]
|
||||
|
||||
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()
|
||||
return plots
|
||||
119
GPy/plotting/matplot_dep/util.py
Normal file
119
GPy/plotting/matplot_dep/util.py
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
#===============================================================================
|
||||
# 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 legend_ontop(ax, mode='expand', ncol=3, fontdict=None):
|
||||
from mpl_toolkits.axes_grid1 import make_axes_locatable
|
||||
handles, labels = ax.get_legend_handles_labels()
|
||||
divider = make_axes_locatable(ax)
|
||||
cax = divider.append_axes("top", "5%", pad=0)
|
||||
lgd = cax.legend(handles, labels, bbox_to_anchor=(0., 0., 1., 1.), loc=3,
|
||||
ncol=ncol, mode=mode, borderaxespad=0., prop=fontdict or {})
|
||||
cax.set_axis_off()
|
||||
#lgd = cax.legend(bbox_to_anchor=(0., 1.02, 1., 1.02), loc=3,
|
||||
# ncol=ncol, mode=mode, borderaxespad=0., prop=fontdict or {})
|
||||
return lgd
|
||||
|
||||
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)
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
import GPy
|
||||
import numpy as np
|
||||
import matplotlib as mpl
|
||||
import time
|
||||
from ...core.parameterization.variational import VariationalPosterior
|
||||
try:
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib as mpl
|
||||
from mpl_toolkits.mplot3d import Axes3D
|
||||
import visual
|
||||
visual_available = True
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue