From 901b0d25d5de931c232e97a95d005c61bfb7ec15 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Mon, 27 Jan 2014 13:17:40 +0000 Subject: [PATCH 01/26] util/plot moved to plotting directory --- GPy/{util => plotting/matplotlib}/plot.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename GPy/{util => plotting/matplotlib}/plot.py (100%) diff --git a/GPy/util/plot.py b/GPy/plotting/matplotlib/plot.py similarity index 100% rename from GPy/util/plot.py rename to GPy/plotting/matplotlib/plot.py From dfd7750d82a57a13891f93d3b737af1e56ba64fa Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:31:49 +0000 Subject: [PATCH 02/26] Relocated --- GPy/plotting/matplot_dep/Tango.py | 166 ++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 GPy/plotting/matplot_dep/Tango.py diff --git a/GPy/plotting/matplot_dep/Tango.py b/GPy/plotting/matplot_dep/Tango.py new file mode 100644 index 00000000..eeb2e075 --- /dev/null +++ b/GPy/plotting/matplot_dep/Tango.py @@ -0,0 +1,166 @@ +# Copyright (c) 2012, GPy authors (see AUTHORS.txt). +# Licensed under the BSD 3-clause license (see LICENSE.txt) + + +import matplotlib as mpl +import pylab as pb +import sys +#sys.path.append('/home/james/mlprojects/sitran_cluster/') +#from switch_pylab_backend import * + + +#this stuff isn;t really Tango related: maybe it could be moved out? TODO +def removeRightTicks(ax=None): + ax = ax or pb.gca() + for i, line in enumerate(ax.get_yticklines()): + if i%2 == 1: # odd indices + line.set_visible(False) +def removeUpperTicks(ax=None): + ax = ax or pb.gca() + for i, line in enumerate(ax.get_xticklines()): + if i%2 == 1: # odd indices + line.set_visible(False) +def fewerXticks(ax=None,divideby=2): + ax = ax or pb.gca() + ax.set_xticks(ax.get_xticks()[::divideby]) + + +colorsHex = {\ +"Aluminium6":"#2e3436",\ +"Aluminium5":"#555753",\ +"Aluminium4":"#888a85",\ +"Aluminium3":"#babdb6",\ +"Aluminium2":"#d3d7cf",\ +"Aluminium1":"#eeeeec",\ +"lightPurple":"#ad7fa8",\ +"mediumPurple":"#75507b",\ +"darkPurple":"#5c3566",\ +"lightBlue":"#729fcf",\ +"mediumBlue":"#3465a4",\ +"darkBlue": "#204a87",\ +"lightGreen":"#8ae234",\ +"mediumGreen":"#73d216",\ +"darkGreen":"#4e9a06",\ +"lightChocolate":"#e9b96e",\ +"mediumChocolate":"#c17d11",\ +"darkChocolate":"#8f5902",\ +"lightRed":"#ef2929",\ +"mediumRed":"#cc0000",\ +"darkRed":"#a40000",\ +"lightOrange":"#fcaf3e",\ +"mediumOrange":"#f57900",\ +"darkOrange":"#ce5c00",\ +"lightButter":"#fce94f",\ +"mediumButter":"#edd400",\ +"darkButter":"#c4a000"} + +darkList = [colorsHex['darkBlue'],colorsHex['darkRed'],colorsHex['darkGreen'], colorsHex['darkOrange'], colorsHex['darkButter'], colorsHex['darkPurple'], colorsHex['darkChocolate'], colorsHex['Aluminium6']] +mediumList = [colorsHex['mediumBlue'], colorsHex['mediumRed'],colorsHex['mediumGreen'], colorsHex['mediumOrange'], colorsHex['mediumButter'], colorsHex['mediumPurple'], colorsHex['mediumChocolate'], colorsHex['Aluminium5']] +lightList = [colorsHex['lightBlue'], colorsHex['lightRed'],colorsHex['lightGreen'], colorsHex['lightOrange'], colorsHex['lightButter'], colorsHex['lightPurple'], colorsHex['lightChocolate'], colorsHex['Aluminium4']] + +def currentDark(): + return darkList[-1] +def currentMedium(): + return mediumList[-1] +def currentLight(): + return lightList[-1] + +def nextDark(): + darkList.append(darkList.pop(0)) + return darkList[-1] +def nextMedium(): + mediumList.append(mediumList.pop(0)) + return mediumList[-1] +def nextLight(): + lightList.append(lightList.pop(0)) + return lightList[-1] + +def reset(): + while not darkList[0]==colorsHex['darkBlue']: + darkList.append(darkList.pop(0)) + while not mediumList[0]==colorsHex['mediumBlue']: + mediumList.append(mediumList.pop(0)) + while not lightList[0]==colorsHex['lightBlue']: + lightList.append(lightList.pop(0)) + +def setLightFigures(): + mpl.rcParams['axes.edgecolor']=colorsHex['Aluminium6'] + mpl.rcParams['axes.facecolor']=colorsHex['Aluminium2'] + mpl.rcParams['axes.labelcolor']=colorsHex['Aluminium6'] + mpl.rcParams['figure.edgecolor']=colorsHex['Aluminium6'] + mpl.rcParams['figure.facecolor']=colorsHex['Aluminium2'] + mpl.rcParams['grid.color']=colorsHex['Aluminium6'] + mpl.rcParams['savefig.edgecolor']=colorsHex['Aluminium2'] + mpl.rcParams['savefig.facecolor']=colorsHex['Aluminium2'] + mpl.rcParams['text.color']=colorsHex['Aluminium6'] + mpl.rcParams['xtick.color']=colorsHex['Aluminium6'] + mpl.rcParams['ytick.color']=colorsHex['Aluminium6'] + +def setDarkFigures(): + mpl.rcParams['axes.edgecolor']=colorsHex['Aluminium2'] + mpl.rcParams['axes.facecolor']=colorsHex['Aluminium6'] + mpl.rcParams['axes.labelcolor']=colorsHex['Aluminium2'] + mpl.rcParams['figure.edgecolor']=colorsHex['Aluminium2'] + mpl.rcParams['figure.facecolor']=colorsHex['Aluminium6'] + mpl.rcParams['grid.color']=colorsHex['Aluminium2'] + mpl.rcParams['savefig.edgecolor']=colorsHex['Aluminium6'] + mpl.rcParams['savefig.facecolor']=colorsHex['Aluminium6'] + mpl.rcParams['text.color']=colorsHex['Aluminium2'] + mpl.rcParams['xtick.color']=colorsHex['Aluminium2'] + mpl.rcParams['ytick.color']=colorsHex['Aluminium2'] + +def hex2rgb(hexcolor): + hexcolor = [hexcolor[1+2*i:1+2*(i+1)] for i in range(3)] + r,g,b = [int(n,16) for n in hexcolor] + return (r,g,b) + +colorsRGB = dict([(k,hex2rgb(i)) for k,i in colorsHex.items()]) + +cdict_RB = {'red' :((0.,colorsRGB['mediumRed'][0]/256.,colorsRGB['mediumRed'][0]/256.), + (.5,colorsRGB['mediumPurple'][0]/256.,colorsRGB['mediumPurple'][0]/256.), + (1.,colorsRGB['mediumBlue'][0]/256.,colorsRGB['mediumBlue'][0]/256.)), + 'green':((0.,colorsRGB['mediumRed'][1]/256.,colorsRGB['mediumRed'][1]/256.), + (.5,colorsRGB['mediumPurple'][1]/256.,colorsRGB['mediumPurple'][1]/256.), + (1.,colorsRGB['mediumBlue'][1]/256.,colorsRGB['mediumBlue'][1]/256.)), + 'blue':((0.,colorsRGB['mediumRed'][2]/256.,colorsRGB['mediumRed'][2]/256.), + (.5,colorsRGB['mediumPurple'][2]/256.,colorsRGB['mediumPurple'][2]/256.), + (1.,colorsRGB['mediumBlue'][2]/256.,colorsRGB['mediumBlue'][2]/256.))} + +cdict_BGR = {'red' :((0.,colorsRGB['mediumBlue'][0]/256.,colorsRGB['mediumBlue'][0]/256.), + (.5,colorsRGB['mediumGreen'][0]/256.,colorsRGB['mediumGreen'][0]/256.), + (1.,colorsRGB['mediumRed'][0]/256.,colorsRGB['mediumRed'][0]/256.)), + 'green':((0.,colorsRGB['mediumBlue'][1]/256.,colorsRGB['mediumBlue'][1]/256.), + (.5,colorsRGB['mediumGreen'][1]/256.,colorsRGB['mediumGreen'][1]/256.), + (1.,colorsRGB['mediumRed'][1]/256.,colorsRGB['mediumRed'][1]/256.)), + 'blue':((0.,colorsRGB['mediumBlue'][2]/256.,colorsRGB['mediumBlue'][2]/256.), + (.5,colorsRGB['mediumGreen'][2]/256.,colorsRGB['mediumGreen'][2]/256.), + (1.,colorsRGB['mediumRed'][2]/256.,colorsRGB['mediumRed'][2]/256.))} + + +cdict_Alu = {'red' :((0./5,colorsRGB['Aluminium1'][0]/256.,colorsRGB['Aluminium1'][0]/256.), + (1./5,colorsRGB['Aluminium2'][0]/256.,colorsRGB['Aluminium2'][0]/256.), + (2./5,colorsRGB['Aluminium3'][0]/256.,colorsRGB['Aluminium3'][0]/256.), + (3./5,colorsRGB['Aluminium4'][0]/256.,colorsRGB['Aluminium4'][0]/256.), + (4./5,colorsRGB['Aluminium5'][0]/256.,colorsRGB['Aluminium5'][0]/256.), + (5./5,colorsRGB['Aluminium6'][0]/256.,colorsRGB['Aluminium6'][0]/256.)), + 'green' :((0./5,colorsRGB['Aluminium1'][1]/256.,colorsRGB['Aluminium1'][1]/256.), + (1./5,colorsRGB['Aluminium2'][1]/256.,colorsRGB['Aluminium2'][1]/256.), + (2./5,colorsRGB['Aluminium3'][1]/256.,colorsRGB['Aluminium3'][1]/256.), + (3./5,colorsRGB['Aluminium4'][1]/256.,colorsRGB['Aluminium4'][1]/256.), + (4./5,colorsRGB['Aluminium5'][1]/256.,colorsRGB['Aluminium5'][1]/256.), + (5./5,colorsRGB['Aluminium6'][1]/256.,colorsRGB['Aluminium6'][1]/256.)), + 'blue' :((0./5,colorsRGB['Aluminium1'][2]/256.,colorsRGB['Aluminium1'][2]/256.), + (1./5,colorsRGB['Aluminium2'][2]/256.,colorsRGB['Aluminium2'][2]/256.), + (2./5,colorsRGB['Aluminium3'][2]/256.,colorsRGB['Aluminium3'][2]/256.), + (3./5,colorsRGB['Aluminium4'][2]/256.,colorsRGB['Aluminium4'][2]/256.), + (4./5,colorsRGB['Aluminium5'][2]/256.,colorsRGB['Aluminium5'][2]/256.), + (5./5,colorsRGB['Aluminium6'][2]/256.,colorsRGB['Aluminium6'][2]/256.))} +# cmap_Alu = mpl.colors.LinearSegmentedColormap('TangoAluminium',cdict_Alu,256) +# cmap_BGR = mpl.colors.LinearSegmentedColormap('TangoRedBlue',cdict_BGR,256) +# cmap_RB = mpl.colors.LinearSegmentedColormap('TangoRedBlue',cdict_RB,256) +if __name__=='__main__': + import pylab as pb + pb.figure() + pb.pcolor(pb.rand(10,10),cmap=cmap_RB) + pb.colorbar() + pb.show() From ad6ff8929c983f394fa47c55c98bd2ee94227efd Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:31:59 +0000 Subject: [PATCH 03/26] Relocated and renamed --- GPy/plotting/matplot_dep/base_plots.py | 135 +++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 GPy/plotting/matplot_dep/base_plots.py diff --git a/GPy/plotting/matplot_dep/base_plots.py b/GPy/plotting/matplot_dep/base_plots.py new file mode 100644 index 00000000..f44864f3 --- /dev/null +++ b/GPy/plotting/matplot_dep/base_plots.py @@ -0,0 +1,135 @@ +# #Copyright (c) 2012, GPy authors (see AUTHORS.txt). +# Licensed under the BSD 3-clause license (see LICENSE.txt) + + +import Tango +import pylab as pb +import numpy as np + +def gpplot(x,mu,lower,upper,edgecol=Tango.colorsHex['darkBlue'],fillcol=Tango.colorsHex['lightBlue'],axes=None,**kwargs): + if axes is None: + axes = pb.gca() + mu = mu.flatten() + x = x.flatten() + lower = lower.flatten() + upper = upper.flatten() + + #here's the mean + axes.plot(x,mu,color=edgecol,linewidth=2) + + #here's the box + kwargs['linewidth']=0.5 + if not 'alpha' in kwargs.keys(): + kwargs['alpha'] = 0.3 + axes.fill(np.hstack((x,x[::-1])),np.hstack((upper,lower[::-1])),color=fillcol,**kwargs) + + #this is the edge: + axes.plot(x,upper,color=edgecol,linewidth=0.2) + axes.plot(x,lower,color=edgecol,linewidth=0.2) + +def removeRightTicks(ax=None): + ax = ax or pb.gca() + for i, line in enumerate(ax.get_yticklines()): + if i%2 == 1: # odd indices + line.set_visible(False) +def removeUpperTicks(ax=None): + ax = ax or pb.gca() + for i, line in enumerate(ax.get_xticklines()): + if i%2 == 1: # odd indices + line.set_visible(False) +def fewerXticks(ax=None,divideby=2): + ax = ax or pb.gca() + ax.set_xticks(ax.get_xticks()[::divideby]) + +def align_subplots(N,M,xlim=None, ylim=None): + """make all of the subplots have the same limits, turn off unnecessary ticks""" + #find sensible xlim,ylim + if xlim is None: + xlim = [np.inf,-np.inf] + for i in range(N*M): + pb.subplot(N,M,i+1) + xlim[0] = min(xlim[0],pb.xlim()[0]) + xlim[1] = max(xlim[1],pb.xlim()[1]) + if ylim is None: + ylim = [np.inf,-np.inf] + for i in range(N*M): + pb.subplot(N,M,i+1) + ylim[0] = min(ylim[0],pb.ylim()[0]) + ylim[1] = max(ylim[1],pb.ylim()[1]) + + for i in range(N*M): + pb.subplot(N,M,i+1) + pb.xlim(xlim) + pb.ylim(ylim) + if (i)%M: + pb.yticks([]) + else: + removeRightTicks() + if i<(M*(N-1)): + pb.xticks([]) + else: + removeUpperTicks() + +def align_subplot_array(axes,xlim=None, ylim=None): + """make all of the axes in the array hae the same limits, turn off unnecessary ticks + + use pb.subplots() to get an array of axes + """ + #find sensible xlim,ylim + if xlim is None: + xlim = [np.inf,-np.inf] + for ax in axes.flatten(): + xlim[0] = min(xlim[0],ax.get_xlim()[0]) + xlim[1] = max(xlim[1],ax.get_xlim()[1]) + if ylim is None: + ylim = [np.inf,-np.inf] + for ax in axes.flatten(): + ylim[0] = min(ylim[0],ax.get_ylim()[0]) + ylim[1] = max(ylim[1],ax.get_ylim()[1]) + + N,M = axes.shape + for i,ax in enumerate(axes.flatten()): + ax.set_xlim(xlim) + ax.set_ylim(ylim) + if (i)%M: + ax.set_yticks([]) + else: + removeRightTicks(ax) + if i<(M*(N-1)): + ax.set_xticks([]) + else: + removeUpperTicks(ax) + +def x_frame1D(X,plot_limits=None,resolution=None): + """ + Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits + """ + assert X.shape[1] ==1, "x_frame1D is defined for one-dimensional inputs" + if plot_limits is None: + xmin,xmax = X.min(0),X.max(0) + xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin) + elif len(plot_limits)==2: + xmin, xmax = plot_limits + else: + raise ValueError, "Bad limits for plotting" + + Xnew = np.linspace(xmin,xmax,resolution or 200)[:,None] + return Xnew, xmin, xmax + +def x_frame2D(X,plot_limits=None,resolution=None): + """ + Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits + """ + assert X.shape[1] ==2, "x_frame2D is defined for two-dimensional inputs" + if plot_limits is None: + xmin,xmax = X.min(0),X.max(0) + xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin) + elif len(plot_limits)==2: + xmin, xmax = plot_limits + else: + raise ValueError, "Bad limits for plotting" + + resolution = resolution or 50 + xx,yy = np.mgrid[xmin[0]:xmax[0]:1j*resolution,xmin[1]:xmax[1]:1j*resolution] + Xnew = np.vstack((xx.flatten(),yy.flatten())).T + return Xnew, xx, yy, xmin, xmax From 69303e215c869044844dbaa6c5787cb8bc72a6b5 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:32:27 +0000 Subject: [PATCH 04/26] Relocated and renamed --- .../matplot_dep/dim_reduction_plots.py | 248 ++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 GPy/plotting/matplot_dep/dim_reduction_plots.py diff --git a/GPy/plotting/matplot_dep/dim_reduction_plots.py b/GPy/plotting/matplot_dep/dim_reduction_plots.py new file mode 100644 index 00000000..74292c05 --- /dev/null +++ b/GPy/plotting/matplot_dep/dim_reduction_plots.py @@ -0,0 +1,248 @@ +import pylab as pb +import numpy as np +from ... import util +from latent_space_visualizations.controllers.imshow_controller import ImshowController,ImAnnotateController +from GPy.util.misc import param_to_array +import itertools +import Tango +from matplotlib.cm import get_cmap + +def most_significant_input_dimensions(model, which_indices): + """ + Determine which dimensions should be plotted + """ + if which_indices is None: + if model.input_dim == 1: + input_1 = 0 + input_2 = None + if model.input_dim == 2: + input_1, input_2 = 0, 1 + else: + try: + input_1, input_2 = np.argsort(model.input_sensitivity())[::-1][:2] + except: + raise ValueError, "cannot automatically determine which dimensions to plot, please pass 'which_indices'" + else: + input_1, input_2 = which_indices + return input_1, input_2 + +def plot_latent(model, labels=None, which_indices=None, + resolution=50, ax=None, marker='o', s=40, + fignum=None, plot_inducing=False, legend=True, + aspect='auto', updates=False): + """ + :param labels: a np.array of size model.num_data containing labels for the points (can be number, strings, etc) + :param resolution: the resolution of the grid on which to evaluate the predictive variance + """ + if ax is None: + fig = pb.figure(num=fignum) + ax = fig.add_subplot(111) + util.plot.Tango.reset() + + if labels is None: + labels = np.ones(model.num_data) + + input_1, input_2 = most_significant_input_dimensions(model, which_indices) + X = param_to_array(model.X) + + # first, plot the output variance as a function of the latent space + Xtest, xx, yy, xmin, xmax = util.plot.x_frame2D(X[:, [input_1, input_2]], resolution=resolution) + Xtest_full = np.zeros((Xtest.shape[0], model.X.shape[1])) + + def plot_function(x): + Xtest_full[:, [input_1, input_2]] = x + mu, var, low, up = model.predict(Xtest_full) + var = var[:, :1] + return np.log(var) + + view = ImshowController(ax, plot_function, + tuple(X[:, [input_1, input_2]].min(0)) + tuple(X[:, [input_1, input_2]].max(0)), + resolution, aspect=aspect, interpolation='bilinear', + cmap=pb.cm.binary) + +# ax.imshow(var.reshape(resolution, resolution).T, +# extent=[xmin[0], xmax[0], xmin[1], xmax[1]], cmap=pb.cm.binary, interpolation='bilinear', origin='lower') + + # make sure labels are in order of input: + ulabels = [] + for lab in labels: + if not lab in ulabels: + ulabels.append(lab) + + marker = itertools.cycle(list(marker)) + + for i, ul in enumerate(ulabels): + if type(ul) is np.string_: + this_label = ul + elif type(ul) is np.int64: + this_label = 'class %i' % ul + else: + this_label = 'class %i' % i + m = marker.next() + + index = np.nonzero(labels == ul)[0] + if model.input_dim == 1: + x = X[index, input_1] + y = np.zeros(index.size) + else: + x = X[index, input_1] + y = X[index, input_2] + ax.scatter(x, y, marker=m, s=s, color=util.plot.Tango.nextMedium(), label=this_label) + + ax.set_xlabel('latent dimension %i' % input_1) + ax.set_ylabel('latent dimension %i' % input_2) + + if not np.all(labels == 1.) and legend: + ax.legend(loc=0, numpoints=1) + + ax.set_xlim(xmin[0], xmax[0]) + ax.set_ylim(xmin[1], xmax[1]) + ax.grid(b=False) # remove the grid if present, it doesn't look good + ax.set_aspect('auto') # set a nice aspect ratio + + if plot_inducing: + Z = param_to_array(model.Z) + ax.plot(Z[:, input_1], Z[:, input_2], '^w') + + if updates: + ax.figure.canvas.show() + raw_input('Enter to continue') + return ax + +def plot_magnification(model, labels=None, which_indices=None, + resolution=60, ax=None, marker='o', s=40, + fignum=None, plot_inducing=False, legend=True, + aspect='auto', updates=False): + """ + :param labels: a np.array of size model.num_data containing labels for the points (can be number, strings, etc) + :param resolution: the resolution of the grid on which to evaluate the predictive variance + """ + if ax is None: + fig = pb.figure(num=fignum) + ax = fig.add_subplot(111) + util.plot.Tango.reset() + + if labels is None: + labels = np.ones(model.num_data) + + input_1, input_2 = most_significant_input_dimensions(model, which_indices) + + # first, plot the output variance as a function of the latent space + Xtest, xx, yy, xmin, xmax = util.plot.x_frame2D(model.X[:, [input_1, input_2]], resolution=resolution) + Xtest_full = np.zeros((Xtest.shape[0], model.X.shape[1])) + + def plot_function(x): + Xtest_full[:, [input_1, input_2]] = x + mf=model.magnification(Xtest_full) + return mf + + view = ImshowController(ax, plot_function, + tuple(model.X.min(0)[:, [input_1, input_2]]) + tuple(model.X.max(0)[:, [input_1, input_2]]), + resolution, aspect=aspect, interpolation='bilinear', + cmap=pb.cm.gray) + + # make sure labels are in order of input: + ulabels = [] + for lab in labels: + if not lab in ulabels: + ulabels.append(lab) + + marker = itertools.cycle(list(marker)) + + for i, ul in enumerate(ulabels): + if type(ul) is np.string_: + this_label = ul + elif type(ul) is np.int64: + this_label = 'class %i' % ul + else: + this_label = 'class %i' % i + m = marker.next() + + index = np.nonzero(labels == ul)[0] + if model.input_dim == 1: + x = model.X[index, input_1] + y = np.zeros(index.size) + else: + x = model.X[index, input_1] + y = model.X[index, input_2] + ax.scatter(x, y, marker=m, s=s, color=util.plot.Tango.nextMedium(), label=this_label) + + ax.set_xlabel('latent dimension %i' % input_1) + ax.set_ylabel('latent dimension %i' % input_2) + + if not np.all(labels == 1.) and legend: + ax.legend(loc=0, numpoints=1) + + ax.set_xlim(xmin[0], xmax[0]) + ax.set_ylim(xmin[1], xmax[1]) + ax.grid(b=False) # remove the grid if present, it doesn't look good + ax.set_aspect('auto') # set a nice aspect ratio + + if plot_inducing: + ax.plot(model.Z[:, input_1], model.Z[:, input_2], '^w') + + if updates: + ax.figure.canvas.show() + raw_input('Enter to continue') + + pb.title('Magnification Factor') + return ax + + +def plot_steepest_gradient_map(model, fignum=None, ax=None, which_indices=None, labels=None, data_labels=None, data_marker='o', data_s=40, resolution=20, aspect='auto', updates=False, ** kwargs): + + input_1, input_2 = significant_dims = most_significant_input_dimensions(model, which_indices) + + X = np.zeros((resolution ** 2, model.input_dim)) + indices = np.r_[:X.shape[0]] + if labels is None: + labels = range(model.output_dim) + + def plot_function(x): + X[:, significant_dims] = x + dmu_dX = model.dmu_dXnew(X) + argmax = np.argmax(dmu_dX, 1) + return dmu_dX[indices, argmax], np.array(labels)[argmax] + + if ax is None: + fig = pyplot.figure(num=fignum) + ax = fig.add_subplot(111) + + if data_labels is None: + data_labels = np.ones(model.num_data) + ulabels = [] + for lab in data_labels: + if not lab in ulabels: + ulabels.append(lab) + marker = itertools.cycle(list(data_marker)) + for i, ul in enumerate(ulabels): + if type(ul) is np.string_: + this_label = ul + elif type(ul) is np.int64: + this_label = 'class %i' % ul + else: + this_label = 'class %i' % i + m = marker.next() + index = np.nonzero(data_labels == ul)[0] + x = model.X[index, input_1] + y = model.X[index, input_2] + ax.scatter(x, y, marker=m, s=data_s, color=Tango.nextMedium(), label=this_label) + + ax.set_xlabel('latent dimension %i' % input_1) + ax.set_ylabel('latent dimension %i' % input_2) + + controller = ImAnnotateController(ax, + plot_function, + tuple(model.X.min(0)[:, significant_dims]) + tuple(model.X.max(0)[:, significant_dims]), + resolution=resolution, + aspect=aspect, + cmap=get_cmap('jet'), + **kwargs) + ax.legend() + ax.figure.tight_layout() + if updates: + pyplot.show() + clear = raw_input('Enter to continue') + if clear.lower() in 'yes' or clear == '': + controller.deactivate() + return controller.view From da97207ff5b0b57f9fc7992427e5417568c63ece Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:33:03 +0000 Subject: [PATCH 05/26] Relocated --- GPy/plotting/matplot_dep/latent_space_visualizations/__init__.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 GPy/plotting/matplot_dep/latent_space_visualizations/__init__.py diff --git a/GPy/plotting/matplot_dep/latent_space_visualizations/__init__.py b/GPy/plotting/matplot_dep/latent_space_visualizations/__init__.py new file mode 100644 index 00000000..ee595945 --- /dev/null +++ b/GPy/plotting/matplot_dep/latent_space_visualizations/__init__.py @@ -0,0 +1 @@ +import controllers From 1c922a830f56ee0dbb8bdbf27f182aeaeb5917b8 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:33:20 +0000 Subject: [PATCH 06/26] Relocated --- .../latent_space_visualizations/controllers/__init__.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 GPy/plotting/matplot_dep/latent_space_visualizations/controllers/__init__.py diff --git a/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/__init__.py b/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/__init__.py new file mode 100644 index 00000000..25f6535e --- /dev/null +++ b/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/__init__.py @@ -0,0 +1 @@ +import axis_event_controller, imshow_controller From 960ebeb32f38ed512a46169d44e5333422a0c616 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:33:33 +0000 Subject: [PATCH 07/26] Relocated --- .../controllers/axis_event_controller.py | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 GPy/plotting/matplot_dep/latent_space_visualizations/controllers/axis_event_controller.py diff --git a/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/axis_event_controller.py b/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/axis_event_controller.py new file mode 100644 index 00000000..d5aaefd2 --- /dev/null +++ b/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/axis_event_controller.py @@ -0,0 +1,139 @@ +''' +Created on 24 Jul 2013 + +@author: maxz +''' +import numpy + +class AxisEventController(object): + def __init__(self, ax): + self.ax = ax + self.activate() + def deactivate(self): + for cb_class in self.ax.callbacks.callbacks.values(): + for cb_num in cb_class.keys(): + self.ax.callbacks.disconnect(cb_num) + def activate(self): + self.ax.callbacks.connect('xlim_changed', self.xlim_changed) + self.ax.callbacks.connect('ylim_changed', self.ylim_changed) + def xlim_changed(self, ax): + pass + def ylim_changed(self, ax): + pass + + +class AxisChangedController(AxisEventController): + ''' + Buffered control of axis limit changes + ''' + _changing = False + + def __init__(self, ax, update_lim=None): + ''' + Constructor + ''' + super(AxisChangedController, self).__init__(ax) + self._lim_ratio_threshold = update_lim or .8 + self._x_lim = self.ax.get_xlim() + self._y_lim = self.ax.get_ylim() + + def update(self, ax): + pass + + def xlim_changed(self, ax): + super(AxisChangedController, self).xlim_changed(ax) + if not self._changing and self.lim_changed(ax.get_xlim(), self._x_lim): + self._changing = True + self._x_lim = ax.get_xlim() + self.update(ax) + self._changing = False + + def ylim_changed(self, ax): + super(AxisChangedController, self).ylim_changed(ax) + if not self._changing and self.lim_changed(ax.get_ylim(), self._y_lim): + self._changing = True + self._y_lim = ax.get_ylim() + self.update(ax) + self._changing = False + + def extent(self, lim): + return numpy.subtract(*lim) + + def lim_changed(self, axlim, savedlim): + axextent = self.extent(axlim) + extent = self.extent(savedlim) + lim_changed = ((axextent / extent) < self._lim_ratio_threshold ** 2 + or (extent / axextent) < self._lim_ratio_threshold ** 2 + or ((1 - (self.extent((axlim[0], savedlim[0])) / self.extent((savedlim[0], axlim[1])))) + < self._lim_ratio_threshold) + or ((1 - (self.extent((savedlim[0], axlim[0])) / self.extent((axlim[0], savedlim[1])))) + < self._lim_ratio_threshold) + ) + return lim_changed + + def _buffer_lim(self, lim): + # buffer_size = 1 - self._lim_ratio_threshold + # extent = self.extent(lim) + return lim + + +class BufferedAxisChangedController(AxisChangedController): + def __init__(self, ax, plot_function, plot_limits, resolution=50, update_lim=None, **kwargs): + """ + :param plot_function: + function to use for creating image for plotting (return ndarray-like) + plot_function gets called with (2D!) Xtest grid if replotting required + :type plot_function: function + :param plot_limits: + beginning plot limits [xmin, ymin, xmax, ymax] + + :param kwargs: additional kwargs are for pyplot.imshow(**kwargs) + """ + super(BufferedAxisChangedController, self).__init__(ax, update_lim=update_lim) + self.plot_function = plot_function + xmin, xmax = self._x_lim # self._compute_buffered(*self._x_lim) + ymin, ymax = self._y_lim # self._compute_buffered(*self._y_lim) + self.resolution = resolution + self._not_init = False + self.view = self._init_view(self.ax, self.recompute_X(), xmin, xmax, ymin, ymax, **kwargs) + self._not_init = True + + def update(self, ax): + super(BufferedAxisChangedController, self).update(ax) + if self._not_init: + xmin, xmax = self._compute_buffered(*self._x_lim) + ymin, ymax = self._compute_buffered(*self._y_lim) + self.update_view(self.view, self.recompute_X(), xmin, xmax, ymin, ymax) + + def _init_view(self, ax, X, xmin, xmax, ymin, ymax): + raise NotImplementedError('return view for this controller') + + def update_view(self, view, X, xmin, xmax, ymin, ymax): + raise NotImplementedError('update view given in here') + + def get_grid(self): + xmin, xmax = self._compute_buffered(*self._x_lim) + ymin, ymax = self._compute_buffered(*self._y_lim) + x, y = numpy.mgrid[xmin:xmax:1j * self.resolution, ymin:ymax:1j * self.resolution] + return numpy.hstack((x.flatten()[:, None], y.flatten()[:, None])) + + def recompute_X(self): + X = self.plot_function(self.get_grid()) + 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, :] + + def _compute_buffered(self, mi, ma): + buffersize = self._buffersize() + size = ma - mi + return mi - (buffersize * size), ma + (buffersize * size) + + def _buffersize(self): + try: + buffersize = 1. - self._lim_ratio_threshold + except: + buffersize = .4 + return buffersize From 472473993db42dd611765ae0439228503003aa0b Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:33:44 +0000 Subject: [PATCH 08/26] Relocated --- .../controllers/imshow_controller.py | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 GPy/plotting/matplot_dep/latent_space_visualizations/controllers/imshow_controller.py diff --git a/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/imshow_controller.py b/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/imshow_controller.py new file mode 100644 index 00000000..b473dd96 --- /dev/null +++ b/GPy/plotting/matplot_dep/latent_space_visualizations/controllers/imshow_controller.py @@ -0,0 +1,71 @@ +''' +Created on 24 Jul 2013 + +@author: maxz +''' +from axis_event_controller import BufferedAxisChangedController +import itertools +import numpy + + +class ImshowController(BufferedAxisChangedController): + def __init__(self, ax, plot_function, plot_limits, resolution=50, update_lim=.5, **kwargs): + """ + :param plot_function: + function to use for creating image for plotting (return ndarray-like) + plot_function gets called with (2D!) Xtest grid if replotting required + :type plot_function: function + :param plot_limits: + beginning plot limits [xmin, ymin, xmax, ymax] + + :param kwargs: additional kwargs are for pyplot.imshow(**kwargs) + """ + super(ImshowController, self).__init__(ax, plot_function, plot_limits, resolution, update_lim, **kwargs) + + def _init_view(self, ax, X, xmin, xmax, ymin, ymax, **kwargs): + return ax.imshow(X, extent=(xmin, xmax, + ymin, ymax), + vmin=X.min(), + vmax=X.max(), + **kwargs) + + def update_view(self, view, X, xmin, xmax, ymin, ymax): + view.set_data(X) + view.set_extent((xmin, xmax, ymin, ymax)) + +class ImAnnotateController(ImshowController): + def __init__(self, ax, plot_function, plot_limits, resolution=20, update_lim=.99, **kwargs): + """ + :param plot_function: + function to use for creating image for plotting (return ndarray-like) + plot_function gets called with (2D!) Xtest grid if replotting required + :type plot_function: function + :param plot_limits: + beginning plot limits [xmin, ymin, xmax, ymax] + :param text_props: kwargs for pyplot.text(**text_props) + :param kwargs: additional kwargs are for pyplot.imshow(**kwargs) + """ + 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)] + 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)) + return view + + def update_view(self, view, X, xmin, xmax, ymin, ymax): + super(ImAnnotateController, self).update_view(view[0], X[0], xmin, xmax, ymin, ymax) + 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]], text in itertools.izip(itertools.product(enumerate(xlin), enumerate(ylin[::-1])), view[1:]): + text.set_x(x + xoffset) + text.set_y(y + yoffset) + text.set_text("{}".format(X[1][j, i])) + return view + + def _offsets(self, xmin, xmax, ymin, ymax): + return (xmax - xmin) / (2 * self.resolution), (ymax - ymin) / (2 * self.resolution) From 8e3194c8b05210f4962fae9c20947f7960ea42f2 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:34:11 +0000 Subject: [PATCH 09/26] Relocated --- GPy/plotting/matplot_dep/maps.py | 161 +++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 GPy/plotting/matplot_dep/maps.py diff --git a/GPy/plotting/matplot_dep/maps.py b/GPy/plotting/matplot_dep/maps.py new file mode 100644 index 00000000..e18c7e68 --- /dev/null +++ b/GPy/plotting/matplot_dep/maps.py @@ -0,0 +1,161 @@ +import numpy as np +import pylab as pb +import matplotlib.patches as patches +from matplotlib.patches import Polygon +from matplotlib.collections import PatchCollection +#from matplotlib import cm +import shapefile +import re + +pb.ion() + +def plot(shape_records,facecolor='w',edgecolor='k',linewidths=.5, ax=None,xlims=None,ylims=None): + """ + Plot the geometry of a shapefile + + :param shape_records: geometry and attributes list + :type shape_records: ShapeRecord object (output of a shapeRecords() method) + :param facecolor: color to be used to fill in polygons + :param edgecolor: color to be used for lines + :param ax: axes to plot on. + :type ax: axes handle + """ + #Axes handle + if ax is None: + fig = pb.figure() + ax = fig.add_subplot(111) + + #Iterate over shape_records + for srec in shape_records: + points = np.vstack(srec.shape.points) + sparts = srec.shape.parts + par = list(sparts) + [points.shape[0]] + + polygs = [] + for pj in xrange(len(sparts)): + polygs.append(Polygon(points[par[pj]:par[pj+1]])) + ax.add_collection(PatchCollection(polygs,facecolor=facecolor,edgecolor=edgecolor, linewidths=linewidths)) + + #Plot limits + _box = np.vstack([srec.shape.bbox for srec in shape_records]) + minx,miny = np.min(_box[:,:2],0) + maxx,maxy = np.max(_box[:,2:],0) + + if xlims is not None: + minx,maxx = xlims + if ylims is not None: + miny,maxy = ylims + ax.set_xlim(minx,maxx) + ax.set_ylim(miny,maxy) + + +def string_match(sf,regex,field=2): + """ + Return the geometry and attributes of a shapefile whose fields match a regular expression given + + :param sf: shapefile + :type sf: shapefile object + :regex: regular expression to match + :type regex: string + :field: field number to be matched with the regex + :type field: integer + """ + index = [] + shape_records = [] + for rec in enumerate(sf.shapeRecords()): + m = re.search(regex,rec[1].record[field]) + if m is not None: + index.append(rec[0]) + shape_records.append(rec[1]) + return index,shape_records + +def bbox_match(sf,bbox,inside_only=True): + """ + Return the geometry and attributes of a shapefile that lie within (or intersect) a bounding box + + :param sf: shapefile + :type sf: shapefile object + :param bbox: bounding box + :type bbox: list of floats [x_min,y_min,x_max,y_max] + :inside_only: True if the objects returned are those that lie within the bbox and False if the objects returned are any that intersect the bbox + :type inside_only: Boolean + """ + A,B,C,D = bbox + index = [] + shape_records = [] + for rec in enumerate(sf.shapeRecords()): + a,b,c,d = rec[1].shape.bbox + if inside_only: + if A <= a and B <= b and C >= c and D >= d: + index.append(rec[0]) + shape_records.append(rec[1]) + else: + cond1 = A <= a and B <= b and C >= a and D >= b + cond2 = A <= c and B <= d and C >= c and D >= d + cond3 = A <= a and D >= d and C >= a and B <= d + cond4 = A <= c and D >= b and C >= c and B <= b + cond5 = a <= C and b <= B and d >= D + cond6 = c <= A and b <= B and d >= D + cond7 = d <= B and a <= A and c >= C + cond8 = b <= D and a <= A and c >= C + if cond1 or cond2 or cond3 or cond4 or cond5 or cond6 or cond7 or cond8: + index.append(rec[0]) + shape_records.append(rec[1]) + return index,shape_records + + +def plot_bbox(sf,bbox,inside_only=True): + """ + Plot the geometry of a shapefile within a bbox + + :param sf: shapefile + :type sf: shapefile object + :param bbox: bounding box + :type bbox: list of floats [x_min,y_min,x_max,y_max] + :inside_only: True if the objects returned are those that lie within the bbox and False if the objects returned are any that intersect the bbox + :type inside_only: Boolean + """ + index,shape_records = bbox_match(sf,bbox,inside_only) + A,B,C,D = bbox + plot(shape_records,xlims=[bbox[0],bbox[2]],ylims=[bbox[1],bbox[3]]) + +def plot_string_match(sf,regex,field): + """ + Plot the geometry of a shapefile whose fields match a regular expression given + + :param sf: shapefile + :type sf: shapefile object + :regex: regular expression to match + :type regex: string + :field: field number to be matched with the regex + :type field: integer + """ + index,shape_records = string_match(sf,regex,field) + plot(shape_records) + + +def new_shape_string(sf,name,regex,field=2,type=shapefile.POINT): + + newshp = shapefile.Writer(shapeType = sf.shapeType) + newshp.autoBalance = 1 + + index,shape_records = string_match(sf,regex,field) + + _fi = [sf.fields[j] for j in index] + for f in _fi: + newshp.field(name=f[0],fieldType=f[1],size=f[2],decimal=f[3]) + + _shre = shape_records + for sr in _shre: + _points = [] + _parts = [] + for point in sr.shape.points: + _points.append(point) + _parts.append(_points) + + newshp.line(parts=_parts) + newshp.records.append(sr.record) + print len(sr.record) + + newshp.save(name) + print index From 838e6822d8dcfa62011f0ff11bbae2a83d0c8bcc Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:34:20 +0000 Subject: [PATCH 10/26] Relocated --- GPy/plotting/matplot_dep/netpbmfile.py | 331 +++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 GPy/plotting/matplot_dep/netpbmfile.py diff --git a/GPy/plotting/matplot_dep/netpbmfile.py b/GPy/plotting/matplot_dep/netpbmfile.py new file mode 100644 index 00000000..030bd574 --- /dev/null +++ b/GPy/plotting/matplot_dep/netpbmfile.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# netpbmfile.py + +# Copyright (c) 2011-2013, Christoph Gohlke +# Copyright (c) 2011-2013, The Regents of the University of California +# Produced at the Laboratory for Fluorescence Dynamics. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the copyright holders nor the names of any +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +"""Read and write image data from respectively to Netpbm files. + +This implementation follows the Netpbm format specifications at +http://netpbm.sourceforge.net/doc/. No gamma correction is performed. + +The following image formats are supported: PBM (bi-level), PGM (grayscale), +PPM (color), PAM (arbitrary), XV thumbnail (RGB332, read-only). + +:Author: + `Christoph Gohlke `_ + +:Organization: + Laboratory for Fluorescence Dynamics, University of California, Irvine + +:Version: 2013.01.18 + +Requirements +------------ +* `CPython 2.7, 3.2 or 3.3 `_ +* `Numpy 1.7 `_ +* `Matplotlib 1.2 `_ (optional for plotting) + +Examples +-------- +>>> im1 = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16) +>>> imsave('_tmp.pgm', im1) +>>> im2 = imread('_tmp.pgm') +>>> assert numpy.all(im1 == im2) + +""" + +from __future__ import division, print_function + +import sys +import re +import math +from copy import deepcopy + +import numpy + +__version__ = '2013.01.18' +__docformat__ = 'restructuredtext en' +__all__ = ['imread', 'imsave', 'NetpbmFile'] + + +def imread(filename, *args, **kwargs): + """Return image data from Netpbm file as numpy array. + + `args` and `kwargs` are arguments to NetpbmFile.asarray(). + + Examples + -------- + >>> image = imread('_tmp.pgm') + + """ + try: + netpbm = NetpbmFile(filename) + image = netpbm.asarray() + finally: + netpbm.close() + return image + + +def imsave(filename, data, maxval=None, pam=False): + """Write image data to Netpbm file. + + Examples + -------- + >>> image = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16) + >>> imsave('_tmp.pgm', image) + + """ + try: + netpbm = NetpbmFile(data, maxval=maxval) + netpbm.write(filename, pam=pam) + finally: + netpbm.close() + + +class NetpbmFile(object): + """Read and write Netpbm PAM, PBM, PGM, PPM, files.""" + + _types = {b'P1': b'BLACKANDWHITE', b'P2': b'GRAYSCALE', b'P3': b'RGB', + b'P4': b'BLACKANDWHITE', b'P5': b'GRAYSCALE', b'P6': b'RGB', + b'P7 332': b'RGB', b'P7': b'RGB_ALPHA'} + + def __init__(self, arg=None, **kwargs): + """Initialize instance from filename, open file, or numpy array.""" + for attr in ('header', 'magicnum', 'width', 'height', 'maxval', + 'depth', 'tupltypes', '_filename', '_fh', '_data'): + setattr(self, attr, None) + if arg is None: + self._fromdata([], **kwargs) + elif isinstance(arg, basestring): + self._fh = open(arg, 'rb') + self._filename = arg + self._fromfile(self._fh, **kwargs) + elif hasattr(arg, 'seek'): + self._fromfile(arg, **kwargs) + self._fh = arg + else: + self._fromdata(arg, **kwargs) + + def asarray(self, copy=True, cache=False, **kwargs): + """Return image data from file as numpy array.""" + data = self._data + if data is None: + data = self._read_data(self._fh, **kwargs) + if cache: + self._data = data + else: + return data + return deepcopy(data) if copy else data + + def write(self, arg, **kwargs): + """Write instance to file.""" + if hasattr(arg, 'seek'): + self._tofile(arg, **kwargs) + else: + with open(arg, 'wb') as fid: + self._tofile(fid, **kwargs) + + def close(self): + """Close open file. Future asarray calls might fail.""" + if self._filename and self._fh: + self._fh.close() + self._fh = None + + def __del__(self): + self.close() + + def _fromfile(self, fh): + """Initialize instance from open file.""" + fh.seek(0) + data = fh.read(4096) + if (len(data) < 7) or not (b'0' < data[1:2] < b'8'): + raise ValueError("Not a Netpbm file:\n%s" % data[:32]) + try: + self._read_pam_header(data) + except Exception: + try: + self._read_pnm_header(data) + except Exception: + raise ValueError("Not a Netpbm file:\n%s" % data[:32]) + + def _read_pam_header(self, data): + """Read PAM header and initialize instance.""" + regroups = re.search( + b"(^P7[\n\r]+(?:(?:[\n\r]+)|(?:#.*)|" + b"(HEIGHT\s+\d+)|(WIDTH\s+\d+)|(DEPTH\s+\d+)|(MAXVAL\s+\d+)|" + b"(?:TUPLTYPE\s+\w+))*ENDHDR\n)", data).groups() + self.header = regroups[0] + self.magicnum = b'P7' + for group in regroups[1:]: + key, value = group.split() + setattr(self, unicode(key).lower(), int(value)) + matches = re.findall(b"(TUPLTYPE\s+\w+)", self.header) + self.tupltypes = [s.split(None, 1)[1] for s in matches] + + def _read_pnm_header(self, data): + """Read PNM header and initialize instance.""" + bpm = data[1:2] in b"14" + regroups = re.search(b"".join(( + b"(^(P[123456]|P7 332)\s+(?:#.*[\r\n])*", + b"\s*(\d+)\s+(?:#.*[\r\n])*", + b"\s*(\d+)\s+(?:#.*[\r\n])*" * (not bpm), + b"\s*(\d+)\s(?:\s*#.*[\r\n]\s)*)")), data).groups() + (1, ) * bpm + self.header = regroups[0] + self.magicnum = regroups[1] + self.width = int(regroups[2]) + self.height = int(regroups[3]) + self.maxval = int(regroups[4]) + self.depth = 3 if self.magicnum in b"P3P6P7 332" else 1 + self.tupltypes = [self._types[self.magicnum]] + + def _read_data(self, fh, byteorder='>'): + """Return image data from open file as numpy array.""" + fh.seek(len(self.header)) + data = fh.read() + dtype = 'u1' if self.maxval < 256 else byteorder + 'u2' + depth = 1 if self.magicnum == b"P7 332" else self.depth + shape = [-1, self.height, self.width, depth] + size = numpy.prod(shape[1:]) + if self.magicnum in b"P1P2P3": + data = numpy.array(data.split(None, size)[:size], dtype) + data = data.reshape(shape) + elif self.maxval == 1: + shape[2] = int(math.ceil(self.width / 8)) + data = numpy.frombuffer(data, dtype).reshape(shape) + data = numpy.unpackbits(data, axis=-2)[:, :, :self.width, :] + else: + data = numpy.frombuffer(data, dtype) + data = data[:size * (data.size // size)].reshape(shape) + if data.shape[0] < 2: + data = data.reshape(data.shape[1:]) + if data.shape[-1] < 2: + data = data.reshape(data.shape[:-1]) + if self.magicnum == b"P7 332": + rgb332 = numpy.array(list(numpy.ndindex(8, 8, 4)), numpy.uint8) + rgb332 *= [36, 36, 85] + data = numpy.take(rgb332, data, axis=0) + return data + + def _fromdata(self, data, maxval=None): + """Initialize instance from numpy array.""" + data = numpy.array(data, ndmin=2, copy=True) + if data.dtype.kind not in "uib": + raise ValueError("not an integer type: %s" % data.dtype) + if data.dtype.kind == 'i' and numpy.min(data) < 0: + raise ValueError("data out of range: %i" % numpy.min(data)) + if maxval is None: + maxval = numpy.max(data) + maxval = 255 if maxval < 256 else 65535 + if maxval < 0 or maxval > 65535: + raise ValueError("data out of range: %i" % maxval) + data = data.astype('u1' if maxval < 256 else '>u2') + self._data = data + if data.ndim > 2 and data.shape[-1] in (3, 4): + self.depth = data.shape[-1] + self.width = data.shape[-2] + self.height = data.shape[-3] + self.magicnum = b'P7' if self.depth == 4 else b'P6' + else: + self.depth = 1 + self.width = data.shape[-1] + self.height = data.shape[-2] + self.magicnum = b'P5' if maxval > 1 else b'P4' + self.maxval = maxval + self.tupltypes = [self._types[self.magicnum]] + self.header = self._header() + + def _tofile(self, fh, pam=False): + """Write Netbm file.""" + fh.seek(0) + fh.write(self._header(pam)) + data = self.asarray(copy=False) + if self.maxval == 1: + data = numpy.packbits(data, axis=-1) + data.tofile(fh) + + def _header(self, pam=False): + """Return file header as byte string.""" + if pam or self.magicnum == b'P7': + header = "\n".join(( + "P7", + "HEIGHT %i" % self.height, + "WIDTH %i" % self.width, + "DEPTH %i" % self.depth, + "MAXVAL %i" % self.maxval, + "\n".join("TUPLTYPE %s" % unicode(i) for i in self.tupltypes), + "ENDHDR\n")) + elif self.maxval == 1: + header = "P4 %i %i\n" % (self.width, self.height) + elif self.depth == 1: + header = "P5 %i %i %i\n" % (self.width, self.height, self.maxval) + else: + header = "P6 %i %i %i\n" % (self.width, self.height, self.maxval) + if sys.version_info[0] > 2: + header = bytes(header, 'ascii') + return header + + def __str__(self): + """Return information about instance.""" + return unicode(self.header) + + +if sys.version_info[0] > 2: + basestring = str + unicode = lambda x: str(x, 'ascii') + +if __name__ == "__main__": + # Show images specified on command line or all images in current directory + from glob import glob + from matplotlib import pyplot + files = sys.argv[1:] if len(sys.argv) > 1 else glob('*.p*m') + for fname in files: + try: + pam = NetpbmFile(fname) + img = pam.asarray(copy=False) + if False: + pam.write('_tmp.pgm.out', pam=True) + img2 = imread('_tmp.pgm.out') + assert numpy.all(img == img2) + imsave('_tmp.pgm.out', img) + img2 = imread('_tmp.pgm.out') + assert numpy.all(img == img2) + pam.close() + except ValueError as e: + print(fname, e) + continue + _shape = img.shape + if img.ndim > 3 or (img.ndim > 2 and img.shape[-1] not in (3, 4)): + img = img[0] + cmap = 'gray' if pam.maxval > 1 else 'binary' + pyplot.imshow(img, cmap, interpolation='nearest') + pyplot.title("%s %s %s %s" % (fname, unicode(pam.magicnum), + _shape, img.dtype)) + pyplot.show() From 822459cdb67738f405481cb4f6a6ff20f7ccedd8 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:34:28 +0000 Subject: [PATCH 11/26] Relocated --- GPy/plotting/matplot_dep/visualize.py | 538 ++++++++++++++++++++++++++ 1 file changed, 538 insertions(+) create mode 100644 GPy/plotting/matplot_dep/visualize.py diff --git a/GPy/plotting/matplot_dep/visualize.py b/GPy/plotting/matplot_dep/visualize.py new file mode 100644 index 00000000..99e8a0da --- /dev/null +++ b/GPy/plotting/matplot_dep/visualize.py @@ -0,0 +1,538 @@ +import matplotlib.pyplot as plt +from mpl_toolkits.mplot3d import Axes3D +import GPy +import numpy as np +import matplotlib as mpl +import time +import Image +try: + import visual + visual_available = True + +except ImportError: + visual_available = False + + +class data_show: + """ + The data_show class is a base class which describes how to visualize a + particular data set. For example, motion capture data can be plotted as a + stick figure, or images are shown using imshow. This class enables latent + to data visualizations for the GP-LVM. + """ + def __init__(self, vals): + self.vals = vals.copy() + # If no axes are defined, create some. + + def modify(self, vals): + raise NotImplementedError, "this needs to be implemented to use the data_show class" + + def close(self): + raise NotImplementedError, "this needs to be implemented to use the data_show class" + +class vpython_show(data_show): + """ + the vpython_show class is a base class for all visualization methods that use vpython to display. It is initialized with a scene. If the scene is set to None it creates a scene window. + """ + + def __init__(self, vals, scene=None): + data_show.__init__(self, vals) + # If no axes are defined, create some. + + if scene==None: + self.scene = visual.display(title='Data Visualization') + else: + self.scene = scene + + def close(self): + self.scene.exit() + + + +class matplotlib_show(data_show): + """ + the matplotlib_show class is a base class for all visualization methods that use matplotlib. It is initialized with an axis. If the axis is set to None it creates a figure window. + """ + def __init__(self, vals, axes=None): + data_show.__init__(self, vals) + # If no axes are defined, create some. + + if axes==None: + fig = plt.figure() + self.axes = fig.add_subplot(111) + else: + self.axes = axes + + def close(self): + plt.close(self.axes.get_figure()) + +class vector_show(matplotlib_show): + """ + A base visualization class that just shows a data vector as a plot of + vector elements alongside their indices. + """ + def __init__(self, vals, axes=None): + matplotlib_show.__init__(self, vals, axes) + self.handle = self.axes.plot(np.arange(0, len(vals))[:, None], self.vals.T)[0] + + def modify(self, vals): + self.vals = vals.copy() + xdata, ydata = self.handle.get_data() + self.handle.set_data(xdata, self.vals.T) + self.axes.figure.canvas.draw() + + +class lvm(matplotlib_show): + def __init__(self, vals, model, data_visualize, latent_axes=None, sense_axes=None, latent_index=[0,1]): + """Visualize a latent variable model + + :param model: the latent variable model to visualize. + :param data_visualize: the object used to visualize the data which has been modelled. + :type data_visualize: visualize.data_show type. + :param latent_axes: the axes where the latent visualization should be plotted. + """ + if vals == None: + vals = model.X[0] + + matplotlib_show.__init__(self, vals, axes=latent_axes) + + if isinstance(latent_axes,mpl.axes.Axes): + self.cid = latent_axes.figure.canvas.mpl_connect('button_press_event', self.on_click) + self.cid = latent_axes.figure.canvas.mpl_connect('motion_notify_event', self.on_move) + self.cid = latent_axes.figure.canvas.mpl_connect('axes_leave_event', self.on_leave) + self.cid = latent_axes.figure.canvas.mpl_connect('axes_enter_event', self.on_enter) + else: + self.cid = latent_axes[0].figure.canvas.mpl_connect('button_press_event', self.on_click) + self.cid = latent_axes[0].figure.canvas.mpl_connect('motion_notify_event', self.on_move) + self.cid = latent_axes[0].figure.canvas.mpl_connect('axes_leave_event', self.on_leave) + self.cid = latent_axes[0].figure.canvas.mpl_connect('axes_enter_event', self.on_enter) + + self.data_visualize = data_visualize + self.model = model + self.latent_axes = latent_axes + self.sense_axes = sense_axes + self.called = False + self.move_on = False + self.latent_index = latent_index + self.latent_dim = model.input_dim + + # The red cross which shows current latent point. + self.latent_values = vals + self.latent_handle = self.latent_axes.plot([0],[0],'rx',mew=2)[0] + self.modify(vals) + self.show_sensitivities() + + def modify(self, vals): + """When latent values are modified update the latent representation and ulso update the output visualization.""" + self.vals = vals.copy() + y = self.model.predict(self.vals)[0] + self.data_visualize.modify(y) + self.latent_handle.set_data(self.vals[self.latent_index[0]], self.vals[self.latent_index[1]]) + self.axes.figure.canvas.draw() + + + def on_enter(self,event): + pass + def on_leave(self,event): + pass + + def on_click(self, event): + print 'click!' + if event.inaxes!=self.latent_axes: return + self.move_on = not self.move_on + self.called = True + + def on_move(self, event): + if event.inaxes!=self.latent_axes: return + if self.called and self.move_on: + # Call modify code on move + self.latent_values[self.latent_index[0]]=event.xdata + self.latent_values[self.latent_index[1]]=event.ydata + self.modify(self.latent_values) + + def show_sensitivities(self): + # A click in the bar chart axis for selection a dimension. + if self.sense_axes != None: + self.sense_axes.cla() + self.sense_axes.bar(np.arange(self.model.input_dim), self.model.input_sensitivity(), color='b') + + if self.latent_index[1] == self.latent_index[0]: + self.sense_axes.bar(np.array(self.latent_index[0]), self.model.input_sensitivity()[self.latent_index[0]], color='y') + self.sense_axes.bar(np.array(self.latent_index[1]), self.model.input_sensitivity()[self.latent_index[1]], color='y') + + else: + self.sense_axes.bar(np.array(self.latent_index[0]), self.model.input_sensitivity()[self.latent_index[0]], color='g') + self.sense_axes.bar(np.array(self.latent_index[1]), self.model.input_sensitivity()[self.latent_index[1]], color='r') + + self.sense_axes.figure.canvas.draw() + + +class lvm_subplots(lvm): + """ + latent_axes is a np array of dimension np.ceil(input_dim/2), + one for each pair of the latent dimensions. + """ + def __init__(self, vals, Model, data_visualize, latent_axes=None, sense_axes=None): + self.nplots = int(np.ceil(Model.input_dim/2.))+1 + assert len(latent_axes)==self.nplots + if vals==None: + vals = Model.X[0, :] + self.latent_values = vals + + for i, axis in enumerate(latent_axes): + if i == self.nplots-1: + if self.nplots*2!=Model.input_dim: + latent_index = [i*2, i*2] + lvm.__init__(self, self.latent_vals, Model, data_visualize, axis, sense_axes, latent_index=latent_index) + else: + latent_index = [i*2, i*2+1] + lvm.__init__(self, self.latent_vals, Model, data_visualize, axis, latent_index=latent_index) + + + +class lvm_dimselect(lvm): + """ + A visualizer for latent variable models which allows selection of the latent dimensions to use by clicking on a bar chart of their length scales. + + For an example of the visualizer's use try: + + GPy.examples.dimensionality_reduction.BGPVLM_oil() + + """ + def __init__(self, vals, model, data_visualize, latent_axes=None, sense_axes=None, latent_index=[0, 1], labels=None): + if latent_axes==None and sense_axes==None: + self.fig,(latent_axes,self.sense_axes) = plt.subplots(1,2) + elif sense_axes==None: + fig=plt.figure() + self.sense_axes = fig.add_subplot(111) + else: + self.sense_axes = sense_axes + self.labels = labels + lvm.__init__(self,vals,model,data_visualize,latent_axes,sense_axes,latent_index) + self.show_sensitivities() + print "use left and right mouse butons to select dimensions" + + + def on_click(self, event): + + if event.inaxes==self.sense_axes: + new_index = max(0,min(int(np.round(event.xdata-0.5)),self.model.input_dim-1)) + if event.button == 1: + # Make it red if and y-axis (red=port=left) if it is a left button click + self.latent_index[1] = new_index + else: + # Make it green and x-axis (green=starboard=right) if it is a right button click + self.latent_index[0] = new_index + + self.show_sensitivities() + + self.latent_axes.cla() + self.model.plot_latent(which_indices=self.latent_index, + ax=self.latent_axes, labels=self.labels) + self.latent_handle = self.latent_axes.plot([0],[0],'rx',mew=2)[0] + self.modify(self.latent_values) + + elif event.inaxes==self.latent_axes: + self.move_on = not self.move_on + + self.called = True + + + + def on_leave(self,event): + latent_values = self.latent_values.copy() + y = self.model.predict(latent_values[None,:])[0] + self.data_visualize.modify(y) + + + +class image_show(matplotlib_show): + """Show a data vector as an image. This visualizer rehapes the output vector and displays it as an image. + + :param vals: the values of the output to display. + :type vals: ndarray + :param axes: the axes to show the output on. + :type vals: axes handle + :param dimensions: the dimensions that the image needs to be transposed to for display. + :type dimensions: tuple + :param transpose: whether to transpose the image before display. + :type bool: default is False. + :param order: whether array is in Fortan ordering ('F') or Python ordering ('C'). Default is python ('C'). + :type order: string + :param invert: whether to invert the pixels or not (default False). + :type invert: bool + :param palette: a palette to use for the image. + :param preset_mean: the preset mean of a scaled image. + :type preset_mean: double + :param preset_std: the preset standard deviation of a scaled image. + :type preset_std: double""" + def __init__(self, vals, axes=None, dimensions=(16,16), transpose=False, order='C', invert=False, scale=False, palette=[], preset_mean = 0., preset_std = -1., select_image=0): + matplotlib_show.__init__(self, vals, axes) + self.dimensions = dimensions + self.transpose = transpose + self.order = order + self.invert = invert + self.scale = scale + self.palette = palette + self.preset_mean = preset_mean + self.preset_std = preset_std + self.select_image = select_image # This is used when the y vector contains multiple images concatenated. + + self.set_image(self.vals) + if not self.palette == []: # Can just show the image (self.set_image() took care of setting the palette) + self.handle = self.axes.imshow(self.vals, interpolation='nearest') + else: # Use a boring gray map. + self.handle = self.axes.imshow(self.vals, cmap=plt.cm.gray, interpolation='nearest') # @UndefinedVariable + plt.show() + + def modify(self, vals): + self.set_image(vals.copy()) + self.handle.set_array(self.vals) + self.axes.figure.canvas.draw() + + def set_image(self, vals): + dim = self.dimensions[0] * self.dimensions[1] + num_images = np.sqrt(vals[0,].size/dim) + if num_images > 1 and num_images.is_integer(): # Show a mosaic of images + num_images = np.int(num_images) + self.vals = np.zeros((self.dimensions[0]*num_images, self.dimensions[1]*num_images)) + for iR in range(num_images): + for iC in range(num_images): + cur_img_id = iR*num_images + iC + cur_img = np.reshape(vals[0,dim*cur_img_id+np.array(range(dim))], self.dimensions, order=self.order) + first_row = iR*self.dimensions[0] + last_row = (iR+1)*self.dimensions[0] + first_col = iC*self.dimensions[1] + last_col = (iC+1)*self.dimensions[1] + self.vals[first_row:last_row, first_col:last_col] = cur_img + + else: + self.vals = np.reshape(vals[0,dim*self.select_image+np.array(range(dim))], self.dimensions, order=self.order) + if self.transpose: + self.vals = self.vals.T + # if not self.scale: + # self.vals = self.vals + if self.invert: + self.vals = -self.vals + + # un-normalizing, for visualisation purposes: + if self.preset_std >= 0: # The Mean is assumed to be in the range (0,255) + self.vals = self.vals*self.preset_std + self.preset_mean + # Clipping the values: + self.vals[self.vals < 0] = 0 + self.vals[self.vals > 255] = 255 + else: + self.vals = 255*(self.vals - self.vals.min())/(self.vals.max() - self.vals.min()) + if not self.palette == []: # applying using an image palette (e.g. if the image has been quantized) + self.vals = Image.fromarray(self.vals.astype('uint8')) + self.vals.putpalette(self.palette) # palette is a list, must be loaded before calling this function + +class mocap_data_show_vpython(vpython_show): + """Base class for visualizing motion capture data using visual module.""" + + def __init__(self, vals, scene=None, connect=None, radius=0.1): + vpython_show.__init__(self, vals, scene) + self.radius = radius + self.connect = connect + self.process_values() + self.draw_edges() + self.draw_vertices() + + def draw_vertices(self): + self.spheres = [] + for i in range(self.vals.shape[0]): + self.spheres.append(visual.sphere(pos=(self.vals[i, 0], self.vals[i, 2], self.vals[i, 1]), radius=self.radius)) + self.scene.visible=True + + def draw_edges(self): + self.rods = [] + self.line_handle = [] + if not self.connect==None: + self.I, self.J = np.nonzero(self.connect) + for i, j in zip(self.I, self.J): + pos, axis = self.pos_axis(i, j) + self.rods.append(visual.cylinder(pos=pos, axis=axis, radius=self.radius)) + + def modify_vertices(self): + for i in range(self.vals.shape[0]): + self.spheres[i].pos = (self.vals[i, 0], self.vals[i, 2], self.vals[i, 1]) + + def modify_edges(self): + self.line_handle = [] + if not self.connect==None: + self.I, self.J = np.nonzero(self.connect) + for rod, i, j in zip(self.rods, self.I, self.J): + rod.pos, rod.axis = self.pos_axis(i, j) + + def pos_axis(self, i, j): + pos = [] + axis = [] + pos.append(self.vals[i, 0]) + axis.append(self.vals[j, 0]-self.vals[i,0]) + pos.append(self.vals[i, 2]) + axis.append(self.vals[j, 2]-self.vals[i,2]) + pos.append(self.vals[i, 1]) + axis.append(self.vals[j, 1]-self.vals[i,1]) + return pos, axis + + def modify(self, vals): + self.vals = vals.copy() + self.process_values() + self.modify_edges() + self.modify_vertices() + + def process_values(self): + raise NotImplementedError, "this needs to be implemented to use the data_show class" + + +class mocap_data_show(matplotlib_show): + """Base class for visualizing motion capture data.""" + + def __init__(self, vals, axes=None, connect=None): + if axes==None: + fig = plt.figure() + axes = fig.add_subplot(111, projection='3d') + matplotlib_show.__init__(self, vals, axes) + + self.connect = connect + self.process_values() + self.initialize_axes() + self.draw_vertices() + self.finalize_axes() + self.draw_edges() + self.axes.figure.canvas.draw() + + def draw_vertices(self): + self.points_handle = self.axes.scatter(self.vals[:, 0], self.vals[:, 1], self.vals[:, 2]) + + def draw_edges(self): + self.line_handle = [] + if not self.connect==None: + x = [] + y = [] + z = [] + self.I, self.J = np.nonzero(self.connect) + for i, j in zip(self.I, self.J): + x.append(self.vals[i, 0]) + x.append(self.vals[j, 0]) + x.append(np.NaN) + y.append(self.vals[i, 1]) + y.append(self.vals[j, 1]) + y.append(np.NaN) + z.append(self.vals[i, 2]) + z.append(self.vals[j, 2]) + z.append(np.NaN) + self.line_handle = self.axes.plot(np.array(x), np.array(y), np.array(z), 'b-') + + def modify(self, vals): + self.vals = vals.copy() + self.process_values() + self.initialize_axes_modify() + self.draw_vertices() + self.finalize_axes_modify() + self.draw_edges() + self.axes.figure.canvas.draw() + + def process_values(self): + raise NotImplementedError, "this needs to be implemented to use the data_show class" + + def initialize_axes(self): + """Set up the axes with the right limits and scaling.""" + self.x_lim = np.array([self.vals[:, 0].min(), self.vals[:, 0].max()]) + self.y_lim = np.array([self.vals[:, 1].min(), self.vals[:, 1].max()]) + self.z_lim = np.array([self.vals[:, 2].min(), self.vals[:, 2].max()]) + + def initialize_axes_modify(self): + self.points_handle.remove() + self.line_handle[0].remove() + + def finalize_axes(self): + self.axes.set_xlim(self.x_lim) + self.axes.set_ylim(self.y_lim) + self.axes.set_zlim(self.z_lim) + self.axes.auto_scale_xyz([-1., 1.], [-1., 1.], [-1.5, 1.5]) + + #self.axes.set_aspect('equal') + self.axes.autoscale(enable=False) + + def finalize_axes_modify(self): + self.axes.set_xlim(self.x_lim) + self.axes.set_ylim(self.y_lim) + self.axes.set_zlim(self.z_lim) + +class stick_show(mocap_data_show): + """Show a three dimensional point cloud as a figure. Connect elements of the figure together using the matrix connect.""" + def __init__(self, vals, connect=None, axes=None): + mocap_data_show.__init__(self, vals, axes=axes, connect=connect) + + def process_values(self): + self.vals = self.vals.reshape((3, self.vals.shape[1]/3)).T + +class skeleton_show(mocap_data_show): + """data_show class for visualizing motion capture data encoded as a skeleton with angles.""" + def __init__(self, vals, skel, axes=None, padding=0): + """data_show class for visualizing motion capture data encoded as a skeleton with angles. + :param vals: set of modeled angles to use for printing in the axis when it's first created. + :type vals: np.array + :param skel: skeleton object that has the parameters of the motion capture skeleton associated with it. + :type skel: mocap.skeleton object + :param padding: + :type int + """ + self.skel = skel + self.padding = padding + connect = skel.connection_matrix() + mocap_data_show.__init__(self, vals, axes=axes, connect=connect) + def process_values(self): + """Takes a set of angles and converts them to the x,y,z coordinates in the internal prepresentation of the class, ready for plotting. + + :param vals: the values that are being modelled.""" + + if self.padding>0: + channels = np.zeros((self.vals.shape[0], self.vals.shape[1]+self.padding)) + channels[:, 0:self.vals.shape[0]] = self.vals + else: + channels = self.vals + vals_mat = self.skel.to_xyz(channels.flatten()) + self.vals = np.zeros_like(vals_mat) + # Flip the Y and Z axes + self.vals[:, 0] = vals_mat[:, 0].copy() + self.vals[:, 1] = vals_mat[:, 2].copy() + self.vals[:, 2] = vals_mat[:, 1].copy() + + def wrap_around(self, lim, connect): + quot = lim[1] - lim[0] + self.vals = rem(self.vals, quot)+lim[0] + nVals = floor(self.vals/quot) + for i in range(connect.shape[0]): + for j in find(connect[i, :]): + if nVals[i] != nVals[j]: + connect[i, j] = False + return connect + + +def data_play(Y, visualizer, frame_rate=30): + """Play a data set using the data_show object given. + + :Y: the data set to be visualized. + :param visualizer: the data show objectwhether to display during optimisation + :type visualizer: data_show + + Example usage: + + This example loads in the CMU mocap database (http://mocap.cs.cmu.edu) subject number 35 motion number 01. It then plays it using the mocap_show visualize object. + + .. code-block:: python + + data = GPy.util.datasets.cmu_mocap(subject='35', train_motions=['01']) + Y = data['Y'] + Y[:, 0:3] = 0. # Make figure walk in place + visualize = GPy.util.visualize.skeleton_show(Y[0, :], data['skel']) + GPy.util.visualize.data_play(Y, visualize) + + """ + + + for y in Y: + visualizer.modify(y[None, :]) + time.sleep(1./float(frame_rate)) From 1654080402a37194621e50c906f71d3b50f446f9 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:39:59 +0000 Subject: [PATCH 12/26] Plotting functions modified --- GPy/core/gp.py | 148 +++++-------------------------------------------- 1 file changed, 15 insertions(+), 133 deletions(-) diff --git a/GPy/core/gp.py b/GPy/core/gp.py index 5b356744..744ac008 100644 --- a/GPy/core/gp.py +++ b/GPy/core/gp.py @@ -2,10 +2,9 @@ # Licensed under the BSD 3-clause license (see LICENSE.txt) import numpy as np -import pylab as pb +import sys import warnings from .. import kern -from ..util.plot import gpplot, Tango, x_frame1D, x_frame2D from ..util.linalg import dtrtrs from model import Model from parameterization import ObservableArray @@ -122,9 +121,9 @@ class GP(Model): :param X: The points at which to take the samples. :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. - :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. :param full_cov: whether to return the full covariance matrix, or just the diagonal. :type full_cov: bool. @@ -145,9 +144,9 @@ class GP(Model): :param X: the points at which to take the samples. :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. - :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. :param full_cov: whether to return the full covariance matrix, or just the diagonal. :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. - This is a convenience function: we simply call self.plot with the - argument use_raw_predict set True. All args and kwargs are passed on to - plot. - - see also: gp.plot + This is a convenience function: arguments are passed to GPy.plotting.matplot_dep.models_plots.plot_f_fit """ - kwargs['plot_raw'] = True - self.plot(*args, **kwargs) + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + 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', - 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']): + def plot(self, *args): """ Plot the posterior of the GP. - 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. 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 - :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 + This is a convenience function: arguments are passed to GPy.plotting.matplot_dep.models_plots.plot_fit """ - #deal with optional arguments - if which_data_rows == 'all': - which_data_rows = slice(None) - 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" - - + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import models_plots + models_plots.plot_fit(self,*args) def _getstate(self): """ @@ -333,5 +217,3 @@ class GP(Model): self.num_data = state.pop() self.X = state.pop() Model._setstate(self, state) - - From 58501dc301b2e75b5a43c814cd2939e46b78c2a5 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:40:08 +0000 Subject: [PATCH 13/26] Plotting functions modified --- GPy/core/mapping.py | 83 +++++++-------------------------------------- 1 file changed, 13 insertions(+), 70 deletions(-) diff --git a/GPy/core/mapping.py b/GPy/core/mapping.py index 513407eb..ef0af16c 100644 --- a/GPy/core/mapping.py +++ b/GPy/core/mapping.py @@ -1,10 +1,9 @@ # Copyright (c) 2013, GPy authors (see AUTHORS.txt). # Licensed under the BSD 3-clause license (see LICENSE.txt) -from ..util.plot import Tango, x_frame1D, x_frame2D +import sys from parameterization import Parameterized import numpy as np -import pylab as pb class Mapping(Parameterized): """ @@ -47,11 +46,8 @@ class Mapping(Parameterized): raise NotImplementedError - def plot(self, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, samples=0, fignum=None, ax=None, fixed_inputs=[], linecol=Tango.colorsHex['darkBlue']): + def plot(self, *args): """ - - Plot the mapping. - Plots the mapping associated with the model. - In one dimension, the function is plotted. - In two dimsensions, a contour-plot shows the function @@ -60,68 +56,15 @@ class Mapping(Parameterized): Can plot only part of the data and part of the posterior functions using which_data and which_functions - :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 which_data: which if the training data to plot (default all) - :type which_data: 'all' or a slice object to slice self.X, self.Y - :param which_parts: which of the kernel functions to plot (additively) - :type which_parts: 'all', or list of bools - :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 - :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 linecol: color of line to plot. - :type linecol: - :param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure - + This is a convenience function: arguments are passed to GPy.plotting.matplot_dep.models_plots.plot_mapping """ - # TODO include samples - if which_data == 'all': - which_data = slice(None) - - if ax is None: - fig = pb.figure(num=fignum) - ax = fig.add_subplot(111) - - plotdims = self.input_dim - len(fixed_inputs) - - if plotdims == 1: - - 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) - Xgrid = np.empty((Xnew.shape[0],self.input_dim)) - Xgrid[:,freedim] = Xnew - for i,v in fixed_inputs: - Xgrid[:,i] = v - - f = self.predict(Xgrid, which_parts=which_parts) - for d in range(y.shape[1]): - ax.plot(Xnew, f[:, d], edgecol=linecol) - - elif self.X.shape[1] == 2: - resolution = resolution or 50 - Xnew, _, _, xmin, xmax = x_frame2D(self.X, plot_limits, resolution) - x, y = np.linspace(xmin[0], xmax[0], resolution), np.linspace(xmin[1], xmax[1], resolution) - f = self.predict(Xnew, which_parts=which_parts) - m = m.reshape(resolution, resolution).T - ax.contour(x, y, f, levels, vmin=m.min(), vmax=m.max(), cmap=pb.cm.jet) # @UndefinedVariable - ax.set_xlim(xmin[0], xmax[0]) - ax.set_ylim(xmin[1], xmax[1]) + if "matplotlib" in sys.modules: + from ..plotting.matplot_dep import models_plots + mapping_plots.plot_mapping(self,*args) else: - raise NotImplementedError, "Cannot define a frame with more than two input dimensions" + raise NameError, "matplotlib package has not been imported." + from model import Model @@ -135,14 +78,14 @@ class Mapping_check_model(Model): X = np.random.randn(num_samples, mapping.input_dim) if dL_df==None: dL_df = np.ones((num_samples, mapping.output_dim)) - + self.mapping=mapping self.X = X self.dL_df = dL_df self.num_params = self.mapping.num_params Model.__init__(self) - + def _get_params(self): return self.mapping._get_params() @@ -157,7 +100,7 @@ class Mapping_check_model(Model): def _log_likelihood_gradients(self): raise NotImplementedError, "This needs to be implemented to use the Mapping_check_model class." - + class Mapping_check_df_dtheta(Mapping_check_model): """This class allows gradient checks for the gradient of a mapping with respect to parameters. """ def __init__(self, mapping=None, dL_df=None, X=None): @@ -175,13 +118,13 @@ class Mapping_check_df_dX(Mapping_check_model): if dL_df==None: dL_df = np.ones((self.X.shape[0],self.mapping.output_dim)) self.num_params = self.X.shape[0]*self.mapping.input_dim - + def _log_likelihood_gradients(self): return self.mapping.df_dX(self.dL_df, self.X).flatten() def _get_param_names(self): return ['X_' +str(i) + ','+str(j) for j in range(self.X.shape[1]) for i in range(self.X.shape[0])] - + def _get_params(self): return self.X.flatten() From 11f784d47275733debaa0e2cc5c6fb869dfa972f Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:40:24 +0000 Subject: [PATCH 14/26] Plotting functions modified --- GPy/core/parameterization/priors.py | 24 ++++-------- GPy/core/parameterization/variational.py | 47 +++--------------------- 2 files changed, 13 insertions(+), 58 deletions(-) diff --git a/GPy/core/parameterization/priors.py b/GPy/core/parameterization/priors.py index 9614ca53..f1208f18 100644 --- a/GPy/core/parameterization/priors.py +++ b/GPy/core/parameterization/priors.py @@ -3,7 +3,6 @@ import numpy as np -import pylab as pb from scipy.special import gammaln, digamma from ...util.linalg import pdinv from domains import _REAL, _POSITIVE @@ -12,16 +11,14 @@ import weakref class Prior: domain = None - + def pdf(self, x): return np.exp(self.lnpdf(x)) def plot(self): - rvs = self.rvs(1000) - pb.hist(rvs, 100, normed=True) - xmin, xmax = pb.xlim() - xx = np.linspace(xmin, xmax, 1000) - pb.plot(xx, self.pdf(xx), 'r', linewidth=2) + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import priors_plots + priors_plots.univariate_plot(self) class Gaussian(Prior): @@ -153,16 +150,9 @@ class MultivariateGaussian: return np.random.multivariate_normal(self.mu, self.var, n) def plot(self): - if self.input_dim == 2: - rvs = self.rvs(200) - pb.plot(rvs[:, 0], rvs[:, 1], 'kx', mew=1.5) - xmin, xmax = pb.xlim() - ymin, ymax = pb.ylim() - xx, yy = np.mgrid[xmin:xmax:100j, ymin:ymax:100j] - xflat = np.vstack((xx.flatten(), yy.flatten())).T - zz = self.pdf(xflat).reshape(100, 100) - pb.contour(xx, yy, zz, linewidths=2) - + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import priors_plots + priors_plots.multivariate_plot(self) def gamma_from_EV(E, V): warnings.warn("use Gamma.from_EV to create Gamma Prior", FutureWarning) diff --git a/GPy/core/parameterization/variational.py b/GPy/core/parameterization/variational.py index 25718fbf..e9868b82 100644 --- a/GPy/core/parameterization/variational.py +++ b/GPy/core/parameterization/variational.py @@ -11,7 +11,7 @@ from ...util.misc import param_to_array class Normal(Parameterized): ''' Normal distribution for variational approximations. - + holds the means and variances for a factorizing multivariate normal distribution ''' def __init__(self, means, variances, name='latent space'): @@ -20,47 +20,12 @@ class Normal(Parameterized): self.variances = Param('variance', variances) self.add_parameters(self.means, self.variances) - def plot(self, fignum=None, ax=None, colors=None): + def plot(self, *args): """ Plot latent space X in 1D: - - if fig is given, create input_dim subplots in fig and plot in these - - if ax is given plot input_dim 1D latent space plots of X into each `axis` - - if neither fig nor ax is given create a figure with fignum and plot in there - - colors: - colors of different latent space dimensions input_dim - + See GPy.plotting.matplot_dep.variational_plots """ - import pylab - if ax is None: - fig = pylab.figure(num=fignum, figsize=(8, min(12, (2 * self.means.shape[1])))) - if colors is None: - colors = pylab.gca()._get_lines.color_cycle - pylab.clf() - else: - colors = iter(colors) - plots = [] - means, variances = param_to_array(self.means, self.variances) - x = np.arange(means.shape[0]) - for i in range(means.shape[1]): - if ax is None: - a = fig.add_subplot(means.shape[1], 1, i + 1) - elif isinstance(ax, (tuple, list)): - a = ax[i] - else: - raise ValueError("Need one ax per latent dimension input_dim") - a.plot(means, c='k', alpha=.3) - plots.extend(a.plot(x, means.T[i], c=colors.next(), label=r"$\mathbf{{X_{{{}}}}}$".format(i))) - a.fill_between(x, - means.T[i] - 2 * np.sqrt(variances.T[i]), - means.T[i] + 2 * np.sqrt(variances.T[i]), - facecolor=plots[-1].get_color(), - alpha=.3) - a.legend(borderaxespad=0.) - a.set_xlim(x.min(), x.max()) - if i < means.shape[1] - 1: - a.set_xticklabels('') - pylab.draw() - fig.tight_layout(h_pad=.01) # , rect=(0, 0, 1, .95)) - return fig + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import variational_plots + return variational_plots.plot(self,*args) From 67658945b192f4f961bf382b9ae10e3a2877b62f Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:40:36 +0000 Subject: [PATCH 15/26] Plotting functions modified --- GPy/core/sparse_gp.py | 79 ------------------------------------------- 1 file changed, 79 deletions(-) diff --git a/GPy/core/sparse_gp.py b/GPy/core/sparse_gp.py index a05bb362..0f977bc3 100644 --- a/GPy/core/sparse_gp.py +++ b/GPy/core/sparse_gp.py @@ -2,7 +2,6 @@ # Licensed under the BSD 3-clause license (see LICENSE.txt) import numpy as np -import pylab as pb from ..util.linalg import mdot, tdot, symmetrify, backsub_both_sides, chol_inv, dtrtrs, dpotrs, dpotri from gp import GP from parameterization.param import Param @@ -106,83 +105,6 @@ class SparseGP(GP): #TODO!!! - def plot_f(self, samples=0, plot_limits=None, which_data='all', which_parts='all', resolution=None, full_cov=False, fignum=None, ax=None): - """ - Plot the belief in the latent function, the "GP's view of the world" - - 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 - - :param samples: the number of a posteriori samples to plot - :param plot_limits: The limits of the plot. If 1D [xmin,xmax], if 2D [[xmin,ymin],[xmax,ymax]]. Defaluts to data limits - :param which_data: which if the training data to plot (default all) - :type which_data: 'all' or a slice object to slice self.X, self.Y - :param which_parts: which of the kernel functions to plot (additively) - :type which_parts: 'all', or list of bools - :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 full_cov: - :type full_cov: bool - :param fignum: figure to plot on. - :type fignum: figure number - :param ax: axes to plot on. - :type ax: axes handle - - :param output: which output to plot (for multiple output models only) - :type output: integer (first output is 0) - """ - if ax is None: - fig = pb.figure(num=fignum) - ax = fig.add_subplot(111) - if fignum is None and ax is None: - fignum = fig.num - if which_data is 'all': - which_data = slice(None) - - GP.plot_f(self, samples=samples, plot_limits=plot_limits, which_data='all', which_parts='all', resolution=resolution, full_cov=full_cov, fignum=fignum, ax=ax) - - if self.X.shape[1] == 1: - if self.has_uncertain_inputs: - ax.errorbar(self.X[which_data, 0], self.likelihood.data[which_data, 0], - xerr=2 * np.sqrt(self.X_variance[which_data, 0]), - ecolor='k', fmt=None, elinewidth=.5, alpha=.5) - Zu = self.Z * self._Xscale + self._Xoffset - ax.plot(Zu, np.zeros_like(Zu) + ax.get_ylim()[0], 'r|', mew=1.5, markersize=12) - - elif self.X.shape[1] == 2: - Zu = self.Z * self._Xscale + self._Xoffset - ax.plot(Zu[:, 0], Zu[:, 1], 'wo') - - else: - raise NotImplementedError, "Cannot define a frame with more than two input dimensions" - - def plot(self, samples=0, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, fignum=None, ax=None): - if ax is None: - fig = pb.figure(num=fignum) - ax = fig.add_subplot(111) - if fignum is None and ax is None: - fignum = fig.num - if which_data is 'all': - which_data = slice(None) - - GP.plot(self, samples=samples, plot_limits=plot_limits, which_data='all', which_parts='all', resolution=resolution, levels=20, fignum=fignum, ax=ax) - - if self.X.shape[1] == 1: - if self.has_uncertain_inputs: - ax.errorbar(self.X[which_data, 0], self.likelihood.data[which_data, 0], - xerr=2 * np.sqrt(self.X_variance[which_data, 0]), - ecolor='k', fmt=None, elinewidth=.5, alpha=.5) - Zu = self.Z * self._Xscale + self._Xoffset - ax.plot(Zu, np.zeros_like(Zu) + ax.get_ylim()[0], 'r|', mew=1.5, markersize=12) - - elif self.X.shape[1] == 2: - Zu = self.Z * self._Xscale + self._Xoffset - ax.plot(Zu[:, 0], Zu[:, 1], 'wo') - - - else: - raise NotImplementedError, "Cannot define a frame with more than two input dimensions" - def _getstate(self): """ Get the current state of the class, @@ -199,4 +121,3 @@ class SparseGP(GP): self.num_inducing = state.pop() self.Z = state.pop() GP._setstate(self, state) - From 73a7b6f079b79a90d516ec99657597d738286262 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:40:48 +0000 Subject: [PATCH 16/26] Plotting functions modified --- GPy/core/svigp.py | 46 +++++++++++++--------------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/GPy/core/svigp.py b/GPy/core/svigp.py index ea0de9e3..d54d3453 100644 --- a/GPy/core/svigp.py +++ b/GPy/core/svigp.py @@ -2,7 +2,6 @@ # Licensed under the BSD 3-clause license (see LICENSE.txt) import numpy as np -import pylab as pb from ..util.linalg import pdinv, mdot, tdot, dpotrs, dtrtrs, jitchol, backsub_both_sides from gp import GP import time @@ -480,38 +479,19 @@ class SVIGP(GP): return self.q_u_canonical_flat - def plot(self, ax=None, fignum=None, Z_height=None, **kwargs): + def plot(self, *args, **kwargs): + """ + See GPy.plotting.matplot_dep.svgi_plots.plot + """ + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import svgi_plots + svgi_plots.plot(self,*args,**kwargs) - if ax is None: - fig = pb.figure(num=fignum) - ax = fig.add_subplot(111) - - #horrible hack here: - data = self.likelihood.data.copy() - self.likelihood.data = self.Y - GP.plot(self, ax=ax, **kwargs) - self.likelihood.data = data - - Zu = self.Z * self._Xscale + self._Xoffset - if self.input_dim==1: - ax.plot(self.X_batch, self.likelihood.data, 'gx',mew=2) - if Z_height is None: - Z_height = ax.get_ylim()[0] - ax.plot(Zu, np.zeros_like(Zu) + Z_height, 'r|', mew=1.5, markersize=12) - - if self.input_dim==2: - ax.scatter(self.X[:,0], self.X[:,1], 20., self.Y[:,0], linewidth=0, cmap=pb.cm.jet) # @UndefinedVariable - ax.plot(Zu[:,0], Zu[:,1], 'w^') def plot_traces(self): - pb.figure() - t = np.array(self._param_trace) - pb.subplot(2,1,1) - for l,ti in zip(self._get_param_names(),t.T): - if not l[:3]=='iip': - pb.plot(ti,label=l) - pb.legend(loc=0) - - pb.subplot(2,1,2) - pb.plot(np.asarray(self._ll_trace),label='stochastic likelihood') - pb.legend(loc=0) + """ + See GPy.plotting.matplot_dep.svgi_plots.plot_traces + """ + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import svgi_plots + svgi_plots.plot_traces(self) From fd34d8aa055fb11d829e829cebf89d89ebf42b5a Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:41:16 +0000 Subject: [PATCH 17/26] Plotting functions modified --- GPy/inference/optimization/optimization.py | 15 +++++++-------- GPy/inference/optimization/sgd.py | 16 ++++++---------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/GPy/inference/optimization/optimization.py b/GPy/inference/optimization/optimization.py index e65b862e..d9be46ce 100644 --- a/GPy/inference/optimization/optimization.py +++ b/GPy/inference/optimization/optimization.py @@ -1,7 +1,6 @@ # Copyright (c) 2012, GPy authors (see AUTHORS.txt). # Licensed under the BSD 3-clause license (see LICENSE.txt) -import pylab as pb import datetime as dt from scipy import optimize from warnings import warn @@ -57,13 +56,13 @@ class Optimizer(): raise NotImplementedError, "this needs to be implemented to use the optimizer class" def plot(self): - if self.trace == None: - print "No trace present so I can't plot it. Please check that the optimizer actually supplies a trace." - else: - pb.figure() - pb.plot(self.trace) - pb.xlabel('Iteration') - pb.ylabel('f(x)') + """ + See GPy.plotting.matplot_dep.inference_plots + """ + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import inference_plots + inference_plots.plot_optimizer(self) + def __str__(self): diagnostics = "Optimizer: \t\t\t\t %s\n" % self.opt_name diff --git a/GPy/inference/optimization/sgd.py b/GPy/inference/optimization/sgd.py index 5cd144e8..3f14dc4b 100644 --- a/GPy/inference/optimization/sgd.py +++ b/GPy/inference/optimization/sgd.py @@ -68,16 +68,12 @@ class opt_SGD(Optimizer): return status def plot_traces(self): - plt.figure() - plt.subplot(211) - plt.title('Parameters') - for k in self.param_traces.keys(): - plt.plot(self.param_traces[k], label=k) - plt.legend(loc=0) - plt.subplot(212) - plt.title('Objective function') - plt.plot(self.fopt_trace) - + """ + See GPy.plotting.matplot_dep.inference_plots + """ + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import inference_plots + inference_plots.plot_sgd_traces(self) def non_null_samples(self, data): return (np.isnan(data).sum(axis=1) == 0) From 957d2bd2aad3ebd24848859989be812cabfc3ba2 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:41:35 +0000 Subject: [PATCH 18/26] Plotting functions modified --- GPy/kern/kern.py | 137 +++++------------------------------------------ 1 file changed, 12 insertions(+), 125 deletions(-) diff --git a/GPy/kern/kern.py b/GPy/kern/kern.py index 196df206..de87ff14 100644 --- a/GPy/kern/kern.py +++ b/GPy/kern/kern.py @@ -3,9 +3,7 @@ import sys import numpy as np -import pylab as pb import itertools -from matplotlib.transforms import offset_copy from parts.prod import Prod as prod from parts.linear import Linear from parts.kernpart import Kernpart @@ -71,77 +69,14 @@ class kern(Parameterized): Parameterized._setstate(self, state) - def plot_ARD(self, fignum=None, ax=None, title='', legend=False): + def plot_ARD(self, *args): """If an ARD kernel is present, plot a bar representation using matplotlib - :param fignum: figure number of the plot - :param ax: matplotlib axis to plot on - :param title: - title of the plot, - pass '' to not print a title - pass None for a generic title + See GPy.plotting.matplot_dep.plot_ARD """ - if ax is None: - fig = pb.figure(fignum) - ax = fig.add_subplot(111) - else: - fig = ax.figure - from GPy.util import Tango - from matplotlib.textpath import TextPath - Tango.reset() - xticklabels = [] - bars = [] - x0 = 0 - for p in self._parameters_: - c = Tango.nextMedium() - if hasattr(p, 'ARD') and p.ARD: - if title is None: - ax.set_title('ARD parameters, %s kernel' % p.name) - else: - ax.set_title(title) - if isinstance(p, Linear): - ard_params = p.variances - else: - ard_params = 1. / p.lengthscale - - x = np.arange(x0, x0 + len(ard_params)) - bars.append(ax.bar(x, ard_params, align='center', color=c, edgecolor='k', linewidth=1.2, label=p.name.replace("_"," "))) - xticklabels.extend([r"$\mathrm{{{name}}}\ {x}$".format(name=p.name, x=i) for i in np.arange(len(ard_params))]) - x0 += len(ard_params) - x = np.arange(x0) - transOffset = offset_copy(ax.transData, fig=fig, - x=0., y= -2., units='points') - transOffsetUp = offset_copy(ax.transData, fig=fig, - x=0., y=1., units='points') - for bar in bars: - for patch, num in zip(bar.patches, np.arange(len(bar.patches))): - height = patch.get_height() - xi = patch.get_x() + patch.get_width() / 2. - va = 'top' - c = 'w' - t = TextPath((0, 0), "${xi}$".format(xi=xi), rotation=0, usetex=True, ha='center') - transform = transOffset - if patch.get_extents().height <= t.get_extents().height + 3: - va = 'bottom' - c = 'k' - transform = transOffsetUp - ax.text(xi, height, "${xi}$".format(xi=int(num)), color=c, rotation=0, ha='center', va=va, transform=transform) - # for xi, t in zip(x, xticklabels): - # ax.text(xi, maxi / 2, t, rotation=90, ha='center', va='center') - # ax.set_xticklabels(xticklabels, rotation=17) - ax.set_xticks([]) - ax.set_xlim(-.5, x0 - .5) - if legend: - if title is '': - mode = 'expand' - if len(bars) > 1: - mode = 'expand' - ax.legend(bbox_to_anchor=(0., 1.02, 1., 1.02), loc=3, - ncol=len(bars), mode=mode, borderaxespad=0.) - fig.tight_layout(rect=(0, 0, 1, .9)) - else: - ax.legend() - return ax + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import kernel_plots + return kernel_plots.plot_ARD(self,*args) # def _transform_gradients(self, g): # """ @@ -530,61 +465,13 @@ class kern(Parameterized): return target_mu, target_S - def plot(self, x=None, plot_limits=None, which_parts='all', resolution=None, *args, **kwargs): - if which_parts == 'all': - which_parts = [True] * self.size - if self.input_dim == 1: - if x is None: - x = np.zeros((1, 1)) - else: - x = np.asarray(x) - assert x.size == 1, "The size of the fixed variable x is not 1" - x = x.reshape((1, 1)) - - if plot_limits == None: - xmin, xmax = (x - 5).flatten(), (x + 5).flatten() - elif len(plot_limits) == 2: - xmin, xmax = plot_limits - else: - raise ValueError, "Bad limits for plotting" - - Xnew = np.linspace(xmin, xmax, resolution or 201)[:, None] - Kx = self.K(Xnew, x, which_parts) - pb.plot(Xnew, Kx, *args, **kwargs) - pb.xlim(xmin, xmax) - pb.xlabel("x") - pb.ylabel("k(x,%0.1f)" % x) - - elif self.input_dim == 2: - if x is None: - x = np.zeros((1, 2)) - else: - x = np.asarray(x) - assert x.size == 2, "The size of the fixed variable x is not 2" - x = x.reshape((1, 2)) - - if plot_limits == None: - xmin, xmax = (x - 5).flatten(), (x + 5).flatten() - elif len(plot_limits) == 2: - xmin, xmax = plot_limits - else: - raise ValueError, "Bad limits for plotting" - - resolution = resolution or 51 - xx, yy = np.mgrid[xmin[0]:xmax[0]:1j * resolution, xmin[1]:xmax[1]:1j * resolution] - xg = np.linspace(xmin[0], xmax[0], resolution) - yg = np.linspace(xmin[1], xmax[1], resolution) - Xnew = np.vstack((xx.flatten(), yy.flatten())).T - Kx = self.K(Xnew, x, which_parts) - Kx = Kx.reshape(resolution, resolution).T - pb.contour(xg, yg, Kx, vmin=Kx.min(), vmax=Kx.max(), cmap=pb.cm.jet, *args, **kwargs) # @UndefinedVariable - pb.xlim(xmin[0], xmax[0]) - pb.ylim(xmin[1], xmax[1]) - pb.xlabel("x1") - pb.ylabel("x2") - pb.title("k(x1,x2 ; %0.1f,%0.1f)" % (x[0, 0], x[0, 1])) - else: - raise NotImplementedError, "Cannot plot a kernel with more than two input dimensions" + def plot(self, *args, **kwargs): + """ + See GPy.plotting.matplot_dep.plot + """ + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import kernel_plots + kernel_plots.plot(self,*args) from GPy.core.model import Model From 016b4fc74f04b929b2c6756306e78aed1616a57d Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:42:01 +0000 Subject: [PATCH 19/26] Plotting functions modified --- GPy/likelihoods/likelihood.py | 2 -- GPy/likelihoods/link_functions.py | 1 - 2 files changed, 3 deletions(-) diff --git a/GPy/likelihoods/likelihood.py b/GPy/likelihoods/likelihood.py index 8ae3174e..b0ecfc37 100644 --- a/GPy/likelihoods/likelihood.py +++ b/GPy/likelihoods/likelihood.py @@ -4,8 +4,6 @@ import numpy as np from scipy import stats,special import scipy as sp -import pylab as pb -from ..util.plot import gpplot from ..util.univariate_Gaussian import std_norm_pdf,std_norm_cdf import link_functions from ..util.misc import chain_1, chain_2, chain_3 diff --git a/GPy/likelihoods/link_functions.py b/GPy/likelihoods/link_functions.py index 9c046223..2a1bf147 100644 --- a/GPy/likelihoods/link_functions.py +++ b/GPy/likelihoods/link_functions.py @@ -4,7 +4,6 @@ import numpy as np from scipy import stats import scipy as sp -import pylab as pb from GPy.util.univariate_Gaussian import std_norm_pdf,std_norm_cdf,inv_std_norm_cdf class GPTransformation(object): From bb0e2a6237fe46aec46887c07242e213c1b8d9e9 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:42:14 +0000 Subject: [PATCH 20/26] Plotting functions modified --- GPy/models/bayesian_gplvm.py | 83 ++++++++---------------------------- 1 file changed, 17 insertions(+), 66 deletions(-) diff --git a/GPy/models/bayesian_gplvm.py b/GPy/models/bayesian_gplvm.py index b806ea31..7a22b5ea 100644 --- a/GPy/models/bayesian_gplvm.py +++ b/GPy/models/bayesian_gplvm.py @@ -3,14 +3,12 @@ import numpy as np import itertools -from matplotlib import pyplot from gplvm import GPLVM from .. import kern from ..core import SparseGP from ..likelihoods import Gaussian from ..inference.optimization import SCG -from ..util import plot_latent, linalg -from ..util.plot_latent import most_significant_input_dimensions +from ..util import linalg from ..core.parameterization.variational import Normal class BayesianGPLVM(SparseGP, GPLVM): @@ -75,11 +73,11 @@ class BayesianGPLVM(SparseGP, GPLVM): # """ # Horizontally stacks the parameters in order to present them to the optimizer. # The resulting 1-input_dim array has this structure: -# +# # =============================================================== # | mu | S | Z | theta | beta | # =============================================================== -# +# # """ # x = np.hstack((self.X.flatten(), self.X_variance.flatten(), SparseGP._get_params(self))) # return x @@ -131,7 +129,13 @@ class BayesianGPLVM(SparseGP, GPLVM): # return np.hstack((self.dbound_dmuS.flatten(), self.dbound_dZtheta)) def plot_latent(self, plot_inducing=True, *args, **kwargs): - return plot_latent.plot_latent(self, plot_inducing=plot_inducing, *args, **kwargs) + """ + See GPy.plotting.matplot_dep.dim_reduction_plots.plot_latent + """ + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import dim_reduction_plots + + return dim_reduction_plots.plot_latent(self, plot_inducing=plot_inducing, *args, **kwargs) def do_test_latents(self, Y): """ @@ -190,65 +194,14 @@ class BayesianGPLVM(SparseGP, GPLVM): dK_dX[:, i] = self.kern.dK_dX(ones, Xnew, self.Z[i:i + 1, :]).sum(-1) return np.dot(dK_dX, self.Cpsi1Vf) - def plot_steepest_gradient_map(self, fignum=None, ax=None, which_indices=None, labels=None, data_labels=None, data_marker='o', data_s=40, resolution=20, aspect='auto', updates=False, ** kwargs): - input_1, input_2 = significant_dims = most_significant_input_dimensions(self, which_indices) + def plot_steepest_gradient_map(self, *args, ** kwargs): + """ + See GPy.plotting.matplot_dep.dim_reduction_plots.plot_steepest_gradient_map + """ + assert "matplotlib" in sys.modules, "matplotlib package has not been imported." + from ..plotting.matplot_dep import dim_reduction_plots - X = np.zeros((resolution ** 2, self.input_dim)) - indices = np.r_[:X.shape[0]] - if labels is None: - labels = range(self.output_dim) - - def plot_function(x): - X[:, significant_dims] = x - dmu_dX = self.dmu_dXnew(X) - argmax = np.argmax(dmu_dX, 1) - return dmu_dX[indices, argmax], np.array(labels)[argmax] - - if ax is None: - fig = pyplot.figure(num=fignum) - ax = fig.add_subplot(111) - - if data_labels is None: - data_labels = np.ones(self.num_data) - ulabels = [] - for lab in data_labels: - if not lab in ulabels: - ulabels.append(lab) - marker = itertools.cycle(list(data_marker)) - from GPy.util import Tango - for i, ul in enumerate(ulabels): - if type(ul) is np.string_: - this_label = ul - elif type(ul) is np.int64: - this_label = 'class %i' % ul - else: - this_label = 'class %i' % i - m = marker.next() - index = np.nonzero(data_labels == ul)[0] - x = self.X[index, input_1] - y = self.X[index, input_2] - ax.scatter(x, y, marker=m, s=data_s, color=Tango.nextMedium(), label=this_label) - - ax.set_xlabel('latent dimension %i' % input_1) - ax.set_ylabel('latent dimension %i' % input_2) - - from matplotlib.cm import get_cmap - from GPy.util.latent_space_visualizations.controllers.imshow_controller import ImAnnotateController - controller = ImAnnotateController(ax, - plot_function, - tuple(self.X.min(0)[:, significant_dims]) + tuple(self.X.max(0)[:, significant_dims]), - resolution=resolution, - aspect=aspect, - cmap=get_cmap('jet'), - **kwargs) - ax.legend() - ax.figure.tight_layout() - if updates: - pyplot.show() - clear = raw_input('Enter to continue') - if clear.lower() in 'yes' or clear == '': - controller.deactivate() - return controller.view + return dim_reduction_plots.plot_steepest_gradient_map(model,*args,**kwargs) def latent_cost_and_grad(mu_S, kern, Z, dL_dpsi0, dL_dpsi1, dL_dpsi2): """ @@ -304,5 +257,3 @@ def latent_grad(mu_S, kern, Z, dL_dpsi0, dL_dpsi1, dL_dpsi2): dlnS = S * (S0 + S1 + S2 - 0.5) + .5 return -np.hstack((dmu.flatten(), dlnS.flatten())) - - From 064a57f851a32b528c909ee7626a6165a614cca6 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:43:33 +0000 Subject: [PATCH 21/26] lines that call matplotlib were commented --- GPy/util/linalg.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/GPy/util/linalg.py b/GPy/util/linalg.py index 4cc2d7e3..b8c6a1df 100644 --- a/GPy/util/linalg.py +++ b/GPy/util/linalg.py @@ -279,14 +279,14 @@ def ppca(Y, Q, iterations=100): def ppca_missing_data_at_random(Y, Q, iters=100): """ EM implementation of Probabilistic pca for when there is missing data. - + Taken from .. math: \\mathbf{Y} = \mathbf{XW} + \\epsilon \\text{, where} \\epsilon = \\mathcal{N}(0, \\sigma^2 \mathbf{I}) - - :returns: X, W, sigma^2 + + :returns: X, W, sigma^2 """ from numpy.ma import dot as madot import diag @@ -300,19 +300,21 @@ def ppca_missing_data_at_random(Y, Q, iters=100): nu = 1. #num_obs_i = 1./Y.count() Ycentered = Y - Y.mean(0) - + X = np.zeros((N,Q)) cs = common_subarrays(Y.mask) cr = common_subarrays(Y.mask, 1) Sigma = np.zeros((N, Q, Q)) Sigma2 = np.zeros((N, Q, Q)) mu = np.zeros(D) + """ if debug: import matplotlib.pyplot as pylab - fig = pylab.figure("FIT MISSING DATA"); + fig = pylab.figure("FIT MISSING DATA"); ax = fig.gca() ax.cla() lines = pylab.plot(np.zeros((N,Q)).dot(W)) + """ W2 = np.zeros((Q,D)) for i in range(iters): @@ -358,6 +360,7 @@ def ppca_missing_data_at_random(Y, Q, iters=100): nu2 /= N nu4 = (((Ycentered - X.dot(W))**2).sum(0) + W.T.dot(Sigma.sum(0).dot(W)).sum(0)).sum()/N import ipdb;ipdb.set_trace() + """ if debug: #print Sigma[0] print "nu:", nu, "sum(X):", X.sum() @@ -368,6 +371,7 @@ def ppca_missing_data_at_random(Y, Q, iters=100): ax.set_ylim(pred_y.min(), pred_y.max()) fig.canvas.draw() time.sleep(.3) + """ return np.asarray_chkfinite(X), np.asarray_chkfinite(W), nu From 73546f2408dbd61f68f43e75814ed432b6cf54f0 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:43:58 +0000 Subject: [PATCH 22/26] Changes according to files reloaction --- GPy/util/__init__.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/GPy/util/__init__.py b/GPy/util/__init__.py index 398dd252..c25b1349 100644 --- a/GPy/util/__init__.py +++ b/GPy/util/__init__.py @@ -4,21 +4,12 @@ import linalg import misc -import plot import squashers -import Tango import warping_functions import datasets import mocap -import visualize import decorators import classification -import latent_space_visualizations -try: - import maps -except: - pass - maps = "warning: the maps module requires pyshp (shapefile). Install it to remove this message" try: import sympy @@ -29,5 +20,3 @@ except ImportError as e: if _sympy_available: import symbolic - -import netpbmfile From 7782f6288591355047b19696762677dcb31cd121 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:44:10 +0000 Subject: [PATCH 23/26] Files relocated --- GPy/plotting/matplotlib/plot.py | 135 ----- GPy/util/Tango.py | 166 ------ .../latent_space_visualizations/__init__.py | 1 - .../controllers/__init__.py | 1 - .../controllers/axis_event_controller.py | 142 ----- .../controllers/imshow_controller.py | 71 --- GPy/util/maps.py | 161 ------ GPy/util/netpbmfile.py | 331 ----------- GPy/util/plot_latent.py | 181 ------ GPy/util/visualize.py | 538 ------------------ 10 files changed, 1727 deletions(-) delete mode 100644 GPy/plotting/matplotlib/plot.py delete mode 100644 GPy/util/Tango.py delete mode 100644 GPy/util/latent_space_visualizations/__init__.py delete mode 100644 GPy/util/latent_space_visualizations/controllers/__init__.py delete mode 100644 GPy/util/latent_space_visualizations/controllers/axis_event_controller.py delete mode 100644 GPy/util/latent_space_visualizations/controllers/imshow_controller.py delete mode 100644 GPy/util/maps.py delete mode 100644 GPy/util/netpbmfile.py delete mode 100644 GPy/util/plot_latent.py delete mode 100644 GPy/util/visualize.py diff --git a/GPy/plotting/matplotlib/plot.py b/GPy/plotting/matplotlib/plot.py deleted file mode 100644 index f44864f3..00000000 --- a/GPy/plotting/matplotlib/plot.py +++ /dev/null @@ -1,135 +0,0 @@ -# #Copyright (c) 2012, GPy authors (see AUTHORS.txt). -# Licensed under the BSD 3-clause license (see LICENSE.txt) - - -import Tango -import pylab as pb -import numpy as np - -def gpplot(x,mu,lower,upper,edgecol=Tango.colorsHex['darkBlue'],fillcol=Tango.colorsHex['lightBlue'],axes=None,**kwargs): - if axes is None: - axes = pb.gca() - mu = mu.flatten() - x = x.flatten() - lower = lower.flatten() - upper = upper.flatten() - - #here's the mean - axes.plot(x,mu,color=edgecol,linewidth=2) - - #here's the box - kwargs['linewidth']=0.5 - if not 'alpha' in kwargs.keys(): - kwargs['alpha'] = 0.3 - axes.fill(np.hstack((x,x[::-1])),np.hstack((upper,lower[::-1])),color=fillcol,**kwargs) - - #this is the edge: - axes.plot(x,upper,color=edgecol,linewidth=0.2) - axes.plot(x,lower,color=edgecol,linewidth=0.2) - -def removeRightTicks(ax=None): - ax = ax or pb.gca() - for i, line in enumerate(ax.get_yticklines()): - if i%2 == 1: # odd indices - line.set_visible(False) -def removeUpperTicks(ax=None): - ax = ax or pb.gca() - for i, line in enumerate(ax.get_xticklines()): - if i%2 == 1: # odd indices - line.set_visible(False) -def fewerXticks(ax=None,divideby=2): - ax = ax or pb.gca() - ax.set_xticks(ax.get_xticks()[::divideby]) - -def align_subplots(N,M,xlim=None, ylim=None): - """make all of the subplots have the same limits, turn off unnecessary ticks""" - #find sensible xlim,ylim - if xlim is None: - xlim = [np.inf,-np.inf] - for i in range(N*M): - pb.subplot(N,M,i+1) - xlim[0] = min(xlim[0],pb.xlim()[0]) - xlim[1] = max(xlim[1],pb.xlim()[1]) - if ylim is None: - ylim = [np.inf,-np.inf] - for i in range(N*M): - pb.subplot(N,M,i+1) - ylim[0] = min(ylim[0],pb.ylim()[0]) - ylim[1] = max(ylim[1],pb.ylim()[1]) - - for i in range(N*M): - pb.subplot(N,M,i+1) - pb.xlim(xlim) - pb.ylim(ylim) - if (i)%M: - pb.yticks([]) - else: - removeRightTicks() - if i<(M*(N-1)): - pb.xticks([]) - else: - removeUpperTicks() - -def align_subplot_array(axes,xlim=None, ylim=None): - """make all of the axes in the array hae the same limits, turn off unnecessary ticks - - use pb.subplots() to get an array of axes - """ - #find sensible xlim,ylim - if xlim is None: - xlim = [np.inf,-np.inf] - for ax in axes.flatten(): - xlim[0] = min(xlim[0],ax.get_xlim()[0]) - xlim[1] = max(xlim[1],ax.get_xlim()[1]) - if ylim is None: - ylim = [np.inf,-np.inf] - for ax in axes.flatten(): - ylim[0] = min(ylim[0],ax.get_ylim()[0]) - ylim[1] = max(ylim[1],ax.get_ylim()[1]) - - N,M = axes.shape - for i,ax in enumerate(axes.flatten()): - ax.set_xlim(xlim) - ax.set_ylim(ylim) - if (i)%M: - ax.set_yticks([]) - else: - removeRightTicks(ax) - if i<(M*(N-1)): - ax.set_xticks([]) - else: - removeUpperTicks(ax) - -def x_frame1D(X,plot_limits=None,resolution=None): - """ - Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits - """ - assert X.shape[1] ==1, "x_frame1D is defined for one-dimensional inputs" - if plot_limits is None: - xmin,xmax = X.min(0),X.max(0) - xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin) - elif len(plot_limits)==2: - xmin, xmax = plot_limits - else: - raise ValueError, "Bad limits for plotting" - - Xnew = np.linspace(xmin,xmax,resolution or 200)[:,None] - return Xnew, xmin, xmax - -def x_frame2D(X,plot_limits=None,resolution=None): - """ - Internal helper function for making plots, returns a set of input values to plot as well as lower and upper limits - """ - assert X.shape[1] ==2, "x_frame2D is defined for two-dimensional inputs" - if plot_limits is None: - xmin,xmax = X.min(0),X.max(0) - xmin, xmax = xmin-0.2*(xmax-xmin), xmax+0.2*(xmax-xmin) - elif len(plot_limits)==2: - xmin, xmax = plot_limits - else: - raise ValueError, "Bad limits for plotting" - - resolution = resolution or 50 - xx,yy = np.mgrid[xmin[0]:xmax[0]:1j*resolution,xmin[1]:xmax[1]:1j*resolution] - Xnew = np.vstack((xx.flatten(),yy.flatten())).T - return Xnew, xx, yy, xmin, xmax diff --git a/GPy/util/Tango.py b/GPy/util/Tango.py deleted file mode 100644 index eeb2e075..00000000 --- a/GPy/util/Tango.py +++ /dev/null @@ -1,166 +0,0 @@ -# Copyright (c) 2012, GPy authors (see AUTHORS.txt). -# Licensed under the BSD 3-clause license (see LICENSE.txt) - - -import matplotlib as mpl -import pylab as pb -import sys -#sys.path.append('/home/james/mlprojects/sitran_cluster/') -#from switch_pylab_backend import * - - -#this stuff isn;t really Tango related: maybe it could be moved out? TODO -def removeRightTicks(ax=None): - ax = ax or pb.gca() - for i, line in enumerate(ax.get_yticklines()): - if i%2 == 1: # odd indices - line.set_visible(False) -def removeUpperTicks(ax=None): - ax = ax or pb.gca() - for i, line in enumerate(ax.get_xticklines()): - if i%2 == 1: # odd indices - line.set_visible(False) -def fewerXticks(ax=None,divideby=2): - ax = ax or pb.gca() - ax.set_xticks(ax.get_xticks()[::divideby]) - - -colorsHex = {\ -"Aluminium6":"#2e3436",\ -"Aluminium5":"#555753",\ -"Aluminium4":"#888a85",\ -"Aluminium3":"#babdb6",\ -"Aluminium2":"#d3d7cf",\ -"Aluminium1":"#eeeeec",\ -"lightPurple":"#ad7fa8",\ -"mediumPurple":"#75507b",\ -"darkPurple":"#5c3566",\ -"lightBlue":"#729fcf",\ -"mediumBlue":"#3465a4",\ -"darkBlue": "#204a87",\ -"lightGreen":"#8ae234",\ -"mediumGreen":"#73d216",\ -"darkGreen":"#4e9a06",\ -"lightChocolate":"#e9b96e",\ -"mediumChocolate":"#c17d11",\ -"darkChocolate":"#8f5902",\ -"lightRed":"#ef2929",\ -"mediumRed":"#cc0000",\ -"darkRed":"#a40000",\ -"lightOrange":"#fcaf3e",\ -"mediumOrange":"#f57900",\ -"darkOrange":"#ce5c00",\ -"lightButter":"#fce94f",\ -"mediumButter":"#edd400",\ -"darkButter":"#c4a000"} - -darkList = [colorsHex['darkBlue'],colorsHex['darkRed'],colorsHex['darkGreen'], colorsHex['darkOrange'], colorsHex['darkButter'], colorsHex['darkPurple'], colorsHex['darkChocolate'], colorsHex['Aluminium6']] -mediumList = [colorsHex['mediumBlue'], colorsHex['mediumRed'],colorsHex['mediumGreen'], colorsHex['mediumOrange'], colorsHex['mediumButter'], colorsHex['mediumPurple'], colorsHex['mediumChocolate'], colorsHex['Aluminium5']] -lightList = [colorsHex['lightBlue'], colorsHex['lightRed'],colorsHex['lightGreen'], colorsHex['lightOrange'], colorsHex['lightButter'], colorsHex['lightPurple'], colorsHex['lightChocolate'], colorsHex['Aluminium4']] - -def currentDark(): - return darkList[-1] -def currentMedium(): - return mediumList[-1] -def currentLight(): - return lightList[-1] - -def nextDark(): - darkList.append(darkList.pop(0)) - return darkList[-1] -def nextMedium(): - mediumList.append(mediumList.pop(0)) - return mediumList[-1] -def nextLight(): - lightList.append(lightList.pop(0)) - return lightList[-1] - -def reset(): - while not darkList[0]==colorsHex['darkBlue']: - darkList.append(darkList.pop(0)) - while not mediumList[0]==colorsHex['mediumBlue']: - mediumList.append(mediumList.pop(0)) - while not lightList[0]==colorsHex['lightBlue']: - lightList.append(lightList.pop(0)) - -def setLightFigures(): - mpl.rcParams['axes.edgecolor']=colorsHex['Aluminium6'] - mpl.rcParams['axes.facecolor']=colorsHex['Aluminium2'] - mpl.rcParams['axes.labelcolor']=colorsHex['Aluminium6'] - mpl.rcParams['figure.edgecolor']=colorsHex['Aluminium6'] - mpl.rcParams['figure.facecolor']=colorsHex['Aluminium2'] - mpl.rcParams['grid.color']=colorsHex['Aluminium6'] - mpl.rcParams['savefig.edgecolor']=colorsHex['Aluminium2'] - mpl.rcParams['savefig.facecolor']=colorsHex['Aluminium2'] - mpl.rcParams['text.color']=colorsHex['Aluminium6'] - mpl.rcParams['xtick.color']=colorsHex['Aluminium6'] - mpl.rcParams['ytick.color']=colorsHex['Aluminium6'] - -def setDarkFigures(): - mpl.rcParams['axes.edgecolor']=colorsHex['Aluminium2'] - mpl.rcParams['axes.facecolor']=colorsHex['Aluminium6'] - mpl.rcParams['axes.labelcolor']=colorsHex['Aluminium2'] - mpl.rcParams['figure.edgecolor']=colorsHex['Aluminium2'] - mpl.rcParams['figure.facecolor']=colorsHex['Aluminium6'] - mpl.rcParams['grid.color']=colorsHex['Aluminium2'] - mpl.rcParams['savefig.edgecolor']=colorsHex['Aluminium6'] - mpl.rcParams['savefig.facecolor']=colorsHex['Aluminium6'] - mpl.rcParams['text.color']=colorsHex['Aluminium2'] - mpl.rcParams['xtick.color']=colorsHex['Aluminium2'] - mpl.rcParams['ytick.color']=colorsHex['Aluminium2'] - -def hex2rgb(hexcolor): - hexcolor = [hexcolor[1+2*i:1+2*(i+1)] for i in range(3)] - r,g,b = [int(n,16) for n in hexcolor] - return (r,g,b) - -colorsRGB = dict([(k,hex2rgb(i)) for k,i in colorsHex.items()]) - -cdict_RB = {'red' :((0.,colorsRGB['mediumRed'][0]/256.,colorsRGB['mediumRed'][0]/256.), - (.5,colorsRGB['mediumPurple'][0]/256.,colorsRGB['mediumPurple'][0]/256.), - (1.,colorsRGB['mediumBlue'][0]/256.,colorsRGB['mediumBlue'][0]/256.)), - 'green':((0.,colorsRGB['mediumRed'][1]/256.,colorsRGB['mediumRed'][1]/256.), - (.5,colorsRGB['mediumPurple'][1]/256.,colorsRGB['mediumPurple'][1]/256.), - (1.,colorsRGB['mediumBlue'][1]/256.,colorsRGB['mediumBlue'][1]/256.)), - 'blue':((0.,colorsRGB['mediumRed'][2]/256.,colorsRGB['mediumRed'][2]/256.), - (.5,colorsRGB['mediumPurple'][2]/256.,colorsRGB['mediumPurple'][2]/256.), - (1.,colorsRGB['mediumBlue'][2]/256.,colorsRGB['mediumBlue'][2]/256.))} - -cdict_BGR = {'red' :((0.,colorsRGB['mediumBlue'][0]/256.,colorsRGB['mediumBlue'][0]/256.), - (.5,colorsRGB['mediumGreen'][0]/256.,colorsRGB['mediumGreen'][0]/256.), - (1.,colorsRGB['mediumRed'][0]/256.,colorsRGB['mediumRed'][0]/256.)), - 'green':((0.,colorsRGB['mediumBlue'][1]/256.,colorsRGB['mediumBlue'][1]/256.), - (.5,colorsRGB['mediumGreen'][1]/256.,colorsRGB['mediumGreen'][1]/256.), - (1.,colorsRGB['mediumRed'][1]/256.,colorsRGB['mediumRed'][1]/256.)), - 'blue':((0.,colorsRGB['mediumBlue'][2]/256.,colorsRGB['mediumBlue'][2]/256.), - (.5,colorsRGB['mediumGreen'][2]/256.,colorsRGB['mediumGreen'][2]/256.), - (1.,colorsRGB['mediumRed'][2]/256.,colorsRGB['mediumRed'][2]/256.))} - - -cdict_Alu = {'red' :((0./5,colorsRGB['Aluminium1'][0]/256.,colorsRGB['Aluminium1'][0]/256.), - (1./5,colorsRGB['Aluminium2'][0]/256.,colorsRGB['Aluminium2'][0]/256.), - (2./5,colorsRGB['Aluminium3'][0]/256.,colorsRGB['Aluminium3'][0]/256.), - (3./5,colorsRGB['Aluminium4'][0]/256.,colorsRGB['Aluminium4'][0]/256.), - (4./5,colorsRGB['Aluminium5'][0]/256.,colorsRGB['Aluminium5'][0]/256.), - (5./5,colorsRGB['Aluminium6'][0]/256.,colorsRGB['Aluminium6'][0]/256.)), - 'green' :((0./5,colorsRGB['Aluminium1'][1]/256.,colorsRGB['Aluminium1'][1]/256.), - (1./5,colorsRGB['Aluminium2'][1]/256.,colorsRGB['Aluminium2'][1]/256.), - (2./5,colorsRGB['Aluminium3'][1]/256.,colorsRGB['Aluminium3'][1]/256.), - (3./5,colorsRGB['Aluminium4'][1]/256.,colorsRGB['Aluminium4'][1]/256.), - (4./5,colorsRGB['Aluminium5'][1]/256.,colorsRGB['Aluminium5'][1]/256.), - (5./5,colorsRGB['Aluminium6'][1]/256.,colorsRGB['Aluminium6'][1]/256.)), - 'blue' :((0./5,colorsRGB['Aluminium1'][2]/256.,colorsRGB['Aluminium1'][2]/256.), - (1./5,colorsRGB['Aluminium2'][2]/256.,colorsRGB['Aluminium2'][2]/256.), - (2./5,colorsRGB['Aluminium3'][2]/256.,colorsRGB['Aluminium3'][2]/256.), - (3./5,colorsRGB['Aluminium4'][2]/256.,colorsRGB['Aluminium4'][2]/256.), - (4./5,colorsRGB['Aluminium5'][2]/256.,colorsRGB['Aluminium5'][2]/256.), - (5./5,colorsRGB['Aluminium6'][2]/256.,colorsRGB['Aluminium6'][2]/256.))} -# cmap_Alu = mpl.colors.LinearSegmentedColormap('TangoAluminium',cdict_Alu,256) -# cmap_BGR = mpl.colors.LinearSegmentedColormap('TangoRedBlue',cdict_BGR,256) -# cmap_RB = mpl.colors.LinearSegmentedColormap('TangoRedBlue',cdict_RB,256) -if __name__=='__main__': - import pylab as pb - pb.figure() - pb.pcolor(pb.rand(10,10),cmap=cmap_RB) - pb.colorbar() - pb.show() diff --git a/GPy/util/latent_space_visualizations/__init__.py b/GPy/util/latent_space_visualizations/__init__.py deleted file mode 100644 index ee595945..00000000 --- a/GPy/util/latent_space_visualizations/__init__.py +++ /dev/null @@ -1 +0,0 @@ -import controllers diff --git a/GPy/util/latent_space_visualizations/controllers/__init__.py b/GPy/util/latent_space_visualizations/controllers/__init__.py deleted file mode 100644 index 25f6535e..00000000 --- a/GPy/util/latent_space_visualizations/controllers/__init__.py +++ /dev/null @@ -1 +0,0 @@ -import axis_event_controller, imshow_controller diff --git a/GPy/util/latent_space_visualizations/controllers/axis_event_controller.py b/GPy/util/latent_space_visualizations/controllers/axis_event_controller.py deleted file mode 100644 index acb1ac8d..00000000 --- a/GPy/util/latent_space_visualizations/controllers/axis_event_controller.py +++ /dev/null @@ -1,142 +0,0 @@ -''' -Created on 24 Jul 2013 - -@author: maxz -''' -import numpy - -class AxisEventController(object): - def __init__(self, ax): - self.ax = ax - self.activate() - def deactivate(self): - for cb_class in self.ax.callbacks.callbacks.values(): - for cb_num in cb_class.keys(): - self.ax.callbacks.disconnect(cb_num) - def activate(self): - self.ax.callbacks.connect('xlim_changed', self.xlim_changed) - self.ax.callbacks.connect('ylim_changed', self.ylim_changed) - def xlim_changed(self, ax): - pass - def ylim_changed(self, ax): - pass - - -class AxisChangedController(AxisEventController): - ''' - Buffered control of axis limit changes - ''' - _changing = False - - def __init__(self, ax, update_lim=None): - ''' - Constructor - ''' - super(AxisChangedController, self).__init__(ax) - self._lim_ratio_threshold = update_lim or .8 - self._x_lim = self.ax.get_xlim() - self._y_lim = self.ax.get_ylim() - - def update(self, ax): - pass - - def xlim_changed(self, ax): - super(AxisChangedController, self).xlim_changed(ax) - if not self._changing and self.lim_changed(ax.get_xlim(), self._x_lim): - self._changing = True - self._x_lim = ax.get_xlim() - self.update(ax) - self._changing = False - - def ylim_changed(self, ax): - super(AxisChangedController, self).ylim_changed(ax) - if not self._changing and self.lim_changed(ax.get_ylim(), self._y_lim): - self._changing = True - self._y_lim = ax.get_ylim() - self.update(ax) - self._changing = False - - def extent(self, lim): - return numpy.subtract(*lim) - - def lim_changed(self, axlim, savedlim): - axextent = self.extent(axlim) - extent = self.extent(savedlim) - lim_changed = ((axextent / extent) < self._lim_ratio_threshold ** 2 - or (extent / axextent) < self._lim_ratio_threshold ** 2 - or ((1 - (self.extent((axlim[0], savedlim[0])) / self.extent((savedlim[0], axlim[1])))) - < self._lim_ratio_threshold) - or ((1 - (self.extent((savedlim[0], axlim[0])) / self.extent((axlim[0], savedlim[1])))) - < self._lim_ratio_threshold) - ) - return lim_changed - - def _buffer_lim(self, lim): - # buffer_size = 1 - self._lim_ratio_threshold - # extent = self.extent(lim) - return lim - - -class BufferedAxisChangedController(AxisChangedController): - def __init__(self, ax, plot_function, plot_limits, resolution=50, update_lim=None, **kwargs): - """ - :param plot_function: - function to use for creating image for plotting (return ndarray-like) - plot_function gets called with (2D!) Xtest grid if replotting required - :type plot_function: function - :param plot_limits: - beginning plot limits [xmin, ymin, xmax, ymax] - - :param kwargs: additional kwargs are for pyplot.imshow(**kwargs) - """ - super(BufferedAxisChangedController, self).__init__(ax, update_lim=update_lim) - self.plot_function = plot_function - xmin, xmax = self._x_lim # self._compute_buffered(*self._x_lim) - ymin, ymax = self._y_lim # self._compute_buffered(*self._y_lim) - self.resolution = resolution - self._not_init = False - self.view = self._init_view(self.ax, self.recompute_X(), xmin, xmax, ymin, ymax, **kwargs) - self._not_init = True - - def update(self, ax): - super(BufferedAxisChangedController, self).update(ax) - if self._not_init: - xmin, xmax = self._compute_buffered(*self._x_lim) - ymin, ymax = self._compute_buffered(*self._y_lim) - self.update_view(self.view, self.recompute_X(), xmin, xmax, ymin, ymax) - - def _init_view(self, ax, X, xmin, xmax, ymin, ymax): - raise NotImplementedError('return view for this controller') - - def update_view(self, view, X, xmin, xmax, ymin, ymax): - raise NotImplementedError('update view given in here') - - def get_grid(self): - xmin, xmax = self._compute_buffered(*self._x_lim) - ymin, ymax = self._compute_buffered(*self._y_lim) - x, y = numpy.mgrid[xmin:xmax:1j * self.resolution, ymin:ymax:1j * self.resolution] - return numpy.hstack((x.flatten()[:, None], y.flatten()[:, None])) - - def recompute_X(self): - X = self.plot_function(self.get_grid()) - 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, :] - - def _compute_buffered(self, mi, ma): - buffersize = self._buffersize() - size = ma - mi - return mi - (buffersize * size), ma + (buffersize * size) - - def _buffersize(self): - try: - buffersize = 1. - self._lim_ratio_threshold - except: - buffersize = .4 - return buffersize - - - diff --git a/GPy/util/latent_space_visualizations/controllers/imshow_controller.py b/GPy/util/latent_space_visualizations/controllers/imshow_controller.py deleted file mode 100644 index fa6682e9..00000000 --- a/GPy/util/latent_space_visualizations/controllers/imshow_controller.py +++ /dev/null @@ -1,71 +0,0 @@ -''' -Created on 24 Jul 2013 - -@author: maxz -''' -from GPy.util.latent_space_visualizations.controllers.axis_event_controller import BufferedAxisChangedController -import itertools -import numpy - - -class ImshowController(BufferedAxisChangedController): - def __init__(self, ax, plot_function, plot_limits, resolution=50, update_lim=.5, **kwargs): - """ - :param plot_function: - function to use for creating image for plotting (return ndarray-like) - plot_function gets called with (2D!) Xtest grid if replotting required - :type plot_function: function - :param plot_limits: - beginning plot limits [xmin, ymin, xmax, ymax] - - :param kwargs: additional kwargs are for pyplot.imshow(**kwargs) - """ - super(ImshowController, self).__init__(ax, plot_function, plot_limits, resolution, update_lim, **kwargs) - - def _init_view(self, ax, X, xmin, xmax, ymin, ymax, **kwargs): - return ax.imshow(X, extent=(xmin, xmax, - ymin, ymax), - vmin=X.min(), - vmax=X.max(), - **kwargs) - - def update_view(self, view, X, xmin, xmax, ymin, ymax): - view.set_data(X) - view.set_extent((xmin, xmax, ymin, ymax)) - -class ImAnnotateController(ImshowController): - def __init__(self, ax, plot_function, plot_limits, resolution=20, update_lim=.99, **kwargs): - """ - :param plot_function: - function to use for creating image for plotting (return ndarray-like) - plot_function gets called with (2D!) Xtest grid if replotting required - :type plot_function: function - :param plot_limits: - beginning plot limits [xmin, ymin, xmax, ymax] - :param text_props: kwargs for pyplot.text(**text_props) - :param kwargs: additional kwargs are for pyplot.imshow(**kwargs) - """ - 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)] - 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)) - return view - - def update_view(self, view, X, xmin, xmax, ymin, ymax): - super(ImAnnotateController, self).update_view(view[0], X[0], xmin, xmax, ymin, ymax) - 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]], text in itertools.izip(itertools.product(enumerate(xlin), enumerate(ylin[::-1])), view[1:]): - text.set_x(x + xoffset) - text.set_y(y + yoffset) - text.set_text("{}".format(X[1][j, i])) - return view - - def _offsets(self, xmin, xmax, ymin, ymax): - return (xmax - xmin) / (2 * self.resolution), (ymax - ymin) / (2 * self.resolution) diff --git a/GPy/util/maps.py b/GPy/util/maps.py deleted file mode 100644 index e18c7e68..00000000 --- a/GPy/util/maps.py +++ /dev/null @@ -1,161 +0,0 @@ -import numpy as np -import pylab as pb -import matplotlib.patches as patches -from matplotlib.patches import Polygon -from matplotlib.collections import PatchCollection -#from matplotlib import cm -import shapefile -import re - -pb.ion() - -def plot(shape_records,facecolor='w',edgecolor='k',linewidths=.5, ax=None,xlims=None,ylims=None): - """ - Plot the geometry of a shapefile - - :param shape_records: geometry and attributes list - :type shape_records: ShapeRecord object (output of a shapeRecords() method) - :param facecolor: color to be used to fill in polygons - :param edgecolor: color to be used for lines - :param ax: axes to plot on. - :type ax: axes handle - """ - #Axes handle - if ax is None: - fig = pb.figure() - ax = fig.add_subplot(111) - - #Iterate over shape_records - for srec in shape_records: - points = np.vstack(srec.shape.points) - sparts = srec.shape.parts - par = list(sparts) + [points.shape[0]] - - polygs = [] - for pj in xrange(len(sparts)): - polygs.append(Polygon(points[par[pj]:par[pj+1]])) - ax.add_collection(PatchCollection(polygs,facecolor=facecolor,edgecolor=edgecolor, linewidths=linewidths)) - - #Plot limits - _box = np.vstack([srec.shape.bbox for srec in shape_records]) - minx,miny = np.min(_box[:,:2],0) - maxx,maxy = np.max(_box[:,2:],0) - - if xlims is not None: - minx,maxx = xlims - if ylims is not None: - miny,maxy = ylims - ax.set_xlim(minx,maxx) - ax.set_ylim(miny,maxy) - - -def string_match(sf,regex,field=2): - """ - Return the geometry and attributes of a shapefile whose fields match a regular expression given - - :param sf: shapefile - :type sf: shapefile object - :regex: regular expression to match - :type regex: string - :field: field number to be matched with the regex - :type field: integer - """ - index = [] - shape_records = [] - for rec in enumerate(sf.shapeRecords()): - m = re.search(regex,rec[1].record[field]) - if m is not None: - index.append(rec[0]) - shape_records.append(rec[1]) - return index,shape_records - -def bbox_match(sf,bbox,inside_only=True): - """ - Return the geometry and attributes of a shapefile that lie within (or intersect) a bounding box - - :param sf: shapefile - :type sf: shapefile object - :param bbox: bounding box - :type bbox: list of floats [x_min,y_min,x_max,y_max] - :inside_only: True if the objects returned are those that lie within the bbox and False if the objects returned are any that intersect the bbox - :type inside_only: Boolean - """ - A,B,C,D = bbox - index = [] - shape_records = [] - for rec in enumerate(sf.shapeRecords()): - a,b,c,d = rec[1].shape.bbox - if inside_only: - if A <= a and B <= b and C >= c and D >= d: - index.append(rec[0]) - shape_records.append(rec[1]) - else: - cond1 = A <= a and B <= b and C >= a and D >= b - cond2 = A <= c and B <= d and C >= c and D >= d - cond3 = A <= a and D >= d and C >= a and B <= d - cond4 = A <= c and D >= b and C >= c and B <= b - cond5 = a <= C and b <= B and d >= D - cond6 = c <= A and b <= B and d >= D - cond7 = d <= B and a <= A and c >= C - cond8 = b <= D and a <= A and c >= C - if cond1 or cond2 or cond3 or cond4 or cond5 or cond6 or cond7 or cond8: - index.append(rec[0]) - shape_records.append(rec[1]) - return index,shape_records - - -def plot_bbox(sf,bbox,inside_only=True): - """ - Plot the geometry of a shapefile within a bbox - - :param sf: shapefile - :type sf: shapefile object - :param bbox: bounding box - :type bbox: list of floats [x_min,y_min,x_max,y_max] - :inside_only: True if the objects returned are those that lie within the bbox and False if the objects returned are any that intersect the bbox - :type inside_only: Boolean - """ - index,shape_records = bbox_match(sf,bbox,inside_only) - A,B,C,D = bbox - plot(shape_records,xlims=[bbox[0],bbox[2]],ylims=[bbox[1],bbox[3]]) - -def plot_string_match(sf,regex,field): - """ - Plot the geometry of a shapefile whose fields match a regular expression given - - :param sf: shapefile - :type sf: shapefile object - :regex: regular expression to match - :type regex: string - :field: field number to be matched with the regex - :type field: integer - """ - index,shape_records = string_match(sf,regex,field) - plot(shape_records) - - -def new_shape_string(sf,name,regex,field=2,type=shapefile.POINT): - - newshp = shapefile.Writer(shapeType = sf.shapeType) - newshp.autoBalance = 1 - - index,shape_records = string_match(sf,regex,field) - - _fi = [sf.fields[j] for j in index] - for f in _fi: - newshp.field(name=f[0],fieldType=f[1],size=f[2],decimal=f[3]) - - _shre = shape_records - for sr in _shre: - _points = [] - _parts = [] - for point in sr.shape.points: - _points.append(point) - _parts.append(_points) - - newshp.line(parts=_parts) - newshp.records.append(sr.record) - print len(sr.record) - - newshp.save(name) - print index diff --git a/GPy/util/netpbmfile.py b/GPy/util/netpbmfile.py deleted file mode 100644 index 030bd574..00000000 --- a/GPy/util/netpbmfile.py +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# netpbmfile.py - -# Copyright (c) 2011-2013, Christoph Gohlke -# Copyright (c) 2011-2013, The Regents of the University of California -# Produced at the Laboratory for Fluorescence Dynamics. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the copyright holders nor the names of any -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - -"""Read and write image data from respectively to Netpbm files. - -This implementation follows the Netpbm format specifications at -http://netpbm.sourceforge.net/doc/. No gamma correction is performed. - -The following image formats are supported: PBM (bi-level), PGM (grayscale), -PPM (color), PAM (arbitrary), XV thumbnail (RGB332, read-only). - -:Author: - `Christoph Gohlke `_ - -:Organization: - Laboratory for Fluorescence Dynamics, University of California, Irvine - -:Version: 2013.01.18 - -Requirements ------------- -* `CPython 2.7, 3.2 or 3.3 `_ -* `Numpy 1.7 `_ -* `Matplotlib 1.2 `_ (optional for plotting) - -Examples --------- ->>> im1 = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16) ->>> imsave('_tmp.pgm', im1) ->>> im2 = imread('_tmp.pgm') ->>> assert numpy.all(im1 == im2) - -""" - -from __future__ import division, print_function - -import sys -import re -import math -from copy import deepcopy - -import numpy - -__version__ = '2013.01.18' -__docformat__ = 'restructuredtext en' -__all__ = ['imread', 'imsave', 'NetpbmFile'] - - -def imread(filename, *args, **kwargs): - """Return image data from Netpbm file as numpy array. - - `args` and `kwargs` are arguments to NetpbmFile.asarray(). - - Examples - -------- - >>> image = imread('_tmp.pgm') - - """ - try: - netpbm = NetpbmFile(filename) - image = netpbm.asarray() - finally: - netpbm.close() - return image - - -def imsave(filename, data, maxval=None, pam=False): - """Write image data to Netpbm file. - - Examples - -------- - >>> image = numpy.array([[0, 1],[65534, 65535]], dtype=numpy.uint16) - >>> imsave('_tmp.pgm', image) - - """ - try: - netpbm = NetpbmFile(data, maxval=maxval) - netpbm.write(filename, pam=pam) - finally: - netpbm.close() - - -class NetpbmFile(object): - """Read and write Netpbm PAM, PBM, PGM, PPM, files.""" - - _types = {b'P1': b'BLACKANDWHITE', b'P2': b'GRAYSCALE', b'P3': b'RGB', - b'P4': b'BLACKANDWHITE', b'P5': b'GRAYSCALE', b'P6': b'RGB', - b'P7 332': b'RGB', b'P7': b'RGB_ALPHA'} - - def __init__(self, arg=None, **kwargs): - """Initialize instance from filename, open file, or numpy array.""" - for attr in ('header', 'magicnum', 'width', 'height', 'maxval', - 'depth', 'tupltypes', '_filename', '_fh', '_data'): - setattr(self, attr, None) - if arg is None: - self._fromdata([], **kwargs) - elif isinstance(arg, basestring): - self._fh = open(arg, 'rb') - self._filename = arg - self._fromfile(self._fh, **kwargs) - elif hasattr(arg, 'seek'): - self._fromfile(arg, **kwargs) - self._fh = arg - else: - self._fromdata(arg, **kwargs) - - def asarray(self, copy=True, cache=False, **kwargs): - """Return image data from file as numpy array.""" - data = self._data - if data is None: - data = self._read_data(self._fh, **kwargs) - if cache: - self._data = data - else: - return data - return deepcopy(data) if copy else data - - def write(self, arg, **kwargs): - """Write instance to file.""" - if hasattr(arg, 'seek'): - self._tofile(arg, **kwargs) - else: - with open(arg, 'wb') as fid: - self._tofile(fid, **kwargs) - - def close(self): - """Close open file. Future asarray calls might fail.""" - if self._filename and self._fh: - self._fh.close() - self._fh = None - - def __del__(self): - self.close() - - def _fromfile(self, fh): - """Initialize instance from open file.""" - fh.seek(0) - data = fh.read(4096) - if (len(data) < 7) or not (b'0' < data[1:2] < b'8'): - raise ValueError("Not a Netpbm file:\n%s" % data[:32]) - try: - self._read_pam_header(data) - except Exception: - try: - self._read_pnm_header(data) - except Exception: - raise ValueError("Not a Netpbm file:\n%s" % data[:32]) - - def _read_pam_header(self, data): - """Read PAM header and initialize instance.""" - regroups = re.search( - b"(^P7[\n\r]+(?:(?:[\n\r]+)|(?:#.*)|" - b"(HEIGHT\s+\d+)|(WIDTH\s+\d+)|(DEPTH\s+\d+)|(MAXVAL\s+\d+)|" - b"(?:TUPLTYPE\s+\w+))*ENDHDR\n)", data).groups() - self.header = regroups[0] - self.magicnum = b'P7' - for group in regroups[1:]: - key, value = group.split() - setattr(self, unicode(key).lower(), int(value)) - matches = re.findall(b"(TUPLTYPE\s+\w+)", self.header) - self.tupltypes = [s.split(None, 1)[1] for s in matches] - - def _read_pnm_header(self, data): - """Read PNM header and initialize instance.""" - bpm = data[1:2] in b"14" - regroups = re.search(b"".join(( - b"(^(P[123456]|P7 332)\s+(?:#.*[\r\n])*", - b"\s*(\d+)\s+(?:#.*[\r\n])*", - b"\s*(\d+)\s+(?:#.*[\r\n])*" * (not bpm), - b"\s*(\d+)\s(?:\s*#.*[\r\n]\s)*)")), data).groups() + (1, ) * bpm - self.header = regroups[0] - self.magicnum = regroups[1] - self.width = int(regroups[2]) - self.height = int(regroups[3]) - self.maxval = int(regroups[4]) - self.depth = 3 if self.magicnum in b"P3P6P7 332" else 1 - self.tupltypes = [self._types[self.magicnum]] - - def _read_data(self, fh, byteorder='>'): - """Return image data from open file as numpy array.""" - fh.seek(len(self.header)) - data = fh.read() - dtype = 'u1' if self.maxval < 256 else byteorder + 'u2' - depth = 1 if self.magicnum == b"P7 332" else self.depth - shape = [-1, self.height, self.width, depth] - size = numpy.prod(shape[1:]) - if self.magicnum in b"P1P2P3": - data = numpy.array(data.split(None, size)[:size], dtype) - data = data.reshape(shape) - elif self.maxval == 1: - shape[2] = int(math.ceil(self.width / 8)) - data = numpy.frombuffer(data, dtype).reshape(shape) - data = numpy.unpackbits(data, axis=-2)[:, :, :self.width, :] - else: - data = numpy.frombuffer(data, dtype) - data = data[:size * (data.size // size)].reshape(shape) - if data.shape[0] < 2: - data = data.reshape(data.shape[1:]) - if data.shape[-1] < 2: - data = data.reshape(data.shape[:-1]) - if self.magicnum == b"P7 332": - rgb332 = numpy.array(list(numpy.ndindex(8, 8, 4)), numpy.uint8) - rgb332 *= [36, 36, 85] - data = numpy.take(rgb332, data, axis=0) - return data - - def _fromdata(self, data, maxval=None): - """Initialize instance from numpy array.""" - data = numpy.array(data, ndmin=2, copy=True) - if data.dtype.kind not in "uib": - raise ValueError("not an integer type: %s" % data.dtype) - if data.dtype.kind == 'i' and numpy.min(data) < 0: - raise ValueError("data out of range: %i" % numpy.min(data)) - if maxval is None: - maxval = numpy.max(data) - maxval = 255 if maxval < 256 else 65535 - if maxval < 0 or maxval > 65535: - raise ValueError("data out of range: %i" % maxval) - data = data.astype('u1' if maxval < 256 else '>u2') - self._data = data - if data.ndim > 2 and data.shape[-1] in (3, 4): - self.depth = data.shape[-1] - self.width = data.shape[-2] - self.height = data.shape[-3] - self.magicnum = b'P7' if self.depth == 4 else b'P6' - else: - self.depth = 1 - self.width = data.shape[-1] - self.height = data.shape[-2] - self.magicnum = b'P5' if maxval > 1 else b'P4' - self.maxval = maxval - self.tupltypes = [self._types[self.magicnum]] - self.header = self._header() - - def _tofile(self, fh, pam=False): - """Write Netbm file.""" - fh.seek(0) - fh.write(self._header(pam)) - data = self.asarray(copy=False) - if self.maxval == 1: - data = numpy.packbits(data, axis=-1) - data.tofile(fh) - - def _header(self, pam=False): - """Return file header as byte string.""" - if pam or self.magicnum == b'P7': - header = "\n".join(( - "P7", - "HEIGHT %i" % self.height, - "WIDTH %i" % self.width, - "DEPTH %i" % self.depth, - "MAXVAL %i" % self.maxval, - "\n".join("TUPLTYPE %s" % unicode(i) for i in self.tupltypes), - "ENDHDR\n")) - elif self.maxval == 1: - header = "P4 %i %i\n" % (self.width, self.height) - elif self.depth == 1: - header = "P5 %i %i %i\n" % (self.width, self.height, self.maxval) - else: - header = "P6 %i %i %i\n" % (self.width, self.height, self.maxval) - if sys.version_info[0] > 2: - header = bytes(header, 'ascii') - return header - - def __str__(self): - """Return information about instance.""" - return unicode(self.header) - - -if sys.version_info[0] > 2: - basestring = str - unicode = lambda x: str(x, 'ascii') - -if __name__ == "__main__": - # Show images specified on command line or all images in current directory - from glob import glob - from matplotlib import pyplot - files = sys.argv[1:] if len(sys.argv) > 1 else glob('*.p*m') - for fname in files: - try: - pam = NetpbmFile(fname) - img = pam.asarray(copy=False) - if False: - pam.write('_tmp.pgm.out', pam=True) - img2 = imread('_tmp.pgm.out') - assert numpy.all(img == img2) - imsave('_tmp.pgm.out', img) - img2 = imread('_tmp.pgm.out') - assert numpy.all(img == img2) - pam.close() - except ValueError as e: - print(fname, e) - continue - _shape = img.shape - if img.ndim > 3 or (img.ndim > 2 and img.shape[-1] not in (3, 4)): - img = img[0] - cmap = 'gray' if pam.maxval > 1 else 'binary' - pyplot.imshow(img, cmap, interpolation='nearest') - pyplot.title("%s %s %s %s" % (fname, unicode(pam.magicnum), - _shape, img.dtype)) - pyplot.show() diff --git a/GPy/util/plot_latent.py b/GPy/util/plot_latent.py deleted file mode 100644 index fbf62c41..00000000 --- a/GPy/util/plot_latent.py +++ /dev/null @@ -1,181 +0,0 @@ -import pylab as pb -import numpy as np -from .. import util -from GPy.util.latent_space_visualizations.controllers.imshow_controller import ImshowController -from misc import param_to_array -import itertools - -def most_significant_input_dimensions(model, which_indices): - if which_indices is None: - if model.input_dim == 1: - input_1 = 0 - input_2 = None - if model.input_dim == 2: - input_1, input_2 = 0, 1 - else: - try: - input_1, input_2 = np.argsort(model.input_sensitivity())[::-1][:2] - except: - raise ValueError, "cannot automatically determine which dimensions to plot, please pass 'which_indices'" - else: - input_1, input_2 = which_indices - return input_1, input_2 - -def plot_latent(model, labels=None, which_indices=None, - resolution=50, ax=None, marker='o', s=40, - fignum=None, plot_inducing=False, legend=True, - aspect='auto', updates=False): - """ - :param labels: a np.array of size model.num_data containing labels for the points (can be number, strings, etc) - :param resolution: the resolution of the grid on which to evaluate the predictive variance - """ - if ax is None: - fig = pb.figure(num=fignum) - ax = fig.add_subplot(111) - util.plot.Tango.reset() - - if labels is None: - labels = np.ones(model.num_data) - - input_1, input_2 = most_significant_input_dimensions(model, which_indices) - X = param_to_array(model.X) - - # first, plot the output variance as a function of the latent space - Xtest, xx, yy, xmin, xmax = util.plot.x_frame2D(X[:, [input_1, input_2]], resolution=resolution) - Xtest_full = np.zeros((Xtest.shape[0], model.X.shape[1])) - - def plot_function(x): - Xtest_full[:, [input_1, input_2]] = x - mu, var, low, up = model.predict(Xtest_full) - var = var[:, :1] - return np.log(var) - view = ImshowController(ax, plot_function, - tuple(X[:, [input_1, input_2]].min(0)) + tuple(X[:, [input_1, input_2]].max(0)), - resolution, aspect=aspect, interpolation='bilinear', - cmap=pb.cm.binary) - -# ax.imshow(var.reshape(resolution, resolution).T, -# extent=[xmin[0], xmax[0], xmin[1], xmax[1]], cmap=pb.cm.binary, interpolation='bilinear', origin='lower') - - # make sure labels are in order of input: - ulabels = [] - for lab in labels: - if not lab in ulabels: - ulabels.append(lab) - - marker = itertools.cycle(list(marker)) - - for i, ul in enumerate(ulabels): - if type(ul) is np.string_: - this_label = ul - elif type(ul) is np.int64: - this_label = 'class %i' % ul - else: - this_label = 'class %i' % i - m = marker.next() - - index = np.nonzero(labels == ul)[0] - if model.input_dim == 1: - x = X[index, input_1] - y = np.zeros(index.size) - else: - x = X[index, input_1] - y = X[index, input_2] - ax.scatter(x, y, marker=m, s=s, color=util.plot.Tango.nextMedium(), label=this_label) - - ax.set_xlabel('latent dimension %i' % input_1) - ax.set_ylabel('latent dimension %i' % input_2) - - if not np.all(labels == 1.) and legend: - ax.legend(loc=0, numpoints=1) - - ax.set_xlim(xmin[0], xmax[0]) - ax.set_ylim(xmin[1], xmax[1]) - ax.grid(b=False) # remove the grid if present, it doesn't look good - ax.set_aspect('auto') # set a nice aspect ratio - - if plot_inducing: - Z = param_to_array(model.Z) - ax.plot(Z[:, input_1], Z[:, input_2], '^w') - - if updates: - ax.figure.canvas.show() - raw_input('Enter to continue') - return ax - -def plot_magnification(model, labels=None, which_indices=None, - resolution=60, ax=None, marker='o', s=40, - fignum=None, plot_inducing=False, legend=True, - aspect='auto', updates=False): - """ - :param labels: a np.array of size model.num_data containing labels for the points (can be number, strings, etc) - :param resolution: the resolution of the grid on which to evaluate the predictive variance - """ - if ax is None: - fig = pb.figure(num=fignum) - ax = fig.add_subplot(111) - util.plot.Tango.reset() - - if labels is None: - labels = np.ones(model.num_data) - - input_1, input_2 = most_significant_input_dimensions(model, which_indices) - - # first, plot the output variance as a function of the latent space - Xtest, xx, yy, xmin, xmax = util.plot.x_frame2D(model.X[:, [input_1, input_2]], resolution=resolution) - Xtest_full = np.zeros((Xtest.shape[0], model.X.shape[1])) - def plot_function(x): - Xtest_full[:, [input_1, input_2]] = x - mf=model.magnification(Xtest_full) - return mf - view = ImshowController(ax, plot_function, - tuple(model.X.min(0)[:, [input_1, input_2]]) + tuple(model.X.max(0)[:, [input_1, input_2]]), - resolution, aspect=aspect, interpolation='bilinear', - cmap=pb.cm.gray) - - # make sure labels are in order of input: - ulabels = [] - for lab in labels: - if not lab in ulabels: - ulabels.append(lab) - - marker = itertools.cycle(list(marker)) - - for i, ul in enumerate(ulabels): - if type(ul) is np.string_: - this_label = ul - elif type(ul) is np.int64: - this_label = 'class %i' % ul - else: - this_label = 'class %i' % i - m = marker.next() - - index = np.nonzero(labels == ul)[0] - if model.input_dim == 1: - x = model.X[index, input_1] - y = np.zeros(index.size) - else: - x = model.X[index, input_1] - y = model.X[index, input_2] - ax.scatter(x, y, marker=m, s=s, color=util.plot.Tango.nextMedium(), label=this_label) - - ax.set_xlabel('latent dimension %i' % input_1) - ax.set_ylabel('latent dimension %i' % input_2) - - if not np.all(labels == 1.) and legend: - ax.legend(loc=0, numpoints=1) - - ax.set_xlim(xmin[0], xmax[0]) - ax.set_ylim(xmin[1], xmax[1]) - ax.grid(b=False) # remove the grid if present, it doesn't look good - ax.set_aspect('auto') # set a nice aspect ratio - - if plot_inducing: - ax.plot(model.Z[:, input_1], model.Z[:, input_2], '^w') - - if updates: - ax.figure.canvas.show() - raw_input('Enter to continue') - - pb.title('Magnification Factor') - return ax diff --git a/GPy/util/visualize.py b/GPy/util/visualize.py deleted file mode 100644 index 691326ac..00000000 --- a/GPy/util/visualize.py +++ /dev/null @@ -1,538 +0,0 @@ -import matplotlib.pyplot as plt -from mpl_toolkits.mplot3d import Axes3D -import GPy -import numpy as np -import matplotlib as mpl -import time -import Image -try: - import visual - visual_available = True - -except ImportError: - visual_available = False - - -class data_show: - """ - The data_show class is a base class which describes how to visualize a - particular data set. For example, motion capture data can be plotted as a - stick figure, or images are shown using imshow. This class enables latent - to data visualizations for the GP-LVM. - """ - def __init__(self, vals): - self.vals = vals.copy() - # If no axes are defined, create some. - - def modify(self, vals): - raise NotImplementedError, "this needs to be implemented to use the data_show class" - - def close(self): - raise NotImplementedError, "this needs to be implemented to use the data_show class" - -class vpython_show(data_show): - """ - the vpython_show class is a base class for all visualization methods that use vpython to display. It is initialized with a scene. If the scene is set to None it creates a scene window. - """ - - def __init__(self, vals, scene=None): - data_show.__init__(self, vals) - # If no axes are defined, create some. - - if scene==None: - self.scene = visual.display(title='Data Visualization') - else: - self.scene = scene - - def close(self): - self.scene.exit() - - - -class matplotlib_show(data_show): - """ - the matplotlib_show class is a base class for all visualization methods that use matplotlib. It is initialized with an axis. If the axis is set to None it creates a figure window. - """ - def __init__(self, vals, axes=None): - data_show.__init__(self, vals) - # If no axes are defined, create some. - - if axes==None: - fig = plt.figure() - self.axes = fig.add_subplot(111) - else: - self.axes = axes - - def close(self): - plt.close(self.axes.get_figure()) - -class vector_show(matplotlib_show): - """ - A base visualization class that just shows a data vector as a plot of - vector elements alongside their indices. - """ - def __init__(self, vals, axes=None): - matplotlib_show.__init__(self, vals, axes) - self.handle = self.axes.plot(np.arange(0, len(vals))[:, None], self.vals.T)[0] - - def modify(self, vals): - self.vals = vals.copy() - xdata, ydata = self.handle.get_data() - self.handle.set_data(xdata, self.vals.T) - self.axes.figure.canvas.draw() - - -class lvm(matplotlib_show): - def __init__(self, vals, model, data_visualize, latent_axes=None, sense_axes=None, latent_index=[0,1]): - """Visualize a latent variable model - - :param model: the latent variable model to visualize. - :param data_visualize: the object used to visualize the data which has been modelled. - :type data_visualize: visualize.data_show type. - :param latent_axes: the axes where the latent visualization should be plotted. - """ - if vals == None: - vals = model.X[0] - - matplotlib_show.__init__(self, vals, axes=latent_axes) - - if isinstance(latent_axes,mpl.axes.Axes): - self.cid = latent_axes.figure.canvas.mpl_connect('button_press_event', self.on_click) - self.cid = latent_axes.figure.canvas.mpl_connect('motion_notify_event', self.on_move) - self.cid = latent_axes.figure.canvas.mpl_connect('axes_leave_event', self.on_leave) - self.cid = latent_axes.figure.canvas.mpl_connect('axes_enter_event', self.on_enter) - else: - self.cid = latent_axes[0].figure.canvas.mpl_connect('button_press_event', self.on_click) - self.cid = latent_axes[0].figure.canvas.mpl_connect('motion_notify_event', self.on_move) - self.cid = latent_axes[0].figure.canvas.mpl_connect('axes_leave_event', self.on_leave) - self.cid = latent_axes[0].figure.canvas.mpl_connect('axes_enter_event', self.on_enter) - - self.data_visualize = data_visualize - self.model = model - self.latent_axes = latent_axes - self.sense_axes = sense_axes - self.called = False - self.move_on = False - self.latent_index = latent_index - self.latent_dim = model.input_dim - - # The red cross which shows current latent point. - self.latent_values = vals - self.latent_handle = self.latent_axes.plot([0],[0],'rx',mew=2)[0] - self.modify(vals) - self.show_sensitivities() - - def modify(self, vals): - """When latent values are modified update the latent representation and ulso update the output visualization.""" - self.vals = vals.copy() - y = self.model.predict(self.vals)[0] - self.data_visualize.modify(y) - self.latent_handle.set_data(self.vals[self.latent_index[0]], self.vals[self.latent_index[1]]) - self.axes.figure.canvas.draw() - - - def on_enter(self,event): - pass - def on_leave(self,event): - pass - - def on_click(self, event): - print 'click!' - if event.inaxes!=self.latent_axes: return - self.move_on = not self.move_on - self.called = True - - def on_move(self, event): - if event.inaxes!=self.latent_axes: return - if self.called and self.move_on: - # Call modify code on move - self.latent_values[self.latent_index[0]]=event.xdata - self.latent_values[self.latent_index[1]]=event.ydata - self.modify(self.latent_values) - - def show_sensitivities(self): - # A click in the bar chart axis for selection a dimension. - if self.sense_axes != None: - self.sense_axes.cla() - self.sense_axes.bar(np.arange(self.model.input_dim), self.model.input_sensitivity(), color='b') - - if self.latent_index[1] == self.latent_index[0]: - self.sense_axes.bar(np.array(self.latent_index[0]), self.model.input_sensitivity()[self.latent_index[0]], color='y') - self.sense_axes.bar(np.array(self.latent_index[1]), self.model.input_sensitivity()[self.latent_index[1]], color='y') - - else: - self.sense_axes.bar(np.array(self.latent_index[0]), self.model.input_sensitivity()[self.latent_index[0]], color='g') - self.sense_axes.bar(np.array(self.latent_index[1]), self.model.input_sensitivity()[self.latent_index[1]], color='r') - - self.sense_axes.figure.canvas.draw() - - -class lvm_subplots(lvm): - """ - latent_axes is a np array of dimension np.ceil(input_dim/2), - one for each pair of the latent dimensions. - """ - def __init__(self, vals, Model, data_visualize, latent_axes=None, sense_axes=None): - self.nplots = int(np.ceil(Model.input_dim/2.))+1 - assert len(latent_axes)==self.nplots - if vals==None: - vals = Model.X[0, :] - self.latent_values = vals - - for i, axis in enumerate(latent_axes): - if i == self.nplots-1: - if self.nplots*2!=Model.input_dim: - latent_index = [i*2, i*2] - lvm.__init__(self, self.latent_vals, Model, data_visualize, axis, sense_axes, latent_index=latent_index) - else: - latent_index = [i*2, i*2+1] - lvm.__init__(self, self.latent_vals, Model, data_visualize, axis, latent_index=latent_index) - - - -class lvm_dimselect(lvm): - """ - A visualizer for latent variable models which allows selection of the latent dimensions to use by clicking on a bar chart of their length scales. - - For an example of the visualizer's use try: - - GPy.examples.dimensionality_reduction.BGPVLM_oil() - - """ - def __init__(self, vals, model, data_visualize, latent_axes=None, sense_axes=None, latent_index=[0, 1], labels=None): - if latent_axes==None and sense_axes==None: - self.fig,(latent_axes,self.sense_axes) = plt.subplots(1,2) - elif sense_axes==None: - fig=plt.figure() - self.sense_axes = fig.add_subplot(111) - else: - self.sense_axes = sense_axes - self.labels = labels - lvm.__init__(self,vals,model,data_visualize,latent_axes,sense_axes,latent_index) - self.show_sensitivities() - print "use left and right mouse butons to select dimensions" - - - def on_click(self, event): - - if event.inaxes==self.sense_axes: - new_index = max(0,min(int(np.round(event.xdata-0.5)),self.model.input_dim-1)) - if event.button == 1: - # Make it red if and y-axis (red=port=left) if it is a left button click - self.latent_index[1] = new_index - else: - # Make it green and x-axis (green=starboard=right) if it is a right button click - self.latent_index[0] = new_index - - self.show_sensitivities() - - self.latent_axes.cla() - self.model.plot_latent(which_indices=self.latent_index, - ax=self.latent_axes, labels=self.labels) - self.latent_handle = self.latent_axes.plot([0],[0],'rx',mew=2)[0] - self.modify(self.latent_values) - - elif event.inaxes==self.latent_axes: - self.move_on = not self.move_on - - self.called = True - - - - def on_leave(self,event): - latent_values = self.latent_values.copy() - y = self.model.predict(latent_values[None,:])[0] - self.data_visualize.modify(y) - - - -class image_show(matplotlib_show): - """Show a data vector as an image. This visualizer rehapes the output vector and displays it as an image. - - :param vals: the values of the output to display. - :type vals: ndarray - :param axes: the axes to show the output on. - :type vals: axes handle - :param dimensions: the dimensions that the image needs to be transposed to for display. - :type dimensions: tuple - :param transpose: whether to transpose the image before display. - :type bool: default is False. - :param order: whether array is in Fortan ordering ('F') or Python ordering ('C'). Default is python ('C'). - :type order: string - :param invert: whether to invert the pixels or not (default False). - :type invert: bool - :param palette: a palette to use for the image. - :param preset_mean: the preset mean of a scaled image. - :type preset_mean: double - :param preset_std: the preset standard deviation of a scaled image. - :type preset_std: double""" - def __init__(self, vals, axes=None, dimensions=(16,16), transpose=False, order='C', invert=False, scale=False, palette=[], preset_mean = 0., preset_std = -1., select_image=0): - matplotlib_show.__init__(self, vals, axes) - self.dimensions = dimensions - self.transpose = transpose - self.order = order - self.invert = invert - self.scale = scale - self.palette = palette - self.preset_mean = preset_mean - self.preset_std = preset_std - self.select_image = select_image # This is used when the y vector contains multiple images concatenated. - - self.set_image(self.vals) - if not self.palette == []: # Can just show the image (self.set_image() took care of setting the palette) - self.handle = self.axes.imshow(self.vals, interpolation='nearest') - else: # Use a boring gray map. - self.handle = self.axes.imshow(self.vals, cmap=plt.cm.gray, interpolation='nearest') # @UndefinedVariable - plt.show() - - def modify(self, vals): - self.set_image(vals.copy()) - self.handle.set_array(self.vals) - self.axes.figure.canvas.draw() - - def set_image(self, vals): - dim = self.dimensions[0] * self.dimensions[1] - num_images = np.sqrt(vals[0,].size/dim) - if num_images > 1 and num_images.is_integer(): # Show a mosaic of images - num_images = np.int(num_images) - self.vals = np.zeros((self.dimensions[0]*num_images, self.dimensions[1]*num_images)) - for iR in range(num_images): - for iC in range(num_images): - cur_img_id = iR*num_images + iC - cur_img = np.reshape(vals[0,dim*cur_img_id+np.array(range(dim))], self.dimensions, order=self.order) - first_row = iR*self.dimensions[0] - last_row = (iR+1)*self.dimensions[0] - first_col = iC*self.dimensions[1] - last_col = (iC+1)*self.dimensions[1] - self.vals[first_row:last_row, first_col:last_col] = cur_img - - else: - self.vals = np.reshape(vals[0,dim*self.select_image+np.array(range(dim))], self.dimensions, order=self.order) - if self.transpose: - self.vals = self.vals.T - # if not self.scale: - # self.vals = self.vals - if self.invert: - self.vals = -self.vals - - # un-normalizing, for visualisation purposes: - if self.preset_std >= 0: # The Mean is assumed to be in the range (0,255) - self.vals = self.vals*self.preset_std + self.preset_mean - # Clipping the values: - self.vals[self.vals < 0] = 0 - self.vals[self.vals > 255] = 255 - else: - self.vals = 255*(self.vals - self.vals.min())/(self.vals.max() - self.vals.min()) - if not self.palette == []: # applying using an image palette (e.g. if the image has been quantized) - self.vals = Image.fromarray(self.vals.astype('uint8')) - self.vals.putpalette(self.palette) # palette is a list, must be loaded before calling this function - -class mocap_data_show_vpython(vpython_show): - """Base class for visualizing motion capture data using visual module.""" - - def __init__(self, vals, scene=None, connect=None, radius=0.1): - vpython_show.__init__(self, vals, scene) - self.radius = radius - self.connect = connect - self.process_values() - self.draw_edges() - self.draw_vertices() - - def draw_vertices(self): - self.spheres = [] - for i in range(self.vals.shape[0]): - self.spheres.append(visual.sphere(pos=(self.vals[i, 0], self.vals[i, 2], self.vals[i, 1]), radius=self.radius)) - self.scene.visible=True - - def draw_edges(self): - self.rods = [] - self.line_handle = [] - if not self.connect==None: - self.I, self.J = np.nonzero(self.connect) - for i, j in zip(self.I, self.J): - pos, axis = self.pos_axis(i, j) - self.rods.append(visual.cylinder(pos=pos, axis=axis, radius=self.radius)) - - def modify_vertices(self): - for i in range(self.vals.shape[0]): - self.spheres[i].pos = (self.vals[i, 0], self.vals[i, 2], self.vals[i, 1]) - - def modify_edges(self): - self.line_handle = [] - if not self.connect==None: - self.I, self.J = np.nonzero(self.connect) - for rod, i, j in zip(self.rods, self.I, self.J): - rod.pos, rod.axis = self.pos_axis(i, j) - - def pos_axis(self, i, j): - pos = [] - axis = [] - pos.append(self.vals[i, 0]) - axis.append(self.vals[j, 0]-self.vals[i,0]) - pos.append(self.vals[i, 2]) - axis.append(self.vals[j, 2]-self.vals[i,2]) - pos.append(self.vals[i, 1]) - axis.append(self.vals[j, 1]-self.vals[i,1]) - return pos, axis - - def modify(self, vals): - self.vals = vals.copy() - self.process_values() - self.modify_edges() - self.modify_vertices() - - def process_values(self): - raise NotImplementedError, "this needs to be implemented to use the data_show class" - - -class mocap_data_show(matplotlib_show): - """Base class for visualizing motion capture data.""" - - def __init__(self, vals, axes=None, connect=None): - if axes==None: - fig = plt.figure() - axes = fig.add_subplot(111, projection='3d') - matplotlib_show.__init__(self, vals, axes) - - self.connect = connect - self.process_values() - self.initialize_axes() - self.draw_vertices() - self.finalize_axes() - self.draw_edges() - self.axes.figure.canvas.draw() - - def draw_vertices(self): - self.points_handle = self.axes.scatter(self.vals[:, 0], self.vals[:, 1], self.vals[:, 2]) - - def draw_edges(self): - self.line_handle = [] - if not self.connect==None: - x = [] - y = [] - z = [] - self.I, self.J = np.nonzero(self.connect) - for i, j in zip(self.I, self.J): - x.append(self.vals[i, 0]) - x.append(self.vals[j, 0]) - x.append(np.NaN) - y.append(self.vals[i, 1]) - y.append(self.vals[j, 1]) - y.append(np.NaN) - z.append(self.vals[i, 2]) - z.append(self.vals[j, 2]) - z.append(np.NaN) - self.line_handle = self.axes.plot(np.array(x), np.array(y), np.array(z), 'b-') - - def modify(self, vals): - self.vals = vals.copy() - self.process_values() - self.initialize_axes_modify() - self.draw_vertices() - self.finalize_axes_modify() - self.draw_edges() - self.axes.figure.canvas.draw() - - def process_values(self): - raise NotImplementedError, "this needs to be implemented to use the data_show class" - - def initialize_axes(self): - """Set up the axes with the right limits and scaling.""" - self.x_lim = np.array([self.vals[:, 0].min(), self.vals[:, 0].max()]) - self.y_lim = np.array([self.vals[:, 1].min(), self.vals[:, 1].max()]) - self.z_lim = np.array([self.vals[:, 2].min(), self.vals[:, 2].max()]) - - def initialize_axes_modify(self): - self.points_handle.remove() - self.line_handle[0].remove() - - def finalize_axes(self): - self.axes.set_xlim(self.x_lim) - self.axes.set_ylim(self.y_lim) - self.axes.set_zlim(self.z_lim) - self.axes.auto_scale_xyz([-1., 1.], [-1., 1.], [-1.5, 1.5]) - - #self.axes.set_aspect('equal') - self.axes.autoscale(enable=False) - - def finalize_axes_modify(self): - self.axes.set_xlim(self.x_lim) - self.axes.set_ylim(self.y_lim) - self.axes.set_zlim(self.z_lim) - -class stick_show(mocap_data_show): - """Show a three dimensional point cloud as a figure. Connect elements of the figure together using the matrix connect.""" - def __init__(self, vals, connect=None, axes=None): - mocap_data_show.__init__(self, vals, axes=axes, connect=connect) - - def process_values(self): - self.vals = self.vals.reshape((3, self.vals.shape[1]/3)).T - -class skeleton_show(mocap_data_show): - """data_show class for visualizing motion capture data encoded as a skeleton with angles.""" - def __init__(self, vals, skel, axes=None, padding=0): - """data_show class for visualizing motion capture data encoded as a skeleton with angles. - :param vals: set of modeled angles to use for printing in the axis when it's first created. - :type vals: np.array - :param skel: skeleton object that has the parameters of the motion capture skeleton associated with it. - :type skel: mocap.skeleton object - :param padding: - :type int - """ - self.skel = skel - self.padding = padding - connect = skel.connection_matrix() - mocap_data_show.__init__(self, vals, axes=axes, connect=connect) - def process_values(self): - """Takes a set of angles and converts them to the x,y,z coordinates in the internal prepresentation of the class, ready for plotting. - - :param vals: the values that are being modelled.""" - - if self.padding>0: - channels = np.zeros((self.vals.shape[0], self.vals.shape[1]+self.padding)) - channels[:, 0:self.vals.shape[0]] = self.vals - else: - channels = self.vals - vals_mat = self.skel.to_xyz(channels.flatten()) - self.vals = np.zeros_like(vals_mat) - # Flip the Y and Z axes - self.vals[:, 0] = vals_mat[:, 0].copy() - self.vals[:, 1] = vals_mat[:, 2].copy() - self.vals[:, 2] = vals_mat[:, 1].copy() - - def wrap_around(self, lim, connect): - quot = lim[1] - lim[0] - self.vals = rem(self.vals, quot)+lim[0] - nVals = floor(self.vals/quot) - for i in range(connect.shape[0]): - for j in find(connect[i, :]): - if nVals[i] != nVals[j]: - connect[i, j] = False - return connect - - -def data_play(Y, visualizer, frame_rate=30): - """Play a data set using the data_show object given. - - :Y: the data set to be visualized. - :param visualizer: the data show objectwhether to display during optimisation - :type visualizer: data_show - - Example usage: - - This example loads in the CMU mocap database (http://mocap.cs.cmu.edu) subject number 35 motion number 01. It then plays it using the mocap_show visualize object. - - .. code-block:: python - - data = GPy.util.datasets.cmu_mocap(subject='35', train_motions=['01']) - Y = data['Y'] - Y[:, 0:3] = 0. # Make figure walk in place - visualize = GPy.util.visualize.skeleton_show(Y[0, :], data['skel']) - GPy.util.visualize.data_play(Y, visualize) - - """ - - - for y in Y: - visualizer.modify(y[None, :]) - time.sleep(1./float(frame_rate)) From 1ab26de56e17e4b8d10735483a48db615af10662 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:46:42 +0000 Subject: [PATCH 24/26] New files --- GPy/plotting/matplot_dep/__init__.py | 16 ++ GPy/plotting/matplot_dep/inference_plots.py | 28 +++ GPy/plotting/matplot_dep/kernel_plots.py | 137 +++++++++++++++ GPy/plotting/matplot_dep/mapping_plots.py | 81 +++++++++ GPy/plotting/matplot_dep/models_plots.py | 161 ++++++++++++++++++ GPy/plotting/matplot_dep/priors_plots.py | 29 ++++ GPy/plotting/matplot_dep/svig_plots.py | 43 +++++ GPy/plotting/matplot_dep/variational_plots.py | 45 +++++ 8 files changed, 540 insertions(+) create mode 100644 GPy/plotting/matplot_dep/__init__.py create mode 100644 GPy/plotting/matplot_dep/inference_plots.py create mode 100644 GPy/plotting/matplot_dep/kernel_plots.py create mode 100644 GPy/plotting/matplot_dep/mapping_plots.py create mode 100644 GPy/plotting/matplot_dep/models_plots.py create mode 100644 GPy/plotting/matplot_dep/priors_plots.py create mode 100644 GPy/plotting/matplot_dep/svig_plots.py create mode 100644 GPy/plotting/matplot_dep/variational_plots.py diff --git a/GPy/plotting/matplot_dep/__init__.py b/GPy/plotting/matplot_dep/__init__.py new file mode 100644 index 00000000..b2a29c2d --- /dev/null +++ b/GPy/plotting/matplot_dep/__init__.py @@ -0,0 +1,16 @@ +# Copyright (c) 2014, GPy authors (see AUTHORS.txt). +# Licensed under the BSD 3-clause license (see LICENSE.txt) + +import base_plots +import models_plots +import priors_plots +import variational_plots +import kernel_plots +import svig_plots +import dim_reduction_plots +import mapping_plots +import Tango +import visualize +import latent_space_visualizations +import netpbmfile +import inference_plots diff --git a/GPy/plotting/matplot_dep/inference_plots.py b/GPy/plotting/matplot_dep/inference_plots.py new file mode 100644 index 00000000..f9bb464a --- /dev/null +++ b/GPy/plotting/matplot_dep/inference_plots.py @@ -0,0 +1,28 @@ +# Copyright (c) 2012, GPy authors (see AUTHORS.txt). +# Licensed under the BSD 3-clause license (see LICENSE.txt) + +import pylab as pb +#import numpy as np +#import Tango +#from base_plots import gpplot, x_frame1D, x_frame2D + + +def plot_optimizer(optimizer): + if optimizer.trace == None: + print "No trace present so I can't plot it. Please check that the optimizer actually supplies a trace." + else: + pb.figure() + pb.plot(optimizer.trace) + pb.xlabel('Iteration') + pb.ylabel('f(x)') + +def plot_sgd_traces(optimizer): + pb.figure() + pb.subplot(211) + pb.title('Parameters') + for k in optimizer.param_traces.keys(): + pb.plot(optimizer.param_traces[k], label=k) + pb.legend(loc=0) + pb.subplot(212) + pb.title('Objective function') + pb.plot(optimizer.fopt_trace) diff --git a/GPy/plotting/matplot_dep/kernel_plots.py b/GPy/plotting/matplot_dep/kernel_plots.py new file mode 100644 index 00000000..66644483 --- /dev/null +++ b/GPy/plotting/matplot_dep/kernel_plots.py @@ -0,0 +1,137 @@ +# Copyright (c) 2012, GPy authors (see AUTHORS.txt). +# Licensed under the BSD 3-clause license (see LICENSE.txt) + +import sys +import numpy as np +import pylab as pb +import Tango +from matplotlib.textpath import TextPath +from matplotlib.transforms import offset_copy + + +def plot_ARD(kernel, fignum=None, ax=None, title='', legend=False): + """If an ARD kernel is present, plot a bar representation using matplotlib + + :param fignum: figure number of the plot + :param ax: matplotlib axis to plot on + :param title: + title of the plot, + pass '' to not print a title + pass None for a generic title + """ + if ax is None: + fig = pb.figure(fignum) + ax = fig.add_subplot(111) + else: + fig = ax.figure + Tango.reset() + xticklabels = [] + bars = [] + x0 = 0 + for p in kernel._parameters_: + c = Tango.nextMedium() + if hasattr(p, 'ARD') and p.ARD: + if title is None: + ax.set_title('ARD parameters, %s kernel' % p.name) + else: + ax.set_title(title) + if isinstance(p, Linear): + ard_params = p.variances + else: + ard_params = 1. / p.lengthscale + + x = np.arange(x0, x0 + len(ard_params)) + bars.append(ax.bar(x, ard_params, align='center', color=c, edgecolor='k', linewidth=1.2, label=p.name.replace("_"," "))) + xticklabels.extend([r"$\mathrm{{{name}}}\ {x}$".format(name=p.name, x=i) for i in np.arange(len(ard_params))]) + x0 += len(ard_params) + x = np.arange(x0) + transOffset = offset_copy(ax.transData, fig=fig, + x=0., y= -2., units='points') + transOffsetUp = offset_copy(ax.transData, fig=fig, + x=0., y=1., units='points') + for bar in bars: + for patch, num in zip(bar.patches, np.arange(len(bar.patches))): + height = patch.get_height() + xi = patch.get_x() + patch.get_width() / 2. + va = 'top' + c = 'w' + t = TextPath((0, 0), "${xi}$".format(xi=xi), rotation=0, usetex=True, ha='center') + transform = transOffset + if patch.get_extents().height <= t.get_extents().height + 3: + va = 'bottom' + c = 'k' + transform = transOffsetUp + ax.text(xi, height, "${xi}$".format(xi=int(num)), color=c, rotation=0, ha='center', va=va, transform=transform) + # for xi, t in zip(x, xticklabels): + # ax.text(xi, maxi / 2, t, rotation=90, ha='center', va='center') + # ax.set_xticklabels(xticklabels, rotation=17) + ax.set_xticks([]) + ax.set_xlim(-.5, x0 - .5) + if legend: + if title is '': + mode = 'expand' + if len(bars) > 1: + mode = 'expand' + ax.legend(bbox_to_anchor=(0., 1.02, 1., 1.02), loc=3, + ncol=len(bars), mode=mode, borderaxespad=0.) + fig.tight_layout(rect=(0, 0, 1, .9)) + else: + ax.legend() + return ax + + +def plot(kernel, x=None, plot_limits=None, which_parts='all', resolution=None, *args, **kwargs): + if which_parts == 'all': + which_parts = [True] * kernel.size + if kernel.input_dim == 1: + if x is None: + x = np.zeros((1, 1)) + else: + x = np.asarray(x) + assert x.size == 1, "The size of the fixed variable x is not 1" + x = x.reshape((1, 1)) + + if plot_limits == None: + xmin, xmax = (x - 5).flatten(), (x + 5).flatten() + elif len(plot_limits) == 2: + xmin, xmax = plot_limits + else: + raise ValueError, "Bad limits for plotting" + + Xnew = np.linspace(xmin, xmax, resolution or 201)[:, None] + Kx = kernel.K(Xnew, x, which_parts) + pb.plot(Xnew, Kx, *args, **kwargs) + pb.xlim(xmin, xmax) + pb.xlabel("x") + pb.ylabel("k(x,%0.1f)" % x) + + elif kernel.input_dim == 2: + if x is None: + x = np.zeros((1, 2)) + else: + x = np.asarray(x) + assert x.size == 2, "The size of the fixed variable x is not 2" + x = x.reshape((1, 2)) + + if plot_limits == None: + xmin, xmax = (x - 5).flatten(), (x + 5).flatten() + elif len(plot_limits) == 2: + xmin, xmax = plot_limits + else: + raise ValueError, "Bad limits for plotting" + + resolution = resolution or 51 + xx, yy = np.mgrid[xmin[0]:xmax[0]:1j * resolution, xmin[1]:xmax[1]:1j * resolution] + xg = np.linspace(xmin[0], xmax[0], resolution) + yg = np.linspace(xmin[1], xmax[1], resolution) + Xnew = np.vstack((xx.flatten(), yy.flatten())).T + Kx = kernel.K(Xnew, x, which_parts) + Kx = Kx.reshape(resolution, resolution).T + pb.contour(xg, yg, Kx, vmin=Kx.min(), vmax=Kx.max(), cmap=pb.cm.jet, *args, **kwargs) # @UndefinedVariable + pb.xlim(xmin[0], xmax[0]) + pb.ylim(xmin[1], xmax[1]) + pb.xlabel("x1") + pb.ylabel("x2") + pb.title("k(x1,x2 ; %0.1f,%0.1f)" % (x[0, 0], x[0, 1])) + else: + raise NotImplementedError, "Cannot plot a kernel with more than two input dimensions" diff --git a/GPy/plotting/matplot_dep/mapping_plots.py b/GPy/plotting/matplot_dep/mapping_plots.py new file mode 100644 index 00000000..3e3ea793 --- /dev/null +++ b/GPy/plotting/matplot_dep/mapping_plots.py @@ -0,0 +1,81 @@ +# Copyright (c) 2012, GPy authors (see AUTHORS.txt). +# Licensed under the BSD 3-clause license (see LICENSE.txt) + +import pylab as pb +import numpy as np +import Tango +from base_plots import x_frame1D, x_frame2D + + +def plot_mapping(self, plot_limits=None, which_data='all', which_parts='all', resolution=None, levels=20, samples=0, fignum=None, ax=None, fixed_inputs=[], linecol=Tango.colorsHex['darkBlue']): + """ + Plots the mapping associated with the model. + - In one dimension, the function is plotted. + - In two dimsensions, a contour-plot shows the function + - In higher dimensions, we've not implemented this yet !TODO! + + Can plot only part of the data and part of the posterior functions + using which_data and which_functions + + :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 which_data: which if the training data to plot (default all) + :type which_data: 'all' or a slice object to slice self.X, self.Y + :param which_parts: which of the kernel functions to plot (additively) + :type which_parts: 'all', or list of bools + :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 + :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 linecol: color of line to plot. + :type linecol: + :param levels: for 2D plotting, the number of contour levels to use is ax is None, create a new figure + + """ + # TODO include samples + if which_data == 'all': + which_data = slice(None) + + if ax is None: + fig = pb.figure(num=fignum) + ax = fig.add_subplot(111) + + plotdims = self.input_dim - len(fixed_inputs) + + if plotdims == 1: + + 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) + Xgrid = np.empty((Xnew.shape[0],self.input_dim)) + Xgrid[:,freedim] = Xnew + for i,v in fixed_inputs: + Xgrid[:,i] = v + + f = self.predict(Xgrid, which_parts=which_parts) + for d in range(y.shape[1]): + ax.plot(Xnew, f[:, d], edgecol=linecol) + + elif self.X.shape[1] == 2: + resolution = resolution or 50 + Xnew, _, _, xmin, xmax = x_frame2D(self.X, plot_limits, resolution) + x, y = np.linspace(xmin[0], xmax[0], resolution), np.linspace(xmin[1], xmax[1], resolution) + f = self.predict(Xnew, which_parts=which_parts) + m = m.reshape(resolution, resolution).T + ax.contour(x, y, f, levels, vmin=m.min(), vmax=m.max(), cmap=pb.cm.jet) # @UndefinedVariable + ax.set_xlim(xmin[0], xmax[0]) + ax.set_ylim(xmin[1], xmax[1]) + + else: + raise NotImplementedError, "Cannot define a frame with more than two input dimensions" diff --git a/GPy/plotting/matplot_dep/models_plots.py b/GPy/plotting/matplot_dep/models_plots.py new file mode 100644 index 00000000..a4e06441 --- /dev/null +++ b/GPy/plotting/matplot_dep/models_plots.py @@ -0,0 +1,161 @@ +# Copyright (c) 2012, GPy authors (see AUTHORS.txt). +# Licensed under the BSD 3-clause license (see LICENSE.txt) + +import pylab as pb +import numpy as np +import Tango +from base_plots import gpplot, x_frame1D, x_frame2D + + +def plot_fit(model, plot_limits=None, which_data_rows='all', + 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. + - 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 + - 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_rowsm 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 + :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 model.X, model.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 + if which_data_rows == 'all': + which_data_rows = slice(None) + if which_data_ycols == 'all': + which_data_ycols = np.arange(model.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(model.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(model.X[:,free_dims], plot_limits=plot_limits) + Xgrid = np.empty((Xnew.shape[0],model.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 = model._raw_predict(Xgrid, which_parts=which_parts) + lower = m - 2*np.sqrt(v) + upper = m + 2*np.sqrt(v) + Y = model.Y + else: + m, v, lower, upper = model.predict(Xgrid, which_parts=which_parts) + Y = model.Y + for d in which_data_ycols: + gpplot(Xnew, m[:, d], lower[:, d], upper[:, d], axes=ax, edgecol=linecol, fillcol=fillcol) + ax.plot(model.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 = model.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. + + #add inducing inputs (if a sparse model is used) + if hasattr(model,"Z"): + Zu = model.Z[:,free_dims] * model._Xscale[:,free_dims] + model._Xoffset[:,free_dims] + ax.plot(Zu, np.zeros_like(Zu) + ax.get_ylim()[0], 'r|', mew=1.5, markersize=12) + + #add error bars for uncertain (if input uncertainty is being modelled) + if hasattr(model,"has_uncertain_inputs"): + ax.errorbar(model.X[which_data, free_dims], model.likelihood.data[which_data, 0], + xerr=2 * np.sqrt(model.X_variance[which_data, free_dims]), + ecolor='k', fmt=None, elinewidth=.5, alpha=.5) + + + #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(model.X[:,free_dims], plot_limits, resolution) + Xgrid = np.empty((Xnew.shape[0],model.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, _ = model._raw_predict(Xgrid, which_parts=which_parts) + Y = model.likelihood.Y + else: + m, _, _, _ = model.predict(Xgrid, which_parts=which_parts,sampling=False) + Y = model.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(model.X[which_data_rows, free_dims[0]], model.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...") + + #add inducing inputs (if a sparse model is used) + if hasattr(model,"Z"): + Zu = model.Z[:,free_dims] * model._Xscale[:,free_dims] + model._Xoffset[:,free_dims] + ax.plot(Zu[:,free_dims[0]], Zu[:,free_dims[1]], 'wo') + + else: + raise NotImplementedError, "Cannot define a frame with more than two input dimensions" + + +def plot_f_fit(model, *args, **kwargs): + """ + Plot the GP's view of the world, where the data is normalized and before applying a likelihood. + + All args and kwargs are passed on to models_plots.plot. + """ + kwargs['plot_raw'] = True + plot(model,*args, **kwargs) diff --git a/GPy/plotting/matplot_dep/priors_plots.py b/GPy/plotting/matplot_dep/priors_plots.py new file mode 100644 index 00000000..af999740 --- /dev/null +++ b/GPy/plotting/matplot_dep/priors_plots.py @@ -0,0 +1,29 @@ +# Copyright (c) 2012, GPy authors (see AUTHORS.txt). +# Licensed under the BSD 3-clause license (see LICENSE.txt) + + +import numpy as np +import pylab as pb + + +def univariate_plot(prior): + rvs = prior.rvs(1000) + pb.hist(rvs, 100, normed=True) + xmin, xmax = pb.xlim() + xx = np.linspace(xmin, xmax, 1000) + pb.plot(xx, prior.pdf(xx), 'r', linewidth=2) + +def plot(prior): + + if prior.input_dim == 2: + rvs = prior.rvs(200) + pb.plot(rvs[:, 0], rvs[:, 1], 'kx', mew=1.5) + xmin, xmax = pb.xlim() + ymin, ymax = pb.ylim() + xx, yy = np.mgrid[xmin:xmax:100j, ymin:ymax:100j] + xflat = np.vstack((xx.flatten(), yy.flatten())).T + zz = prior.pdf(xflat).reshape(100, 100) + pb.contour(xx, yy, zz, linewidths=2) + + else: + raise NotImplementedError, "Cannot define a frame with more than two input dimensions" diff --git a/GPy/plotting/matplot_dep/svig_plots.py b/GPy/plotting/matplot_dep/svig_plots.py new file mode 100644 index 00000000..95344643 --- /dev/null +++ b/GPy/plotting/matplot_dep/svig_plots.py @@ -0,0 +1,43 @@ +# Copyright (c) 2012, James Hensman and Nicolo' Fusi +# Licensed under the BSD 3-clause license (see LICENSE.txt) + +import numpy as np +import pylab as pb + + +def plot(model, ax=None, fignum=None, Z_height=None, **kwargs): + + if ax is None: + fig = pb.figure(num=fignum) + ax = fig.add_subplot(111) + + #horrible hack here: + data = model.likelihood.data.copy() + model.likelihood.data = model.Y + GP.plot(model, ax=ax, **kwargs) + model.likelihood.data = data + + Zu = model.Z * model._Xscale + model._Xoffset + if model.input_dim==1: + ax.plot(model.X_batch, model.likelihood.data, 'gx',mew=2) + if Z_height is None: + Z_height = ax.get_ylim()[0] + ax.plot(Zu, np.zeros_like(Zu) + Z_height, 'r|', mew=1.5, markersize=12) + + if model.input_dim==2: + ax.scatter(model.X[:,0], model.X[:,1], 20., model.Y[:,0], linewidth=0, cmap=pb.cm.jet) # @UndefinedVariable + ax.plot(Zu[:,0], Zu[:,1], 'w^') + +def plot_traces(model): + + pb.figure() + t = np.array(model._param_trace) + pb.subplot(2,1,1) + for l,ti in zip(model._get_param_names(),t.T): + if not l[:3]=='iip': + pb.plot(ti,label=l) + pb.legend(loc=0) + + pb.subplot(2,1,2) + pb.plot(np.asarray(model._ll_trace),label='stochastic likelihood') + pb.legend(loc=0) diff --git a/GPy/plotting/matplot_dep/variational_plots.py b/GPy/plotting/matplot_dep/variational_plots.py new file mode 100644 index 00000000..9f791dd1 --- /dev/null +++ b/GPy/plotting/matplot_dep/variational_plots.py @@ -0,0 +1,45 @@ +import pylab as pb + +def plot(parameterized, fignum=None, ax=None, colors=None): + """ + Plot latent space X in 1D: + + - if fig is given, create input_dim subplots in fig and plot in these + - if ax is given plot input_dim 1D latent space plots of X into each `axis` + - if neither fig nor ax is given create a figure with fignum and plot in there + + colors: + colors of different latent space dimensions input_dim + + """ + if ax is None: + fig = pb.figure(num=fignum, figsize=(8, min(12, (2 * parameterized.means.shape[1])))) + if colors is None: + colors = pb.gca()._get_lines.color_cycle + pb.clf() + else: + colors = iter(colors) + plots = [] + means, variances = param_to_array(parameterized.means, parameterized.variances) + x = np.arange(means.shape[0]) + for i in range(means.shape[1]): + if ax is None: + a = fig.add_subplot(means.shape[1], 1, i + 1) + elif isinstance(ax, (tuple, list)): + a = ax[i] + else: + raise ValueError("Need one ax per latent dimension input_dim") + a.plot(means, c='k', alpha=.3) + plots.extend(a.plot(x, means.T[i], c=colors.next(), label=r"$\mathbf{{X_{{{}}}}}$".format(i))) + a.fill_between(x, + means.T[i] - 2 * np.sqrt(variances.T[i]), + means.T[i] + 2 * np.sqrt(variances.T[i]), + facecolor=plots[-1].get_color(), + alpha=.3) + a.legend(borderaxespad=0.) + a.set_xlim(x.min(), x.max()) + if i < means.shape[1] - 1: + a.set_xticklabels('') + pb.draw() + fig.tight_layout(h_pad=.01) # , rect=(0, 0, 1, .95)) + return fig From d115e61b8d7b23d36429238df552d8abba099ca9 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:47:59 +0000 Subject: [PATCH 25/26] typo corrected --- GPy/core/svigp.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/GPy/core/svigp.py b/GPy/core/svigp.py index d54d3453..9e4f3b12 100644 --- a/GPy/core/svigp.py +++ b/GPy/core/svigp.py @@ -481,17 +481,17 @@ class SVIGP(GP): def plot(self, *args, **kwargs): """ - See GPy.plotting.matplot_dep.svgi_plots.plot + See GPy.plotting.matplot_dep.svig_plots.plot """ assert "matplotlib" in sys.modules, "matplotlib package has not been imported." - from ..plotting.matplot_dep import svgi_plots - svgi_plots.plot(self,*args,**kwargs) + from ..plotting.matplot_dep import svig_plots + svig_plots.plot(self,*args,**kwargs) def plot_traces(self): """ - See GPy.plotting.matplot_dep.svgi_plots.plot_traces + See GPy.plotting.matplot_dep.svig_plots.plot_traces """ assert "matplotlib" in sys.modules, "matplotlib package has not been imported." - from ..plotting.matplot_dep import svgi_plots - svgi_plots.plot_traces(self) + from ..plotting.matplot_dep import svig_plots + svig_plots.plot_traces(self) From 30724f72d9adf6cd55a39c84542aae4614045af1 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 28 Jan 2014 13:59:53 +0000 Subject: [PATCH 26/26] pylab library not needed --- GPy/inference/optimization/samplers.py | 4 ---- GPy/inference/optimization/sgd.py | 5 ----- 2 files changed, 9 deletions(-) diff --git a/GPy/inference/optimization/samplers.py b/GPy/inference/optimization/samplers.py index c2b47bce..fdb3df76 100644 --- a/GPy/inference/optimization/samplers.py +++ b/GPy/inference/optimization/samplers.py @@ -4,7 +4,6 @@ import numpy as np from scipy import linalg, optimize -import pylab as pb import Tango import sys import re @@ -80,6 +79,3 @@ class Metropolis_Hastings: fs.append(function(*args)) self.model._set_params(param)# reset model to starting state return fs - - - diff --git a/GPy/inference/optimization/sgd.py b/GPy/inference/optimization/sgd.py index 3f14dc4b..fd089bf5 100644 --- a/GPy/inference/optimization/sgd.py +++ b/GPy/inference/optimization/sgd.py @@ -3,7 +3,6 @@ import scipy as sp import scipy.sparse from optimization import Optimizer from scipy import linalg, optimize -import pylab as plt import copy, sys, pickle class opt_SGD(Optimizer): @@ -285,7 +284,6 @@ class opt_SGD(Optimizer): b = len(features)/self.batch_size features = [features[i::b] for i in range(b)] NLL = [] - import pylab as plt for count, j in enumerate(features): self.Model.input_dim = len(j) self.Model.likelihood.input_dim = len(j) @@ -318,9 +316,6 @@ class opt_SGD(Optimizer): self.adapt_learning_rate(it+count, D) NLL.append(f) self.fopt_trace.append(NLL[-1]) - # fig = plt.figure('traces') - # plt.clf() - # plt.plot(self.param_traces['noise']) # for k in self.param_traces.keys(): # self.param_traces[k].append(self.Model.get(k)[0])