diff --git a/GPy/core/gp.py b/GPy/core/gp.py index 01e09739..16b0ca0f 100644 --- a/GPy/core/gp.py +++ b/GPy/core/gp.py @@ -294,7 +294,7 @@ class GP(Model): 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* @@ -311,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): diff --git a/GPy/plotting/__init__.py b/GPy/plotting/__init__.py index b90bf938..2a297f28 100644 --- a/GPy/plotting/__init__.py +++ b/GPy/plotting/__init__.py @@ -46,10 +46,13 @@ if config.get('plotting', 'library') is not 'none': from ..models import bayesian_gplvm_minibatch GPLVM.plot_prediction_fit = gpy_plot.latent_plots.plot_prediction_fit GPLVM.plot_latent = gpy_plot.latent_plots.plot_latent + GPLVM.plot_steepest_gradient_map = gpy_plot.latent_plots.plot_steepest_gradient_map BayesianGPLVM.plot_latent = gpy_plot.latent_plots.plot_latent BayesianGPLVM.plot_prediction_fit = gpy_plot.latent_plots.plot_prediction_fit + 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_prediction_fit = gpy_plot.latent_plots.plot_prediction_fit + bayesian_gplvm_minibatch.BayesianGPLVMMiniBatch.plot_steepest_gradient_map = gpy_plot.latent_plots.plot_steepest_gradient_map from ..kern import Kern #Kern.plot_covariance = gpy_plot.kern_plots.plot_kern diff --git a/GPy/plotting/abstract_plotting_library.py b/GPy/plotting/abstract_plotting_library.py index a03d8591..b7b0c1aa 100644 --- a/GPy/plotting/abstract_plotting_library.py +++ b/GPy/plotting/abstract_plotting_library.py @@ -189,6 +189,31 @@ class AbstractPlottingLibrary(object): """ 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, plot_function=None, resolution=15, **kwargs): + """ + Plot an annotation heatmap. That is like an imshow, but + put the text of the labels inside the cells of the heatmap (centered). + + if the labels are not given, just plot the heatmap. + + 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 + :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. diff --git a/GPy/plotting/gpy_plot/latent_plots.py b/GPy/plotting/gpy_plot/latent_plots.py index a8bb2be6..06f3f226 100644 --- a/GPy/plotting/gpy_plot/latent_plots.py +++ b/GPy/plotting/gpy_plot/latent_plots.py @@ -111,15 +111,74 @@ def _plot_prediction_fit(self, canvas, plot_limits=None, else: raise NotImplementedError("Cannot plot in more then one dimension.") return plots + +def _plot_latent_scatter(self, canvas, X, input_1, input_2, labels, marker, num_samples, **kwargs): + from .. import Tango + Tango.reset() + if labels is None: + labels = np.ones(self.num_data) + X, labels = subsample_X(X, labels, num_samples) + scatters = [] + for x, y, this_label, _, m in scatter_label_generator(labels, X, input_1, input_2, marker): + update_not_existing_kwargs(kwargs, pl.defaults.latent_scatter) + scatters.append(pl.scatter(canvas, x, y, marker=m, color=Tango.nextMedium(), 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, + **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 = self.get_most_significant_input_dimensions(which_indices) + canvas, kwargs = pl.get_new_canvas(xlabel='latent dimension %i' % input_1, ylabel='latent dimension %i' % input_2, **kwargs) + X, _, _ = get_x_y_var(self) + scatters = _plot_latent_scatter(self, canvas, X, input_1, input_2, labels, marker, num_samples, **kwargs) + return pl.show_canvas(canvas, dict(scatter=scatters), legend=legend and (labels is not None)) + + + + +def _plot_magnification(self, canvas, input_1, input_2, Xgrid, + xmin, xmax, resolution, + mean=True, covariance=True, + kern=None, + **imshow_kwargs): + def plot_function(x): + Xtest_full = np.zeros((x.shape[0], Xgrid.shape[1])) + Xtest_full[:, [input_1, input_2]] = x + mf = self.predict_magnification(Xtest_full, kern=kern, mean=mean, covariance=covariance) + return mf.reshape(resolution, resolution).T[::-1, :] + + imshow_kwargs = update_not_existing_kwargs(imshow_kwargs, pl.defaults.magnification) + Y = plot_function(Xgrid[:, [input_1, input_2]]) + view = pl.imshow(canvas, Y, + (xmin[0], xmin[1], xmax[1], xmax[1]), + None, plot_function, resolution, + vmin=Y.min(), vmax=Y.max(), + **imshow_kwargs) + return view def plot_magnification(self, labels=None, which_indices=None, - resolution=60, legend=True, + resolution=60, marker='<>^vsd', legend=True, plot_limits=None, updates=False, mean=True, covariance=True, - kern=None, marker='<>^vsd', - num_samples=1000, - imshow_kwargs=None, **kwargs): + kern=None, num_samples=1000, + imshow_kwargs=None, + **scatter_kwargs): """ Plot the magnification factor of the GP on the inputs. This is the density of the GP as a gray scale. @@ -127,6 +186,7 @@ def plot_magnification(self, labels=None, which_indices=None, :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)) @@ -134,48 +194,41 @@ def plot_magnification(self, labels=None, which_indices=None, :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 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 kwargs: the kwargs for the scatter plots """ input_1, input_2 = self.get_most_significant_input_dimensions(which_indices) + canvas, scatter_kwargs = pl.get_new_canvas(xlabel='latent dimension %i' % input_1, ylabel='latent dimension %i' % input_2, **scatter_kwargs) + X, _, _, _, _, Xgrid, _, _, xmin, xmax, resolution = helper_for_plot_data(self, plot_limits, (input_1, input_2), None, resolution) + scatters = _plot_latent_scatter(self, canvas, X, input_1, input_2, labels, marker, num_samples, **scatter_kwargs) + if imshow_kwargs is None: imshow_kwargs = {} + view = _plot_magnification(self, canvas, input_1, input_2, Xgrid, xmin, xmax, resolution, mean, covariance, kern, **imshow_kwargs) + plots = pl.show_canvas(canvas, dict(scatter=scatters, imshow=view), legend=legend and (labels is not None), xlim=(xmin[0], xmax[0]), ylim=(xmin[1], xmax[1])) + _wait_for_updates(view, updates) + return plots - from .. import Tango - Tango.reset() - - if labels is None: - labels = np.ones(self.num_data) - legend = False # No legend if there is no labels given - - canvas, kwargs = pl.get_new_canvas(xlabel='latent dimension %i' % input_1, ylabel='latent dimension %i' % input_2, **kwargs) - X, _, _, _, _, Xgrid, _, _, xmin, xmax, resolution = helper_for_plot_data(self, plot_limits, (input_1, input_2), None, resolution) - X, labels = subsample_X(X, labels) - + + +def _plot_latent(self, canvas, input_1, input_2, Xgrid, + xmin, xmax, resolution, + kern=None, + **imshow_kwargs): def plot_function(x): - Xtest_full = np.zeros((x.shape[0], X.shape[1])) + Xtest_full = np.zeros((x.shape[0], Xgrid.shape[1])) Xtest_full[:, [input_1, input_2]] = x - mf = self.predict_magnification(Xtest_full, kern=kern, mean=mean, covariance=covariance) - return mf + mf = np.log(self.predict(Xtest_full, kern=kern)[1]) + return mf.reshape(resolution, resolution).T[::-1, :] - imshow_kwargs = update_not_existing_kwargs(imshow_kwargs, pl.defaults.magnification) + imshow_kwargs = update_not_existing_kwargs(imshow_kwargs, pl.defaults.latent) Y = plot_function(Xgrid[:, [input_1, input_2]]).reshape(resolution, resolution).T[::-1, :] view = pl.imshow(canvas, Y, (xmin[0], xmin[1], xmax[1], xmax[1]), None, plot_function, resolution, vmin=Y.min(), vmax=Y.max(), **imshow_kwargs) - - scatters = [] - for x, y, this_label, _, m in scatter_label_generator(labels, X, input_1, input_2, marker): - update_not_existing_kwargs(kwargs, pl.defaults.latent_scatter) - scatters.append(pl.scatter(canvas, x, y, marker=m, color=Tango.nextMedium(), label=this_label, **kwargs)) - - plots = pl.show_canvas(canvas, dict(scatter=scatters, imshow=view), legend=legend, xlim=(xmin[0], xmax[0]), ylim=(xmin[1], xmax[1])) - _wait_for_updates(view, updates) - return plots - + return view def plot_latent(self, labels=None, which_indices=None, resolution=60, legend=True, @@ -183,7 +236,7 @@ def plot_latent(self, labels=None, which_indices=None, updates=False, kern=None, marker='<>^vsd', num_samples=1000, - imshow_kwargs=None, **kwargs): + imshow_kwargs=None, **scatter_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 @@ -200,53 +253,44 @@ def plot_latent(self, labels=None, which_indices=None, :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 kwargs: the kwargs for the scatter plots + :param scatter_kwargs: the kwargs for the scatter plots """ input_1, input_2 = self.get_most_significant_input_dimensions(which_indices) - - from .. import Tango - Tango.reset() - - if labels is None: - labels = np.ones(self.num_data) - legend = False # No legend if there is no labels given - - canvas, kwargs = pl.get_new_canvas(xlabel='latent dimension %i' % input_1, ylabel='latent dimension %i' % input_2, **kwargs) - - X, _, _, _, _, Xgrid, _, _, xmin, xmax, resolution = helper_for_plot_data(self, plot_limits, (input_1, input_2), None, resolution) - X, labels = subsample_X(X, labels) - - def plot_function(x): - Xtest_full = np.zeros((x.shape[0], X.shape[1])) - Xtest_full[:, [input_1, input_2]] = x - mf = np.log(self.predict(Xtest_full, kern=kern)[1]) - return mf - - imshow_kwargs = update_not_existing_kwargs(imshow_kwargs, pl.defaults.latent) - Y = plot_function(Xgrid[:, [input_1, input_2]]).reshape(resolution, resolution).T[::-1, :] - view = pl.imshow(canvas, Y, - (xmin[0], xmin[1], xmax[1], xmax[1]), - None, plot_function, resolution, - vmin=Y.min(), vmax=Y.max(), - **imshow_kwargs) - - scatters = [] - for x, y, this_label, _, m in scatter_label_generator(labels, X, input_1, input_2, marker): - update_not_existing_kwargs(kwargs, pl.defaults.latent_scatter) - scatters.append(pl.scatter(canvas, x, y, marker=m, color=Tango.nextMedium(), label=this_label, **kwargs)) - - plots = pl.show_canvas(canvas, dict(scatter=scatters, imshow=view), legend=legend, xlim=(xmin[0], xmax[0]), ylim=(xmin[1], xmax[1])) + canvas, scatter_kwargs = pl.get_new_canvas(xlabel='latent dimension %i' % input_1, ylabel='latent dimension %i' % input_2, **scatter_kwargs) + X, _, _, _, _, Xgrid, _, _, xmin, xmax, resolution = helper_for_plot_data(self, plot_limits, (input_1, input_2), None, resolution) + scatters = _plot_latent_scatter(self, canvas, X, input_1, input_2, labels, marker, num_samples, **scatter_kwargs) + if imshow_kwargs is None: imshow_kwargs = {} + view = _plot_latent(self, canvas, input_1, input_2, Xgrid, xmin, xmax, resolution, kern, **imshow_kwargs) + plots = pl.show_canvas(canvas, dict(scatter=scatters, imshow=view), legend=legend and (labels is not None), xlim=(xmin[0], xmax[0]), ylim=(xmin[1], xmax[1])) _wait_for_updates(view, updates) return plots +def _plot_steepest_gradient_map(self, canvas, input_1, input_2, Xgrid, + xmin, xmax, resolution, output_labels, + kern=None, annotation_kwargs=None, + **imshow_kwargs): + if output_labels is None: + output_labels = range(self.output_dim) + def plot_function(x): + Xgrid[:, [input_1, input_2]] = x + 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[::-1, :], np.array(output_labels)[argmax].reshape(resolution, resolution) + Y, annotation = plot_function(Xgrid[:, [input_1, input_2]]) + annotation_kwargs = update_not_existing_kwargs(annotation_kwargs or {}, pl.defaults.annotation) + imshow_kwargs = update_not_existing_kwargs(imshow_kwargs or {}, pl.defaults.gradient) + annotation = pl.annotation_heatmap(canvas, Y, annotation, (xmin[0], xmin[1], xmax[1], xmax[1]), + None, plot_function, resolution, imshow_kwargs=imshow_kwargs, **annotation_kwargs) + imshow_kwargs = update_not_existing_kwargs(imshow_kwargs, pl.defaults.gradient) + return dict(annotation=annotation) -def plot_steepest_gradient_map(self, labels=None, which_indices=None, - resolution=60, legend=True, +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, - imshow_kwargs=None, **kwargs): + annotation_kwargs=None, scatter_kwargs=None, **imshow_kwargs): """ Plot the latent space of the GP on the inputs. This is the @@ -264,41 +308,19 @@ def plot_steepest_gradient_map(self, labels=None, which_indices=None, :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 kwargs: the kwargs for the scatter plots + :param annotation_kwargs: the kwargs for the annotation plot + :param scatter_kwargs: the kwargs for the scatter plots """ input_1, input_2 = self.get_most_significant_input_dimensions(which_indices) + canvas, imshow_kwargs = pl.get_new_canvas(xlabel='latent dimension %i' % input_1, ylabel='latent dimension %i' % input_2, **imshow_kwargs) + X, _, _, _, _, Xgrid, _, _, xmin, xmax, resolution = helper_for_plot_data(self, plot_limits, (input_1, input_2), None, resolution) + scatters = _plot_latent_scatter(self, canvas, X, input_1, input_2, data_labels, marker, num_samples, **scatter_kwargs or {}) + view = _plot_steepest_gradient_map(self, canvas, input_1, input_2, Xgrid, xmin, xmax, resolution, output_labels, kern, annotation_kwargs=annotation_kwargs, **imshow_kwargs) + plots = pl.show_canvas(canvas, dict(scatter=scatters, imshow=view), legend=legend and (data_labels is not None), xlim=(xmin[0], xmax[0]), ylim=(xmin[1], xmax[1])) + _wait_for_updates(view['annotation'], updates) + return plots + - from .. import Tango - Tango.reset() - - if labels is None: - labels = np.ones(self.num_data) - legend = False # No legend if there is no labels given - - canvas, kwargs = pl.get_new_canvas(xlabel='latent dimension %i' % input_1, ylabel='latent dimension %i' % input_2, **kwargs) - X, _, _, _, _, Xgrid, _, _, xmin, xmax, resolution = helper_for_plot_data(self, plot_limits, (input_1, input_2), None, resolution) - X, labels = subsample_X(X, labels) - - def plot_function(x): - X[:, [input_1, input_2]] = x - dmu_dX = self.predictive_gradients(X)[0] - argmax = np.argmax(dmu_dX, 1) - return dmu_dX[:, argmax], np.array(labels)[argmax] - imshow_kwargs = update_not_existing_kwargs(imshow_kwargs, pl.defaults.latent) - Y = plot_function(Xgrid[:, [input_1, input_2]]).reshape(resolution, resolution).T[::-1, :] - view = pl.imshow(canvas, Y, - (xmin[0], xmin[1], xmax[1], xmax[1]), - None, plot_function, resolution, - vmin=Y.min(), vmax=Y.max(), - **imshow_kwargs) - scatters = [] - for x, y, this_label, _, m in scatter_label_generator(labels, X, input_1, input_2, marker): - update_not_existing_kwargs(kwargs, pl.defaults.latent_scatter) - scatters.append(pl.scatter(canvas, x, y, marker=m, color=Tango.nextMedium(), label=this_label, **kwargs)) - - plots = pl.show_canvas(canvas, dict(scatter=scatters, imshow=view), legend=legend, xlim=(xmin[0], xmax[0]), ylim=(xmin[1], xmax[1])) - _wait_for_updates(view, updates) - return plots \ No newline at end of file diff --git a/GPy/plotting/matplot_dep/controllers/axis_event_controller.py b/GPy/plotting/matplot_dep/controllers/axis_event_controller.py index 15fcd098..042afb59 100644 --- a/GPy/plotting/matplot_dep/controllers/axis_event_controller.py +++ b/GPy/plotting/matplot_dep/controllers/axis_event_controller.py @@ -129,13 +129,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() diff --git a/GPy/plotting/matplot_dep/controllers/imshow_controller.py b/GPy/plotting/matplot_dep/controllers/imshow_controller.py index 9d941073..093d7859 100644 --- a/GPy/plotting/matplot_dep/controllers/imshow_controller.py +++ b/GPy/plotting/matplot_dep/controllers/imshow_controller.py @@ -33,7 +33,7 @@ class ImshowController(BufferedAxisChangedController): view.set_extent((xmin, xmax, ymin, ymax)) 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) @@ -44,15 +44,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)) + 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): diff --git a/GPy/plotting/matplot_dep/defaults.py b/GPy/plotting/matplot_dep/defaults.py index 5e8d84e9..7333e450 100644 --- a/GPy/plotting/matplot_dep/defaults.py +++ b/GPy/plotting/matplot_dep/defaults.py @@ -68,6 +68,8 @@ data_y_1d_plot = dict(color='k', linewidth=1.5) ard = dict(edgecolor='k', linewidth=1.2) # Input plots: -latent = dict(aspect='auto', cmap='Greys', interpolation='bilinear') -magnification = dict(aspect='auto', cmap='Greys', interpolation='bilinear') -latent_scatter = dict(s=40, linewidth=.2, edgecolor='k', alpha=.9) \ No newline at end of file +latent = dict(aspect='auto', cmap='Greys', interpolation='bicubic') +gradient = dict(aspect='auto', cmap='RdBu', interpolation='nearest') +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) \ No newline at end of file diff --git a/GPy/plotting/matplot_dep/plot_definitions.py b/GPy/plotting/matplot_dep/plot_definitions.py index 46b67283..76e557a4 100644 --- a/GPy/plotting/matplot_dep/plot_definitions.py +++ b/GPy/plotting/matplot_dep/plot_definitions.py @@ -33,7 +33,8 @@ from ..abstract_plotting_library import AbstractPlottingLibrary from .. import Tango from . import defaults from matplotlib.colors import LinearSegmentedColormap -from .controllers import ImshowController +from .controllers import ImshowController, ImAnnotateController +import itertools class MatplotlibPlots(AbstractPlottingLibrary): def __init__(self): @@ -120,10 +121,26 @@ class MatplotlibPlots(AbstractPlottingLibrary): def imshow(self, ax, X, extent=None, label=None, plot_function=None, resolution=None, vmin=None, vmax=None, **kwargs): if plot_function is not None: - self.controller = ImshowController(ax, plot_function, extent, resolution=resolution, vmin=vmin, vmax=vmax, **kwargs) - return self.controller + return ImshowController(ax, plot_function, extent, resolution=resolution, vmin=vmin, vmax=vmax, **kwargs) return ax.imshow(X, label=label, extent=extent, vmin=vmin, vmax=vmax, **kwargs) + def annotation_heatmap(self, ax, X, annotation, extent, label=None, plot_function=None, resolution=None, imshow_kwargs=None, **annotation_kwargs): + if plot_function is not None: + return ImAnnotateController(ax, plot_function, extent, resolution=resolution, imshow_kwargs=imshow_kwargs or {}, **annotation_kwargs) + 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' + xmin, xmax, ymin, ymax = extent + self.imshow(X, extent, label, None, resolution, **imshow_kwargs or {}) + xoffset, yoffset = (xmax - xmin) / (2 * self.resolution), (ymax - ymin) / (2 * self.resolution) + xlin = np.linspace(xmin, xmax, self.resolution, endpoint=False) + ylin = np.linspace(ymin, ymax, self.resolution, endpoint=False) + annotations = [] + for [i, x], [j, y] in itertools.product(enumerate(xlin), enumerate(ylin[::-1])): + annotations.append(ax.text(x + xoffset, y + yoffset, "{}".format(annotation[j, i]), **annotation_kwargs)) + return annotations + 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) diff --git a/GPy/testing/plotting_tests.py b/GPy/testing/plotting_tests.py index 24e64ccd..9618697b 100644 --- a/GPy/testing/plotting_tests.py +++ b/GPy/testing/plotting_tests.py @@ -167,7 +167,8 @@ def test_gplvm_plot(self=None): plt.close('all') m.plot_latent() m.plot_magnification(labels=labels) - for do_test in _image_comparison(baseline_images=['gplvm_{}'.format(sub) for sub in ["latent", "magnification"]], extensions=extensions): + m.plot_steepest_gradient_map(resolution=5) + for do_test in _image_comparison(baseline_images=['gplvm_{}'.format(sub) for sub in ["latent", "magnification", 'gradient']], extensions=extensions): yield (do_test, ) if __name__ == '__main__': diff --git a/GPy/testing/plotting_tests/baseline/gplvm_gradient.png b/GPy/testing/plotting_tests/baseline/gplvm_gradient.png new file mode 100644 index 00000000..3625b673 Binary files /dev/null and b/GPy/testing/plotting_tests/baseline/gplvm_gradient.png differ diff --git a/GPy/testing/plotting_tests/baseline/gplvm_latent.png b/GPy/testing/plotting_tests/baseline/gplvm_latent.png index f8167b13..acb56fe4 100644 Binary files a/GPy/testing/plotting_tests/baseline/gplvm_latent.png and b/GPy/testing/plotting_tests/baseline/gplvm_latent.png differ diff --git a/GPy/testing/plotting_tests/baseline/gplvm_magnification.png b/GPy/testing/plotting_tests/baseline/gplvm_magnification.png index 584578a0..b2c18f4f 100644 Binary files a/GPy/testing/plotting_tests/baseline/gplvm_magnification.png and b/GPy/testing/plotting_tests/baseline/gplvm_magnification.png differ