def demo_2D():
    # Create a Gaussian Process
    x_training = np.array([
        [0., 0.],
        [1.5, 1.5],
        [3., 3.],
        [0., 1.5],
        [1.5, 0.],
        [0., 3.],
        [3., 0.],
        [3., 1.5],
        [1.5, 3.]
    ])

    y_training = get_y_simulated_2D(x_training)

    gp = GaussianProcess(x_training, y_training)
    np.random.seed(47)
    gp = fit_GP_MAP(gp)

    # Define observation
    obs = [0.1, 0.0004]

    # Coords to predict
    n_rand = 2000
    a_predict_min = 0
    a_predict_max = np.pi
    b_predict_min = a_predict_min
    b_predict_max = a_predict_max
    a_predict = np.random.rand(n_rand) * (a_predict_max - a_predict_min) + a_predict_min
    b_predict = np.random.rand(n_rand) * (b_predict_max - b_predict_min) + b_predict_min
    x_predict = np.concatenate((a_predict[:,None], b_predict[:,None]), axis=1)
    x_predict = np.concatenate((x_predict, x_training), axis=0)

    coords = x_predict

    # Compute GPE expectations
    expectations = gp.predict(coords)

    # Compute Implausbility
    hm = HistoryMatching(obs=obs, expectations=expectations)
    I = hm.get_implausibility()
    NROY = hm.get_NROY()
    RO = hm.get_RO()

    print("Fraction of points ruled out {:6}".format(str(float(len(RO))/float(n_rand))))

    # Plotting
    if makeplots:
        from mpl_toolkits.mplot3d import Axes3D
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')

        Axes3D.scatter(     # Training Data
            ax,
            x_training[:,0],
            x_training[:,1],
            y_training,
            color='black',
            marker = '.',
            s = 100
        )

        #Axes3D.scatter(      # GPE prediction
        #    ax,
        #    coords[:,0],
        #    coords[:,1],
        #    expectations[0],
        #    color='red',
        #    marker='.',
        #    s=2
        #)

        Axes3D.scatter(     # GPE prediction uncertainty
            ax,
            coords[:,0][RO],
            coords[:,1][RO],
            expectations[0][RO] + 3*np.sqrt(expectations[1][RO]),
            color='red',
            marker='.',
            s=1
        )
        Axes3D.scatter(
            ax,
            coords[:,0][RO],
            coords[:,1][RO],
            expectations[0][RO] - 3*np.sqrt(expectations[1][RO]),
            color='red',
            marker='.',
            s=1
        )
        Axes3D.scatter(
            ax,
            coords[:,0][NROY],
            coords[:,1][NROY],
            expectations[0][NROY] + 3*np.sqrt(expectations[1][NROY]),
            color='green',
            marker='.',
            s=1
        )
        Axes3D.scatter(
            ax,
            coords[:,0][NROY],
            coords[:,1][NROY],
            expectations[0][NROY] - 3*np.sqrt(expectations[1][NROY]),
            color='green',
            marker='.',
            s=1
        )

        Axes3D.set(
            ax,
            xlabel = 'Input parameter a',
            ylabel = 'Input parameter b',
            zlabel = 'Model output f(a, b)'
        )



        plt.savefig('histmatch_2D.png', bbox_inches = "tight")