From 1fe92b2515af5b57e7231f84cdd1a4c7b0366713 Mon Sep 17 00:00:00 2001 From: James Hensman Date: Sat, 26 Oct 2013 15:01:35 +0100 Subject: [PATCH] fixed up plot in GP_base --- GPy/core/gp_base.py | 59 +++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/GPy/core/gp_base.py b/GPy/core/gp_base.py index 12e71c93..ca1e75af 100644 --- a/GPy/core/gp_base.py +++ b/GPy/core/gp_base.py @@ -162,7 +162,7 @@ class GPBase(Model): 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 - - Not implemented in higher dimensions + - 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 and which_functions @@ -198,52 +198,69 @@ class GPBase(Model): fig = pb.figure(num=fignum) ax = fig.add_subplot(111) - plotdims = self.input_dim - len(fixed_inputs) - if plotdims == 1: + #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 - Xu = self.X * self._Xscale + self._Xoffset #NOTE self.X are the normalized values now - - fixed_dims = np.array([i for i,v in fixed_inputs]) - freedim = np.setdiff1d(np.arange(self.input_dim),fixed_dims) - - Xnew, xmin, xmax = x_frame1D(Xu[:,freedim], plot_limits=plot_limits) + Xnew, xmin, xmax = x_frame1D(Xu[:,free_dims], plot_limits=plot_limits) Xgrid = np.empty((Xnew.shape[0],self.input_dim)) - Xgrid[:,freedim] = Xnew + Xgrid[:,free_dims] = Xnew for i,v in fixed_inputs: Xgrid[:,i] = v + #make a prediction on the frame and plot it m, v, lower, upper = self.predict(Xgrid, which_parts=which_parts) + for d in range(m.shape[1]): + gpplot(Xnew, m[:, d], lower[:, d], upper[:, d], axes=ax, edgecol=linecol, fillcol=fillcol) + ax.plot(Xu[which_data,free_dims], self.likelihood.data[which_data, 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, full_cov=True) 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. - for d in range(m.shape[1]): - gpplot(Xnew, m[:, d], lower[:, d], upper[:, d], axes=ax, edgecol=linecol, fillcol=fillcol) - ax.plot(Xu[which_data,freedim], self.likelihood.data[which_data, d], 'kx', mew=1.5) + + #set the limits of the plot to some sensible values ymin, ymax = min(np.append(self.likelihood.data, lower)), max(np.append(self.likelihood.data, upper)) ymin, ymax = ymin - 0.1 * (ymax - ymin), ymax + 0.1 * (ymax - ymin) ax.set_xlim(xmin, xmax) ax.set_ylim(ymin, ymax) - elif self.X.shape[1] == 2: + #2D plotting + elif len(free_dims) == 2: + #define the frame for plotting on resolution = resolution or 50 - Xnew, _, _, xmin, xmax = x_frame2D(self.X, plot_limits, resolution) + Xu = self.X * self._Xscale + self._Xoffset #NOTE self.X are the normalized values now + Xnew, _, _, xmin, xmax = x_frame2D(Xu[:,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) - m, _, lower, upper = self.predict(Xnew, which_parts=which_parts) - m = m.reshape(resolution, resolution).T - ax.contour(x, y, m, levels, vmin=m.min(), vmax=m.max(), cmap=pb.cm.jet) # @UndefinedVariable - Yf = self.likelihood.Y.flatten() - ax.scatter(self.X[:, 0], self.X[:, 1], 40, Yf, cmap=pb.cm.jet, vmin=m.min(), vmax=m.max(), linewidth=0.) # @UndefinedVariable + + #predict on the frame and plot + m, _, _, _ = self.predict(Xgrid, which_parts=which_parts) + for d in range(m.shape[1]): + 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) + Y_d = self.likelihood.Y[:,d] + ax.scatter(self.X[:, free_dims[0]], self.X[:, free_dims[1]], 40, Y_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 only implemented for 1 dimensional inputs.") + warnings.warn("Samples are rather difficult to plot for 2D inputs...") else: raise NotImplementedError, "Cannot define a frame with more than two input dimensions"