Plotting functions modified

This commit is contained in:
Ricardo 2014-01-28 13:39:59 +00:00
parent 822459cdb6
commit 1654080402

View file

@ -2,10 +2,9 @@
# Licensed under the BSD 3-clause license (see LICENSE.txt) # Licensed under the BSD 3-clause license (see LICENSE.txt)
import numpy as np import numpy as np
import pylab as pb import sys
import warnings import warnings
from .. import kern from .. import kern
from ..util.plot import gpplot, Tango, x_frame1D, x_frame2D
from ..util.linalg import dtrtrs from ..util.linalg import dtrtrs
from model import Model from model import Model
from parameterization import ObservableArray from parameterization import ObservableArray
@ -122,9 +121,9 @@ class GP(Model):
:param X: The points at which to take the samples. :param X: The points at which to take the samples.
:type X: np.ndarray, Nnew x self.input_dim. :type X: np.ndarray, Nnew x self.input_dim.
:param size: the number of a posteriori samples to plot. :param size: the number of a posteriori samples.
:type size: int. :type size: int.
:param which_parts: which of the kernel functions to plot (additively). :param which_parts: which of the kernel functions to use (additively).
:type which_parts: 'all', or list of bools. :type which_parts: 'all', or list of bools.
:param full_cov: whether to return the full covariance matrix, or just the diagonal. :param full_cov: whether to return the full covariance matrix, or just the diagonal.
:type full_cov: bool. :type full_cov: bool.
@ -145,9 +144,9 @@ class GP(Model):
:param X: the points at which to take the samples. :param X: the points at which to take the samples.
:type X: np.ndarray, Nnew x self.input_dim. :type X: np.ndarray, Nnew x self.input_dim.
:param size: the number of a posteriori samples to plot. :param size: the number of a posteriori samples.
:type size: int. :type size: int.
:param which_parts: which of the kernel functions to plot (additively). :param which_parts: which of the kernel functions to use (additively).
:type which_parts: 'all', or list of bools. :type which_parts: 'all', or list of bools.
:param full_cov: whether to return the full covariance matrix, or just the diagonal. :param full_cov: whether to return the full covariance matrix, or just the diagonal.
:type full_cov: bool. :type full_cov: bool.
@ -172,20 +171,13 @@ class GP(Model):
""" """
Plot the GP's view of the world, where the data is normalized and before applying a likelihood. Plot the GP's view of the world, where the data is normalized and before applying a likelihood.
This is a convenience function: we simply call self.plot with the This is a convenience function: arguments are passed to GPy.plotting.matplot_dep.models_plots.plot_f_fit
argument use_raw_predict set True. All args and kwargs are passed on to
plot.
see also: gp.plot
""" """
kwargs['plot_raw'] = True assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
self.plot(*args, **kwargs) from ..plotting.matplot_dep import models_plots
models_plots.plot_fit_f(self,*args,**kwargs)
def plot(self, plot_limits=None, which_data_rows='all', def plot(self, *args):
which_data_ycols='all', which_parts='all', fixed_inputs=[],
levels=20, samples=0, fignum=None, ax=None, resolution=None,
plot_raw=False,
linecol=Tango.colorsHex['darkBlue'],fillcol=Tango.colorsHex['lightBlue']):
""" """
Plot the posterior of the GP. Plot the posterior of the GP.
- In one dimension, the function is plotted with a shaded region identifying two standard deviations. - In one dimension, the function is plotted with a shaded region identifying two standard deviations.
@ -193,121 +185,13 @@ class GP(Model):
- In higher dimensions, use fixed_inputs to plot the GP with some of the inputs fixed. - 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 Can plot only part of the data and part of the posterior functions
using which_data_rowsm which_data_ycols and which_parts using which_data_rows which_data_ycols and which_parts
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits This is a convenience function: arguments are passed to GPy.plotting.matplot_dep.models_plots.plot_fit
:type plot_limits: np.array
:param which_data_rows: which of the training data to plot (default all)
:type which_data_rows: 'all' or a slice object to slice self.X, self.Y
:param which_data_ycols: when the data has several columns (independant outputs), only plot these
:type which_data_rows: 'all' or a list of integers
:param which_parts: which of the kernel functions to plot (additively)
:type which_parts: 'all', or list of bools
: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.
: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
:type output: integer (first output is 0)
:param linecol: color of line to plot.
:type linecol:
:param fillcol: color of fill
:param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure
""" """
#deal with optional arguments assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
if which_data_rows == 'all': from ..plotting.matplot_dep import models_plots
which_data_rows = slice(None) models_plots.plot_fit(self,*args)
if which_data_ycols == 'all':
which_data_ycols = np.arange(self.output_dim)
if len(which_data_ycols)==0:
raise ValueError('No data selected for plotting')
if ax is None:
fig = pb.figure(num=fignum)
ax = fig.add_subplot(111)
#work out what the inputs are for plotting (1D or 2D)
fixed_dims = np.array([i for i,v in fixed_inputs])
free_dims = np.setdiff1d(np.arange(self.input_dim),fixed_dims)
#one dimensional plotting
if len(free_dims) == 1:
#define the frame on which to plot
resolution = resolution or 200
Xnew, xmin, xmax = x_frame1D(self.X[:,free_dims], plot_limits=plot_limits)
Xgrid = np.empty((Xnew.shape[0],self.input_dim))
Xgrid[:,free_dims] = Xnew
for i,v in fixed_inputs:
Xgrid[:,i] = v
#make a prediction on the frame and plot it
if plot_raw:
m, v = self._raw_predict(Xgrid, which_parts=which_parts)
lower = m - 2*np.sqrt(v)
upper = m + 2*np.sqrt(v)
Y = self.Y
else:
m, v, lower, upper = self.predict(Xgrid, which_parts=which_parts)
Y = self.Y
for d in which_data_ycols:
gpplot(Xnew, m[:, d], lower[:, d], upper[:, d], axes=ax, edgecol=linecol, fillcol=fillcol)
ax.plot(self.X[which_data_rows,free_dims], Y[which_data_rows, d], 'kx', mew=1.5)
#optionally plot some samples
if samples: #NOTE not tested with fixed_inputs
Ysim = self.posterior_samples(Xgrid, samples, which_parts=which_parts)
for yi in Ysim.T:
ax.plot(Xnew, yi[:,None], Tango.colorsHex['darkBlue'], linewidth=0.25)
#ax.plot(Xnew, yi[:,None], marker='x', linestyle='--',color=Tango.colorsHex['darkBlue']) #TODO apply this line for discrete outputs.
#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(xmin, xmax)
ax.set_ylim(ymin, ymax)
#2D plotting
elif len(free_dims) == 2:
#define the frame for plotting on
resolution = resolution or 50
Xnew, _, _, xmin, xmax = x_frame2D(self.X[:,free_dims], plot_limits, resolution)
Xgrid = np.empty((Xnew.shape[0],self.input_dim))
Xgrid[:,free_dims] = Xnew
for i,v in fixed_inputs:
Xgrid[:,i] = v
x, y = np.linspace(xmin[0], xmax[0], resolution), np.linspace(xmin[1], xmax[1], resolution)
#predict on the frame and plot
if plot_raw:
m, _ = self._raw_predict(Xgrid, which_parts=which_parts)
Y = self.likelihood.Y
else:
m, _, _, _ = self.predict(Xgrid, which_parts=which_parts,sampling=False)
Y = self.likelihood.data
for d in which_data_ycols:
m_d = m[:,d].reshape(resolution, resolution).T
ax.contour(x, y, m_d, levels, vmin=m.min(), vmax=m.max(), cmap=pb.cm.jet)
ax.scatter(self.X[which_data_rows, free_dims[0]], self.X[which_data_rows, free_dims[1]], 40, Y[which_data_rows, d], cmap=pb.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...")
else:
raise NotImplementedError, "Cannot define a frame with more than two input dimensions"
def _getstate(self): def _getstate(self):
""" """
@ -333,5 +217,3 @@ class GP(Model):
self.num_data = state.pop() self.num_data = state.pop()
self.X = state.pop() self.X = state.pop()
Model._setstate(self, state) Model._setstate(self, state)