mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-06-14 15:25:15 +02:00
[density] plot added
This commit is contained in:
parent
6b6ca60bb5
commit
d8243383b4
3 changed files with 186 additions and 0 deletions
|
|
@ -595,6 +595,45 @@ class GP(Model):
|
|||
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_density(self, levels=20, plot_limits=None, fignum=None, ax=None,
|
||||
fixed_inputs=[], plot_raw=False, edgecolor='none', facecolor='#3465a4',
|
||||
predict_kw=None,Y_metadata=None,
|
||||
apply_link=False, resolution=200, **patch_kw):
|
||||
"""
|
||||
Plot the posterior density of the GP.
|
||||
- In one dimension, the function is plotted with a shaded gradient, visualizing the density of the posterior.
|
||||
- Only implemented for one dimension, for higher dimensions use `plot`.
|
||||
|
||||
:param levels: number of levels to plot in the density plot. This is a number between 1 and 100. 1 corresponds to the normal plot_fit.
|
||||
:type levels: int
|
||||
:param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits
|
||||
:type plot_limits: np.array
|
||||
:param fixed_inputs: a list of tuple [(i,v), (i,v)...], specifying that input index i should be set to value v.
|
||||
:type fixed_inputs: a list of tuples
|
||||
:param resolution: the number of intervals to sample the GP on. Defaults to 200 in 1D and 50 (a 50x50 grid) in 2D
|
||||
:type resolution: int
|
||||
:param edgecolor: color of line to plot [Tango.colorsHex['darkBlue']]
|
||||
:type edgecolor: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib
|
||||
:param facecolor: color of fill [Tango.colorsHex['lightBlue']]
|
||||
:type facecolor: color either as Tango.colorsHex object or character ('r' is red, 'g' is green) as is standard in matplotlib
|
||||
:param Y_metadata: additional data associated with Y which may be needed
|
||||
:type Y_metadata: dict
|
||||
:param apply_link: if there is a link function of the likelihood, plot the link(f*) rather than f*, when plotting posterior samples f
|
||||
:type apply_link: boolean
|
||||
:param resolution: resolution of interpolation (how many points to interpolate of the posterior).
|
||||
:type resolution: int
|
||||
:param: patch_kw: the keyword arguments for the patchcollection fill.
|
||||
"""
|
||||
assert "matplotlib" in sys.modules, "matplotlib package has not been imported."
|
||||
from ..plotting.matplot_dep import models_plots
|
||||
return models_plots.plot_density(self, levels, plot_limits, fignum, ax,
|
||||
fixed_inputs, plot_raw=plot_raw,
|
||||
Y_metadata=Y_metadata,
|
||||
predict_kw=predict_kw,
|
||||
apply_link=apply_link,
|
||||
edgecolor=edgecolor, facecolor=facecolor,
|
||||
**patch_kw)
|
||||
|
||||
|
||||
def plot_data(self, which_data_rows='all',
|
||||
which_data_ycols='all', visible_dims=None,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,88 @@ def gpplot(x, mu, lower, upper, edgecol='#3300FF', fillcol='#33CCFF', ax=None, f
|
|||
|
||||
return plots
|
||||
|
||||
def plot_gradient_fill(ax, x, percentiles, **kwargs):
|
||||
plots = []
|
||||
|
||||
#here's the box
|
||||
if 'linewidth' not in kwargs:
|
||||
kwargs['linewidth'] = 0.5
|
||||
if not 'alpha' in kwargs.keys():
|
||||
kwargs['alpha'] = 1./(len(percentiles))
|
||||
|
||||
# pop where from kwargs
|
||||
where = kwargs.pop('where') if 'where' in kwargs else None
|
||||
# pop interpolate, which we actually do not do here!
|
||||
if 'interpolate' in kwargs: kwargs.pop('interpolate')
|
||||
|
||||
def pairwise(inlist):
|
||||
l = len(inlist)
|
||||
for i in range(int(np.ceil(l/2.))):
|
||||
yield inlist[:][i], inlist[:][(l-1)-i]
|
||||
|
||||
polycol = []
|
||||
for y1, y2 in pairwise(percentiles):
|
||||
import matplotlib.mlab as mlab
|
||||
# Handle united data, such as dates
|
||||
ax._process_unit_info(xdata=x, ydata=y1)
|
||||
ax._process_unit_info(ydata=y2)
|
||||
|
||||
# Convert the arrays so we can work with them
|
||||
from numpy import ma
|
||||
x = ma.masked_invalid(ax.convert_xunits(x))
|
||||
y1 = ma.masked_invalid(ax.convert_yunits(y1))
|
||||
y2 = ma.masked_invalid(ax.convert_yunits(y2))
|
||||
|
||||
if y1.ndim == 0:
|
||||
y1 = np.ones_like(x) * y1
|
||||
if y2.ndim == 0:
|
||||
y2 = np.ones_like(x) * y2
|
||||
|
||||
if where is None:
|
||||
where = np.ones(len(x), np.bool)
|
||||
else:
|
||||
where = np.asarray(where, np.bool)
|
||||
|
||||
if not (x.shape == y1.shape == y2.shape == where.shape):
|
||||
raise ValueError("Argument dimensions are incompatible")
|
||||
|
||||
mask = reduce(ma.mask_or, [ma.getmask(a) for a in (x, y1, y2)])
|
||||
if mask is not ma.nomask:
|
||||
where &= ~mask
|
||||
|
||||
polys = []
|
||||
for ind0, ind1 in mlab.contiguous_regions(where):
|
||||
xslice = x[ind0:ind1]
|
||||
y1slice = y1[ind0:ind1]
|
||||
y2slice = y2[ind0:ind1]
|
||||
|
||||
if not len(xslice):
|
||||
continue
|
||||
|
||||
N = len(xslice)
|
||||
X = np.zeros((2 * N + 2, 2), np.float)
|
||||
|
||||
# the purpose of the next two lines is for when y2 is a
|
||||
# scalar like 0 and we want the fill to go all the way
|
||||
# down to 0 even if none of the y1 sample points do
|
||||
start = xslice[0], y2slice[0]
|
||||
end = xslice[-1], y2slice[-1]
|
||||
|
||||
X[0] = start
|
||||
X[N + 1] = end
|
||||
|
||||
X[1:N + 1, 0] = xslice
|
||||
X[1:N + 1, 1] = y1slice
|
||||
X[N + 2:, 0] = xslice[::-1]
|
||||
X[N + 2:, 1] = y2slice[::-1]
|
||||
|
||||
polys.append(X)
|
||||
polycol.extend(polys)
|
||||
from matplotlib.collections import PolyCollection
|
||||
plots.append(PolyCollection(polycol, **kwargs))
|
||||
ax.add_collection(plots[-1], autolim=True)
|
||||
ax.autoscale_view()
|
||||
return plots
|
||||
|
||||
def gperrors(x, mu, lower, upper, edgecol=None, ax=None, fignum=None, **kwargs):
|
||||
_, axes = ax_default(fignum, ax)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from ...models.sparse_gp_coregionalized_regression import SparseGPCoregionalized
|
|||
from scipy import sparse
|
||||
from ...core.parameterization.variational import VariationalPosterior
|
||||
from matplotlib import pyplot as plt
|
||||
from GPy.plotting.matplot_dep.base_plots import plot_gradient_fill
|
||||
|
||||
|
||||
def plot_data(model, which_data_rows='all',
|
||||
|
|
@ -299,6 +300,70 @@ def plot_fit(model, plot_limits=None, which_data_rows='all',
|
|||
raise NotImplementedError("Cannot define a frame with more than two input dimensions")
|
||||
return plots
|
||||
|
||||
def plot_density(model, levels=20, plot_limits=None, fignum=None, ax=None,
|
||||
fixed_inputs=[], plot_raw=False, edgecolor='none', facecolor='#3465a4',
|
||||
predict_kw=None,Y_metadata=None,
|
||||
apply_link=False, resolution=200, **patch_kwargs):
|
||||
#deal with optional arguments
|
||||
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
|
||||
else:
|
||||
X = model.X
|
||||
Y = model.Y
|
||||
if sparse.issparse(Y): Y = Y.todense().view(np.ndarray)
|
||||
|
||||
if predict_kw is None:
|
||||
predict_kw = {}
|
||||
|
||||
#work out what the inputs are for plotting (1D or 2D)
|
||||
fixed_dims = np.array([i for i,v in fixed_inputs])
|
||||
free_dims = np.setdiff1d(np.arange(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)
|
||||
Xgrid = np.empty((Xnew.shape[0],model.input_dim))
|
||||
Xgrid[:,free_dims] = Xnew
|
||||
for i,v in fixed_inputs:
|
||||
Xgrid[:,i] = v
|
||||
|
||||
percs = np.linspace(2.5, 97.5, levels*2)
|
||||
|
||||
#make a prediction on the frame and plot it
|
||||
if plot_raw:
|
||||
raise NotImplementedError('What to do? What to do?')
|
||||
#===================================================================
|
||||
# m, v = model._raw_predict(Xgrid, **predict_kw)
|
||||
# percentiles = model.predict_quantiles(Xgrid, )
|
||||
# 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
|
||||
percentiles = [i[:, 0] for i in model.predict_quantiles(Xgrid, percs, Y_metadata=Y_metadata, **predict_kw)]
|
||||
patch_kwargs['facecolor'] = facecolor
|
||||
patch_kwargs['edgecolor'] = edgecolor
|
||||
plots['density'] = plot_gradient_fill(ax, Xgrid[:, 0], percentiles, **patch_kwargs)
|
||||
else:
|
||||
raise NotImplementedError('Only 1D density plottable.')
|
||||
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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue