diff --git a/EIVPackage/EIVData/cubic.py b/EIVPackage/EIVData/cubic.py
index a9eda381bc4d1f45cb39964f824bfc2b172a51a4..c4a06540c19c990474483c2127b0ea5597eccdf3 100644
--- a/EIVPackage/EIVData/cubic.py
+++ b/EIVPackage/EIVData/cubic.py
@@ -2,7 +2,8 @@ import torch
 import sys
 from torch.utils.data import TensorDataset
 
-from EIVGeneral.manipulate_tensors import add_noise
+from EIVGeneral.manipulate_tensors import add_noise, normalize_tensor,\
+        unnormalize_tensor
 
 total_number_of_datapoints = 2000
 input_range = [-4,4]
@@ -11,38 +12,63 @@ intercept = 0.0
 x_noise_strength = 0.05 * (input_range[1] - input_range[0])/2
 y_noise_strength = 3
 func = lambda true_x: slope * true_x**3 + intercept 
+
 def load_data(seed=0, splitting_part=0.8, normalize=True,
-        return_ground_truth=False):
+        return_ground_truth=False,
+        return_normalized_func=False,
+        fixed_seed = 0):
     """
-    Loads one-dimensional, cubic data as in Hernandez-Lobato, Adams 2015.
-    :param seed: Seed for drawing and splitting the data.
+    Loads one-dimensional data, cubic data as in Hernandez-Lobato, Adams 2015.
+    :param seed: Seed for shuffling the data before splitting.
     :param splitting_part: Which fraction of the data to use as training
     data. Defaults to 0.8.
     :param normalize: Whether to normalize the data, defaults to True.
     :param return_ground_truth: Boolean. If True, the unnoisy ground truth will
     also be returned. Defaults to False.
-    :returns: cubic_trainset, cubic_testset if return_ground_truth is False,
+    :param return_normalized_func: Boolean (default False). If True, the
+    normalized version of the used function is returned as a last element.
+    :param fixed_seed: Used to generate the full dataset (test and train).
+    Defaults to 0.
+    :returns: cubic_trainset, cubic_testset, (, normalized_func) if
+    return_ground_truth is False,
     else cubic_trainset, cubic_testset,  true_cubic_trainset,
-    true_cubic_testset. The later two return **four tensors**: The true x,y and
-    their noisy counterparts.
+    true_cubic_testset, (, normalized_func). The "true" datasets each return
+    **four tensors**: The true x,y and their noisy counterparts.
     """
-    random_generator = torch.Generator().manual_seed(seed)
     # draw different seeds for noise and splitting
+    random_generator = torch.Generator().manual_seed(fixed_seed)
     seeds = [int(t) for t in torch.randint(0,sys.maxsize,(3,),\
             generator=random_generator)]
+
     # create new generators from tensor seeds
     true_x = input_range[0] + (input_range[1]-input_range[0])\
                   * torch.rand((total_number_of_datapoints,1),
                           generator=torch.Generator().manual_seed(seeds[0]))
     true_y = func(true_x)
+
     # add noise and normalize x and y
-    (noisy_x, noisy_y), (true_x, true_y) = add_noise(
+    (noisy_x, noisy_y), (true_x, true_y), normalization_list = add_noise(
             tensor_list=(true_x, true_y),
             noise_strength_list=(x_noise_strength, y_noise_strength),
             seed_list=seeds[1:3],
-            normalize=normalize)
-    # create datasets
+            normalize=normalize,
+            return_normalization=True)
+    def normalized_func(x):
+        unnormalized_x = unnormalize_tensor(x, normalization_list[0])
+        y = func(unnormalized_x)
+        normalized_y = normalize_tensor(y, normalization_list[1])
+        return normalized_y
     dataset_len = noisy_x.shape[0]
+
+    # shuffle via seed
+    new_order = torch.randperm(dataset_len,
+            generator=torch.Generator().manual_seed(seed))
+    true_x = true_x[new_order, ...]
+    true_y = true_y[new_order, ...]
+    noisy_x = noisy_x[new_order, ...]
+    noisy_y = noisy_y[new_order, ...]
+
+    # create datasets
     train_len = int(dataset_len*splitting_part)
     test_len = dataset_len - train_len
     true_train_x, true_test_x = torch.split(true_x, [train_len, test_len])
@@ -55,8 +81,19 @@ def load_data(seed=0, splitting_part=0.8, normalize=True,
             noisy_train_x, noisy_train_y)
     true_cubic_testset = TensorDataset(true_test_x, true_test_y,
             noisy_test_x, noisy_test_y)
+
+
+    # return different objects, depending on Booleans
     if not return_ground_truth:
-        return cubic_trainset, cubic_testset
+        if not return_normalized_func:
+            return cubic_trainset, cubic_testset
+        else:
+            return cubic_trainset, cubic_testset, normalized_func
     else:
-        return cubic_trainset, cubic_testset, true_cubic_trainset,\
-            true_cubic_testset
+        if not return_normalized_func:
+            return cubic_trainset, cubic_testset, true_cubic_trainset,\
+                true_cubic_testset
+        else: 
+            return cubic_trainset, cubic_testset, true_cubic_trainset,\
+                true_cubic_testset, normalized_func
+
diff --git a/EIVPackage/EIVData/linear.py b/EIVPackage/EIVData/linear.py
index bbfc53298497613f51e6d9ebeac4c300d37da968..499e9d1848516e54990f8d7031c61fcf2f3e7676 100644
--- a/EIVPackage/EIVData/linear.py
+++ b/EIVPackage/EIVData/linear.py
@@ -2,7 +2,8 @@ import torch
 import sys
 from torch.utils.data import TensorDataset
 
-from EIVGeneral.manipulate_tensors import add_noise
+from EIVGeneral.manipulate_tensors import add_noise, normalize_tensor,\
+        unnormalize_tensor
 
 total_number_of_datapoints = 2000
 input_range = [-1,1]
@@ -13,37 +14,61 @@ y_noise_strength = 0.1
 func = lambda true_x: slope * true_x + intercept 
 
 def load_data(seed=0, splitting_part=0.8, normalize=True,
-        return_ground_truth=False):
+        return_ground_truth=False,
+        return_normalized_func=False,
+        fixed_seed = 0):
     """
     Loads one-dimensional data
-    :param seed: Seed for drawing and splitting the data.
+    :param seed: Seed for shuffling the data before splitting.
     :param splitting_part: Which fraction of the data to use as training
     data. Defaults to 0.8.
     :param normalize: Whether to normalize the data, defaults to True.
     :param return_ground_truth: Boolean. If True, the unnoisy ground truth will
     also be returned. Defaults to False.
-    :returns: linear_trainset, linear_testset if return_ground_truth is False,
+    :param return_normalized_func: Boolean (default False). If True, the
+    normalized version of the used function is returned as a last element.
+    :param fixed_seed: Used to generate the full dataset (test and train).
+    Defaults to 0.
+    :returns: linear_trainset, linear_testset, (, normalized_func) if
+    return_ground_truth is False,
     else linear_trainset, linear_testset,  true_linear_trainset,
-    true_linear_testset. The later two return **four tensors**: The true x,y and
-    their noisy counterparts.
+    true_linear_testset, (, normalized_func). The "true" datasets each return
+    **four tensors**: The true x,y and their noisy counterparts.
     """
-    random_generator = torch.Generator().manual_seed(seed)
     # draw different seeds for noise and splitting
+    random_generator = torch.Generator().manual_seed(fixed_seed)
     seeds = [int(t) for t in torch.randint(0,sys.maxsize,(3,),\
             generator=random_generator)]
+
     # create new generators from tensor seeds
     true_x = input_range[0] + (input_range[1]-input_range[0])\
                   * torch.rand((total_number_of_datapoints,1),
                           generator=torch.Generator().manual_seed(seeds[0]))
     true_y = func(true_x)
+
     # add noise and normalize x and y
-    (noisy_x, noisy_y), (true_x, true_y) = add_noise(
+    (noisy_x, noisy_y), (true_x, true_y), normalization_list = add_noise(
             tensor_list=(true_x, true_y),
             noise_strength_list=(x_noise_strength, y_noise_strength),
             seed_list=seeds[1:3],
-            normalize=normalize)
-    # create datasets
+            normalize=normalize,
+            return_normalization=True)
+    def normalized_func(x):
+        unnormalized_x = unnormalize_tensor(x, normalization_list[0])
+        y = func(unnormalized_x)
+        normalized_y = normalize_tensor(y, normalization_list[1])
+        return normalized_y
     dataset_len = noisy_x.shape[0]
+
+    # shuffle via seed
+    new_order = torch.randperm(dataset_len,
+            generator=torch.Generator().manual_seed(seed))
+    true_x = true_x[new_order, ...]
+    true_y = true_y[new_order, ...]
+    noisy_x = noisy_x[new_order, ...]
+    noisy_y = noisy_y[new_order, ...]
+
+    # create datasets
     train_len = int(dataset_len*splitting_part)
     test_len = dataset_len - train_len
     true_train_x, true_test_x = torch.split(true_x, [train_len, test_len])
@@ -56,8 +81,19 @@ def load_data(seed=0, splitting_part=0.8, normalize=True,
             noisy_train_x, noisy_train_y)
     true_linear_testset = TensorDataset(true_test_x, true_test_y,
             noisy_test_x, noisy_test_y)
+
+
+    # return different objects, depending on Booleans
     if not return_ground_truth:
-        return linear_trainset, linear_testset
+        if not return_normalized_func:
+            return linear_trainset, linear_testset
+        else:
+            return linear_trainset, linear_testset, normalized_func
     else:
-        return linear_trainset, linear_testset, true_linear_trainset,\
-            true_linear_testset
+        if not return_normalized_func:
+            return linear_trainset, linear_testset, true_linear_trainset,\
+                true_linear_testset
+        else: 
+            return linear_trainset, linear_testset, true_linear_trainset,\
+                true_linear_testset, normalized_func
+
diff --git a/EIVPackage/EIVData/quadratic.py b/EIVPackage/EIVData/quadratic.py
index c662b1326da99faf9f295364ed7fef1aeeca8873..13ab3f13c3ae1aa812bd2e4b6e281d6d40cc527d 100644
--- a/EIVPackage/EIVData/quadratic.py
+++ b/EIVPackage/EIVData/quadratic.py
@@ -2,7 +2,8 @@ import torch
 import sys
 from torch.utils.data import TensorDataset
 
-from EIVGeneral.manipulate_tensors import add_noise
+from EIVGeneral.manipulate_tensors import add_noise, normalize_tensor,\
+        unnormalize_tensor
 
 total_number_of_datapoints = 2000
 input_range = [-1,1]
@@ -13,37 +14,61 @@ y_noise_strength = 0.1
 func = lambda true_x: slope * true_x**2 + intercept 
 
 def load_data(seed=0, splitting_part=0.8, normalize=True,
-        return_ground_truth=False):
+        return_ground_truth=False,
+        return_normalized_func=False,
+        fixed_seed = 0):
     """
     Loads one-dimensional data
-    :param seed: Seed for drawing and splitting the data.
+    :param seed: Seed for shuffling the data before splitting.
     :param splitting_part: Which fraction of the data to use as training
     data. Defaults to 0.8.
     :param normalize: Whether to normalize the data, defaults to True.
     :param return_ground_truth: Boolean. If True, the unnoisy ground truth will
     also be returned. Defaults to False.
-    :returns: quadratic_trainset, quadratic_testset if return_ground_truth is False,
+    :param return_normalized_func: Boolean (default False). If True, the
+    normalized version of the used function is returned as a last element.
+    :param fixed_seed: Used to generate the full dataset (test and train).
+    Defaults to 0.
+    :returns: quadratic_trainset, quadratic_testset, (, normalized_func) if
+    return_ground_truth is False,
     else quadratic_trainset, quadratic_testset,  true_quadratic_trainset,
-    true_quadratic_testset. The later two return **four tensors**: The true x,y and
-    their noisy counterparts.
+    true_quadratic_testset, (, normalized_func). The "true" datasets each return
+    **four tensors**: The true x,y and their noisy counterparts.
     """
-    random_generator = torch.Generator().manual_seed(seed)
     # draw different seeds for noise and splitting
+    random_generator = torch.Generator().manual_seed(fixed_seed)
     seeds = [int(t) for t in torch.randint(0,sys.maxsize,(3,),\
             generator=random_generator)]
+
     # create new generators from tensor seeds
     true_x = input_range[0] + (input_range[1]-input_range[0])\
                   * torch.rand((total_number_of_datapoints,1),
                           generator=torch.Generator().manual_seed(seeds[0]))
     true_y = func(true_x)
+
     # add noise and normalize x and y
-    (noisy_x, noisy_y), (true_x, true_y) = add_noise(
+    (noisy_x, noisy_y), (true_x, true_y), normalization_list = add_noise(
             tensor_list=(true_x, true_y),
             noise_strength_list=(x_noise_strength, y_noise_strength),
             seed_list=seeds[1:3],
-            normalize=normalize)
-    # create datasets
+            normalize=normalize,
+            return_normalization=True)
+    def normalized_func(x):
+        unnormalized_x = unnormalize_tensor(x, normalization_list[0])
+        y = func(unnormalized_x)
+        normalized_y = normalize_tensor(y, normalization_list[1])
+        return normalized_y
     dataset_len = noisy_x.shape[0]
+
+    # shuffle via seed
+    new_order = torch.randperm(dataset_len,
+            generator=torch.Generator().manual_seed(seed))
+    true_x = true_x[new_order, ...]
+    true_y = true_y[new_order, ...]
+    noisy_x = noisy_x[new_order, ...]
+    noisy_y = noisy_y[new_order, ...]
+
+    # create datasets
     train_len = int(dataset_len*splitting_part)
     test_len = dataset_len - train_len
     true_train_x, true_test_x = torch.split(true_x, [train_len, test_len])
@@ -56,8 +81,19 @@ def load_data(seed=0, splitting_part=0.8, normalize=True,
             noisy_train_x, noisy_train_y)
     true_quadratic_testset = TensorDataset(true_test_x, true_test_y,
             noisy_test_x, noisy_test_y)
+
+
+    # return different objects, depending on Booleans
     if not return_ground_truth:
-        return quadratic_trainset, quadratic_testset
+        if not return_normalized_func:
+            return quadratic_trainset, quadratic_testset
+        else:
+            return quadratic_trainset, quadratic_testset, normalized_func
     else:
-        return quadratic_trainset, quadratic_testset, true_quadratic_trainset,\
-            true_quadratic_testset
+        if not return_normalized_func:
+            return quadratic_trainset, quadratic_testset, true_quadratic_trainset,\
+                true_quadratic_testset
+        else: 
+            return quadratic_trainset, quadratic_testset, true_quadratic_trainset,\
+                true_quadratic_testset, normalized_func
+
diff --git a/EIVPackage/EIVData/sine.py b/EIVPackage/EIVData/sine.py
index f68112e30e357597369a548c19da60735aea5c5e..a420654e57379c165c5b867b6f3e25bab684af21 100644
--- a/EIVPackage/EIVData/sine.py
+++ b/EIVPackage/EIVData/sine.py
@@ -2,7 +2,8 @@ import torch
 import sys
 from torch.utils.data import TensorDataset
 
-from EIVGeneral.manipulate_tensors import add_noise
+from EIVGeneral.manipulate_tensors import add_noise, normalize_tensor,\
+        unnormalize_tensor
 
 total_number_of_datapoints = 2000
 input_range = [-0.2,0.8]
@@ -14,37 +15,61 @@ func = lambda true_x: true_x +\
             torch.sin(4 * torch.pi * true_x)
 
 def load_data(seed=0, splitting_part=0.8, normalize=True,
-        return_ground_truth=False):
+        return_ground_truth=False,
+        return_normalized_func=False,
+        fixed_seed = 0):
     """
     Loads one-dimensional, sine shaped data as in Blundell et al. 2014.
-    :param seed: Seed for drawing and splitting the data.
+    :param seed: Seed for shuffling the data before splitting.
     :param splitting_part: Which fraction of the data to use as training
     data. Defaults to 0.8.
     :param normalize: Whether to normalize the data, defaults to True.
     :param return_ground_truth: Boolean. If True, the unnoisy ground truth will
     also be returned. Defaults to False.
-    :returns: sine_trainset, sine_testset if return_ground_truth is False,
+    :param return_normalized_func: Boolean (default False). If True, the
+    normalized version of the used function is returned as a last element.
+    :param fixed_seed: Used to generate the full dataset (test and train).
+    Defaults to 0.
+    :returns: sine_trainset, sine_testset, (, normalized_func) if
+    return_ground_truth is False,
     else sine_trainset, sine_testset,  true_sine_trainset,
-    true_sine_testset. The later two return **four tensors**: The true x,y and
-    their noisy counterparts.
+    true_sine_testset, (, normalized_func). The "true" datasets each return
+    **four tensors**: The true x,y and their noisy counterparts.
     """
-    random_generator = torch.Generator().manual_seed(seed)
     # draw different seeds for noise and splitting
+    random_generator = torch.Generator().manual_seed(fixed_seed)
     seeds = [int(t) for t in torch.randint(0,sys.maxsize,(3,),\
             generator=random_generator)]
+
     # create new generators from tensor seeds
     true_x = input_range[0] + (input_range[1]-input_range[0])\
                   * torch.rand((total_number_of_datapoints,1),
                           generator=torch.Generator().manual_seed(seeds[0]))
     true_y = func(true_x)
+
     # add noise and normalize x and y
-    (noisy_x, noisy_y), (true_x, true_y) = add_noise(
+    (noisy_x, noisy_y), (true_x, true_y), normalization_list = add_noise(
             tensor_list=(true_x, true_y),
             noise_strength_list=(x_noise_strength, y_noise_strength),
             seed_list=seeds[1:3],
-            normalize=normalize)
-    # create datasets
+            normalize=normalize,
+            return_normalization=True)
+    def normalized_func(x):
+        unnormalized_x = unnormalize_tensor(x, normalization_list[0])
+        y = func(unnormalized_x)
+        normalized_y = normalize_tensor(y, normalization_list[1])
+        return normalized_y
     dataset_len = noisy_x.shape[0]
+
+    # shuffle via seed
+    new_order = torch.randperm(dataset_len,
+            generator=torch.Generator().manual_seed(seed))
+    true_x = true_x[new_order, ...]
+    true_y = true_y[new_order, ...]
+    noisy_x = noisy_x[new_order, ...]
+    noisy_y = noisy_y[new_order, ...]
+
+    # create datasets
     train_len = int(dataset_len*splitting_part)
     test_len = dataset_len - train_len
     true_train_x, true_test_x = torch.split(true_x, [train_len, test_len])
@@ -57,8 +82,19 @@ def load_data(seed=0, splitting_part=0.8, normalize=True,
             noisy_train_x, noisy_train_y)
     true_sine_testset = TensorDataset(true_test_x, true_test_y,
             noisy_test_x, noisy_test_y)
+
+
+    # return different objects, depending on Booleans
     if not return_ground_truth:
-        return sine_trainset, sine_testset
+        if not return_normalized_func:
+            return sine_trainset, sine_testset
+        else:
+            return sine_trainset, sine_testset, normalized_func
     else:
-        return sine_trainset, sine_testset, true_sine_trainset,\
-            true_sine_testset
+        if not return_normalized_func:
+            return sine_trainset, sine_testset, true_sine_trainset,\
+                true_sine_testset
+        else: 
+            return sine_trainset, sine_testset, true_sine_trainset,\
+                true_sine_testset, normalized_func
+
diff --git a/EIVPackage/EIVGeneral/manipulate_datasets.py b/EIVPackage/EIVGeneral/manipulate_datasets.py
index f04280e3a84f374cef1705a3e53a6607a6d0e394..553db1672f547837309c20383e788d35953933d8 100644
--- a/EIVPackage/EIVGeneral/manipulate_datasets.py
+++ b/EIVPackage/EIVGeneral/manipulate_datasets.py
@@ -19,3 +19,7 @@ class VerticalCut(Dataset):
 
     def __len__(self):
         return len(self.dataset)
+
+    @property
+    def tensors(self):
+        return itemgetter(*self.components_to_pick)(self.dataset.tensors)
diff --git a/EIVPackage/EIVGeneral/manipulate_tensors.py b/EIVPackage/EIVGeneral/manipulate_tensors.py
index 20c37a63ed2be6cc6a618b0d9c7a712ba8c81df7..57392fdfe722a0afc6250d29f2388a121242f7b7 100644
--- a/EIVPackage/EIVGeneral/manipulate_tensors.py
+++ b/EIVPackage/EIVGeneral/manipulate_tensors.py
@@ -18,9 +18,17 @@ def normalize_tensor(t, mean_std):
     """
     return (t-mean_std[0])/mean_std[1]
 
+def unnormalize_tensor(t, mean_std):
+    """
+    Unnormalize the tensor `t` by the mean `mean_std[0]` and the standard
+    devation `mean_std[1]`. The inverse of `normalize_tensor`.
+    """
+    return t * mean_std[1] + mean_std[0]
+
+
 
 def add_noise(tensor_list, noise_strength_list, seed_list, normalize=True,
-        normalization_list = None):
+        normalization_list = None, return_normalization = False):
     """
     Takes the tensors in `tensor_list`, adds random noise using the standard
     deviations in `noise_strength_list` and the seeds in `seed_list`, then, if
@@ -35,10 +43,14 @@ def add_noise(tensor_list, noise_strength_list, seed_list, normalize=True,
     :param normalization_list: Either None (default) or a list of tensors.
     If the latter, these tensors will be used for normalization and `normalize`
     is assumed to be True.
-    :returns: noisy_tensor_list, unnoisy_tensor_list, both normalized
+    :param list_of_normalization: Boolean. If True (default: False) the
+    used normalizations will be returned.
+    :returns: noisy_tensor_list, unnoisy_tensor_list(, list_of_normalization)
     """
     noisy_t_list = []
     unnoisy_t_list = []
+    # store tuples that were used for normalization in here
+    list_of_normalization = []
     if normalization_list is not None:
         assert len(normalization_list) == len(tensor_list)
     for i, (t,noise,seed) in enumerate(zip(tensor_list, noise_strength_list,\
@@ -51,9 +63,12 @@ def add_noise(tensor_list, noise_strength_list, seed_list, normalize=True,
                         get_normalization(normalization_list[i])
             else:
                 noisy_t_normalization = get_normalization(noisy_t)
+            list_of_normalization.append(noisy_t_normalization)
             noisy_t = normalize_tensor(noisy_t, noisy_t_normalization)
             t = normalize_tensor(t, noisy_t_normalization)
         noisy_t_list.append(noisy_t)
         unnoisy_t_list.append(t)
-    return noisy_t_list, unnoisy_t_list
-
+    if return_normalization:
+        return noisy_t_list, unnoisy_t_list, list_of_normalization
+    else:
+        return noisy_t_list, unnoisy_t_list
diff --git a/Experiments/plot_prediction.py b/Experiments/plot_prediction.py
index ab29feddb8d26242f83d690bcf25bf5207b78943..61fac8dfa9dce0ebe87cabb9e49be9109b219802 100644
--- a/Experiments/plot_prediction.py
+++ b/Experiments/plot_prediction.py
@@ -1,6 +1,8 @@
 """
 Plot predictions with uncertainties for (simulated) datasets with a ground 
-truth.
+truth. At the moment it is assumed that the used datasets have an output
+dimension equal to 1. Plots are only produced for datasets with input dimension
+and output dimension 1.
 """
 import importlib
 import os
@@ -25,15 +27,20 @@ def compute_predictions_and_uncertainties(data, x_range, eiv, number_of_draws,
     throuth their JSON configuration and evaluate their prediction and
     uncertainties for the (true) x in `x_range`. The results returned are as numpy
     arrays included in a `plotting_dictionary` that contains the predictions
-    and uncertainties via the keys "prediction" and "uncertainty" but also the
-    noisified version of `x_range` and the corresponding y values (key
-    "range_points") and `number_of_test_datapoints` points from the test
-    dataset with seed `plotting_seed` (key "test_data_points").
+    and uncertainties via the keys "prediction" and "uncertainty" but also 
+    - A tuple of `x_range` and the corresponding values of y (key
+            "range_points")
+    - the noisified version of `x_range` and the corresponding y values (key
+    "noisy_range_points") and 
+    - `number_of_test_datapoints` points from the test
+    dataset with seed `plotting_seed` (key "test_data_points") and
+    - the input dimension (key "input_dim").
 
     **Note**: The output of the neural networks are assumed to be
     one-dimensional .
 
-    :data: String, short dataname
+    :data: String, short dataname. The corresponding module should contain
+    `x_noise_strength`, `y_noise_strength`.
     :x_range: An iterator yielding the (true) x values to consider
     :eiv: Boolean. If True an EiV model is used, else an non-EiV model.
     :number_of_draws: Number of draws to use for prediction. Take an int for
@@ -41,7 +48,7 @@ def compute_predictions_and_uncertainties(data, x_range, eiv, number_of_draws,
     :x_noise_seed: An integer. Will be used as a seed to generate the noise put
     on `x_range`.
     :y_noise_seed: An integer. Will be used as a seed to generate the noise put
-    on `func(x_range)` that will be returned with `range_values` in the
+    on `normalized_func(x_range)` that will be returned with `range_values` in the
     `plotting_dictionary`.
     :plotting_seed: An integer. Needed for choosing which of the test datasets
     will be used to returning the test datapoints.
@@ -59,16 +66,19 @@ def compute_predictions_and_uncertainties(data, x_range, eiv, number_of_draws,
                 conf_file:
             conf_dict = json.load(conf_file)
 
+    # get datanames
     long_dataname = conf_dict["long_dataname"]
     short_dataname = conf_dict["short_dataname"]
 
 
+    # load hyperparameters
     load_data = importlib.import_module(f'EIVData.{long_dataname}').load_data
     x_noise_strength =\
         importlib.import_module(f'EIVData.{long_dataname}').x_noise_strength
     y_noise_strength =\
         importlib.import_module(f'EIVData.{long_dataname}').y_noise_strength
-    func = importlib.import_module(f'EIVData.{long_dataname}').func
+    seed_list = range(conf_dict["seed_range"][0],
+            conf_dict["seed_range"][1])
 
     # switch to gpu, if possible
     try:
@@ -87,19 +97,21 @@ def compute_predictions_and_uncertainties(data, x_range, eiv, number_of_draws,
         device = torch.device('cpu')
 
 
+    # determine dimensions
     _, test_data = load_data(seed=plotting_seed, return_ground_truth=False)
     input_dim = test_data[0][0].numel()
     output_dim = test_data[0][1].numel()
     assert output_dim == 1
+    # store in plotting_dictionary
+    plotting_dictionary['input_dim'] = input_dim
+
+    # store test datapoints
     test_x, test_y = test_data[:number_of_test_datapoints]
     plotting_dictionary['test_data_points'] = (test_x.detach().cpu().numpy(),
             test_y.detach().cpu().numpy())
 
-    ## Create iterators for get_coverage_distribution
-    seed_list = range(conf_dict["seed_range"][0],
-            conf_dict["seed_range"][1])
 
-    # iterator for networks
+    # iterator for looping through networks
     def net_iterator(eiv=eiv, seed_list=seed_list):
         """
         Yields EiV models (if `eiv`) or
@@ -145,17 +157,28 @@ def compute_predictions_and_uncertainties(data, x_range, eiv, number_of_draws,
                         net=net, device=device)
                 yield net
     
+    # add feature dimension (if necessary) 
     x_range = x_range.view((-1, input_dim))
+    y_range = normalized_func(x_range)
+    # noisify
     noisy_x_range = x_range + x_noise_strength * torch.randn(x_range.shape,
             generator=torch.Generator().manual_seed(x_noise_seed))
-    # add feature dimension (if necessary) and move to device
-    noisy_x_range = noisy_x_range.to(device)
-    noisy_y_range = func(x_range) + y_noise_strength *\
+    # move to device for later processing
+    noisy_x_range = noisy_x_range.to(device) 
+    # y values for noisy_x_range (not on device)
+    noisy_y_range = y_range + y_noise_strength *\
     torch.randn(x_range.shape,
             generator=torch.Generator().manual_seed(y_noise_seed))
-    plotting_dictionary['range_points'] =\
+    # save in plotting_dictionary
+    plotting_dictionary['noisy_range_points'] =\
             (noisy_x_range.detach().cpu().numpy(),
             noisy_y_range.detach().cpu().numpy())
+    plotting_dictionary['range_points'] =\
+            (x_range.detach().cpu().numpy(),
+            y_range.detach().cpu().numpy())
+
+
+    # loop through networks and predict
     mean_collection, unc_collection = [], []
     for net in net_iterator(eiv=eiv):
         mean, unc = net.predict_mean_and_unc(noisy_x_range,
@@ -176,7 +199,8 @@ def compute_predictions_and_uncertainties(data, x_range, eiv, number_of_draws,
     # stack collections along a new, first dimension
     mean_collection = torch.stack(mean_collection, dim=0)
     unc_collection = torch.stack(unc_collection, dim=0)
-    # average
+
+    # save average in plotting_dictionary
     plotting_dictionary['prediction'] =\
             torch.mean(mean_collection, dim=0).detach().cpu().numpy()
     plotting_dictionary['uncertainty'] =\
@@ -184,3 +208,36 @@ def compute_predictions_and_uncertainties(data, x_range, eiv, number_of_draws,
     return plotting_dictionary
 
 
+data_list = ['sine'] # short datanames
+list_x_range = [torch.linspace(0.0,1.0, 50)]
+list_color = [('red','blue')]
+list_number_of_draws = [((100,5), 100)]
+for i, (data, x_range, color, number_of_draws) in enumerate(zip(data_list,
+    list_x_range, list_color, list_number_of_draws)):
+    eiv_plotting_dictionary = compute_predictions_and_uncertainties(
+            data=data,
+            x_range=x_range,
+            eiv=True,
+            number_of_draws=number_of_draws[0])
+    noneiv_plotting_dictionary = compute_predictions_and_uncertainties(
+            data=data,
+            x_range=x_range,
+            eiv=False,
+            number_of_draws=number_of_draws[1])
+    input_dim = eiv_plotting_dictionary['input_dim']
+    if input_dim == 1:
+        plt.figure(i)
+        plt.clf()
+        x_values, y_values = eiv_plotting_dictionary['range_points']
+        plt.plot(x_values, y_values,'-', color='k')
+        # plt.plot(x_values, eiv_plotting_dictionary['prediction'],'-',
+        #         color=color[0])
+        # plt.plot(x_values, noneiv_plotting_dictionary['prediction'],'-',
+        #         color=color[1])
+    else:
+        # multidimensional handling not included yet
+        pass
+
+
+plt.show()    
+