[density] plot added

This commit is contained in:
mzwiessele 2015-10-01 20:06:31 +01:00
parent 6b6ca60bb5
commit d8243383b4
3 changed files with 186 additions and 0 deletions

View file

@ -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)

View file

@ -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.