diff --git a/lib/storage/@LevelData/LevelData.m b/lib/storage/@LevelData/LevelData.m
index 1d92859a38d61f6709d75559a926cdcfb16265e3..a41af48b65e135af4824ae642e611c5eafa65dec 100644
--- a/lib/storage/@LevelData/LevelData.m
+++ b/lib/storage/@LevelData/LevelData.m
@@ -28,10 +28,6 @@ classdef LevelData < handle
         level (1,:) struct
         % Dictionary of data types
         type (1,1) dictionary
-        % Cell array of names of absolute value variables
-        absoluteVariable (1,:) cell
-        % Cell array of names of timing variables
-        timeVariable (1,:) cell
     end
 
     properties (Access=private)
@@ -60,6 +56,10 @@ classdef LevelData < handle
         nTimeVariable (1,1) int32
         % Boolean indicating whether data has been stored for a single level
         isInitialRun (1,1) logical
+        % Cell array of names of absolute value variables
+        absoluteVariable (1,:) cell
+        % Cell array of names of timing variables
+        timeVariable (1,:) cell
     end
 
     properties (Dependent, Access=private)
@@ -145,25 +145,12 @@ classdef LevelData < handle
         function bool = get.isScalar(obj)
             % Creates boolean vector determining whether a variable
             % contains a scalar value per level only
-            bool = false(1, obj.nVariable);
-            for j = 1:obj.nVariable
-                t = obj.type(obj.label{j});
-                if strcmp(t.shape, 's')
-                    bool(j) = true;
-                end
-            end
+            bool = [obj.type(obj.label).isScalar]';
         end
 
         function variables = get.scalarVariable(obj)
             % Returns list of names of all scalar variables
-            variables = cell(obj.nScalarVariable, 1);
-            k = 1;
-            for j = 1:obj.nVariable
-                if obj.isScalar(j)
-                    variables{k} = obj.label{j};
-                    k = k + 1;
-                end
-            end
+            variables = obj.label(obj.isScalar);
         end
 
         function nVariable = get.nScalarVariable(obj)
@@ -172,20 +159,22 @@ classdef LevelData < handle
 
         function variables = get.timeVariable(obj)
             % Returns list of names of all time variables
-            variables = obj.timeVariable;
+            idx = (obj.category(obj.label) == DataCategory.TIME);
+            variables = obj.label(idx);
         end
 
         function nVariable = get.nTimeVariable(obj)
-            nVariable = length(obj.timeVariable);
+            nVariable = nnz(obj.category.values() == DataCategory.TIME);
         end
 
         function variables = get.absoluteVariable(obj)
             % Returns list of names of all absolute variables
-            variables = obj.absoluteVariable;
+            idx = (obj.category(obj.label) == DataCategory.ABSOLUTE);
+            variables = obj.label(idx);
         end
 
         function nVariable = get.nAbsoluteVariable(obj)
-            nVariable = length(obj.absoluteVariable);
+            nVariable = nnz(obj.category.values() == DataCategory.ABSOLUTE);
         end
 
         function bool = get.isInitialRun(obj)
diff --git a/lib/storage/@LevelData/get.m b/lib/storage/@LevelData/get.m
index 585f8090b5149de0b00c11c17e8e6012ab43470c..c130089623ad775a2c9d93b97a96c12135fc96ff 100644
--- a/lib/storage/@LevelData/get.m
+++ b/lib/storage/@LevelData/get.m
@@ -36,7 +36,6 @@ function data = get(obj, jLevel, variableName)
 
     % Initialise return variable
     data = nan(length(jLevel), length(variableName));
-    containsCharOnly = true;
 
     % filter non-existing variables
     existingVariables = ismember(variableName, obj.label);
@@ -53,10 +52,7 @@ function data = get(obj, jLevel, variableName)
         idx = obj.getIndex(name);
         if obj.isScalar(idx)
             % Extract scalar variables for each level
-            value = zeros(length(jLevel), 1);
-            for k = 1:length(jLevel)
-                value(k) = obj.level(jLevel(k)).(name);
-            end
+            value = [obj.level.(name)];
         else
             % Extract non-scalar variables only in case of a single level
             if length(jLevel) > 1
diff --git a/lib/storage/@LevelData/plot.m b/lib/storage/@LevelData/plot.m
index 008d133fc005cf2404c5c333d0431c33f0f54be1..1151963f6c7313b49169568fbd5fa489971ca05b 100644
--- a/lib/storage/@LevelData/plot.m
+++ b/lib/storage/@LevelData/plot.m
@@ -34,14 +34,5 @@ function ax = plot(obj, xVariable, yVariable)
         yVariable = setdiff(obj.label, xVariable);
     end
 
-    % TODO: introduce plot specification to allow for different plot types (time, absolute, level)
-
-    % Plot only scalar variables that do not belong to time or absolute
-    % variables
-    yVariable = intersect(yVariable, obj.scalarVariable);
-    yVariable = setdiff(yVariable, obj.absoluteVariable);
-    yVariable = setdiff(yVariable, obj.timeVariable);
-
-    % Creates double logarithmic splot 
     ax = obj.plotLevel(DataCategory.ERROR, xVariable, yVariable);
 end
\ No newline at end of file
diff --git a/lib/storage/@LevelData/plotAbsolute.m b/lib/storage/@LevelData/plotAbsolute.m
index 949b85fc1f9a55a12ad98ef8cbe3af04441ed855..931353fe3b137c3be13c32a0fe90d7ceeac0eaa0 100644
--- a/lib/storage/@LevelData/plotAbsolute.m
+++ b/lib/storage/@LevelData/plotAbsolute.m
@@ -35,10 +35,5 @@ function ax = plotAbsolute(obj, xVariable, yVariable)
         yVariable = setdiff(obj.label, xVariable);
     end
 
-    % Plot only scalar variables that do belong to absolute variables
-    yVariable = intersect(yVariable, obj.scalarVariable);
-    yVariable = intersect(yVariable, obj.absoluteVariable);
-
-    % Creates semilogx plot 
     ax = obj.plotLevel(DataCategory.ABSOLUTE, xVariable, yVariable);
 end
\ No newline at end of file
diff --git a/lib/storage/@LevelData/plotLevel.m b/lib/storage/@LevelData/plotLevel.m
index 0394ee4abef68326b6e13909d8a8b15aa884fc80..a52dc28a8efdfb8d64d17d75af799f44ec618b4a 100644
--- a/lib/storage/@LevelData/plotLevel.m
+++ b/lib/storage/@LevelData/plotLevel.m
@@ -28,6 +28,12 @@ function ax = plotLevel(obj, category, xVariable, yVariable)
         yVariable cell
     end
 
+    % Extract variables with correct category, type, and shape for y-axis
+    idx = (obj.category(yVariable) == category) ...
+        & ([obj.type(yVariable).rawType]' == RawType.FLOAT) ...
+        & [obj.type(yVariable).isScalar]';
+    yVariable = yVariable(idx); 
+
     % Create handle to currently active axis object
     ax = gca;
 
@@ -39,18 +45,16 @@ function ax = plotLevel(obj, category, xVariable, yVariable)
 
     % Iterate over given variables
     for j = 1:length(yVariable)
-        if obj.type(yVariable{j}).rawType ~= RawType.FLOAT
-            continue
-        end
-
         % Extract value for y-axis
         yValue = obj.get(1:obj.nLevel, yVariable{j});
+
         % Extract label for legend from dictionary
         if isfield(obj.dictionary, yVariable{j})
             variableLabel = obj.dictionary.(yVariable{j});
         else
             variableLabel = yVariable{j};
         end
+
         % Create plot
         category.plotFunction( ...
                 ax, xValue, yValue, '-', ...
diff --git a/lib/storage/@LevelData/plotTime.m b/lib/storage/@LevelData/plotTime.m
index be727319d272b63cf7bf7dcee4f3429365efce99..3b7693f5f684259fe1465bff7b0ccdff03de12fc 100644
--- a/lib/storage/@LevelData/plotTime.m
+++ b/lib/storage/@LevelData/plotTime.m
@@ -34,10 +34,5 @@ function ax = plotTime(obj, xVariable, yVariable)
         yVariable = setdiff(obj.label, xVariable);
     end
 
-    % Plot only scalar variables that do belong to time variables
-    yVariable = intersect(yVariable, obj.scalarVariable);
-    yVariable = intersect(yVariable, obj.timeVariable);
-
-    % Creates double logarithmic splot 
     ax = obj.plotLevel(DataCategory.TIME, xVariable, yVariable);
 end
\ No newline at end of file
diff --git a/lib/storage/@LevelData/set.m b/lib/storage/@LevelData/set.m
index 6f4434e1aecc846693280b7155d8b19096c363de..7a3ee72195dcda906172a451be472995e9f035ab 100644
--- a/lib/storage/@LevelData/set.m
+++ b/lib/storage/@LevelData/set.m
@@ -42,19 +42,21 @@ function set(obj, jLevel, variableName, value)
     for j = 1:nArgument
         name = variableName{j};
         val = value{j};
-        % Determine type of data
+        
         if isa(val, 'ValueDetails')
             % Copy type argument
             currentType = val;
             valueList = repmat({nan}, length(jLevel), 1);
         else
-            % Determine type by example data
             [valueList, currentType] = splitIntoLevelWiseData(length(jLevel), val);
         end
-        % Store type
+
+        % Store type and category
         if ~ismember(name, obj.label)
             obj.type(name) = currentType.adaptPrintWidthTo(name);
+            obj.category(name) = DataCategory.ERROR;
         end
+
         % Store level-oriented data
         for k = 1:length(jLevel)
             obj.level(jLevel(k)).(name) = valueList{k};
diff --git a/lib/storage/@LevelData/setAbsolute.m b/lib/storage/@LevelData/setAbsolute.m
index d0f07d280788095be36f54149d10454bfec66e88..d5fbf92a22bc227a71c503f2f1e56d0cd875aa23 100644
--- a/lib/storage/@LevelData/setAbsolute.m
+++ b/lib/storage/@LevelData/setAbsolute.m
@@ -45,22 +45,21 @@ function setAbsolute(obj, jLevel, variableName, value)
     for j = 1:nArgument
         name = variableName{j};
         val = value{j};
-        % Determine type of data
+
         if isa(val, 'ValueDetails')
             % Copy type argument
             currentType = val;
             valueList = repmat({nan}, length(jLevel), 1);
         else
-            % Determine type by example data
             [valueList, currentType] = splitIntoLevelWiseData(length(jLevel), val);
         end
 
+        % Store type and category
         if ~ismember(name, obj.absoluteVariable)
-            % Store type
             obj.type(name) = currentType.adaptPrintWidthTo(name);
-            % Store variable as absolute variable
-            obj.absoluteVariable{end+1} = name;
+            obj.category(name) = DataCategory.ABSOLUTE;
         end
+
         % Store level-oriented data
         for k = 1:length(jLevel)
             obj.level(jLevel(k)).(name) = valueList{k};
diff --git a/lib/storage/@LevelData/setTime.m b/lib/storage/@LevelData/setTime.m
index 958a0fad58b86c67898295a94efcf4ac02d7864a..c492f28de989cb54686235506c863c0ebceeb1ed 100644
--- a/lib/storage/@LevelData/setTime.m
+++ b/lib/storage/@LevelData/setTime.m
@@ -45,23 +45,21 @@ function setTime(obj, jLevel, variableName, value)
     for j = 1:nArgument
         name = variableName{j};
         val = value{j};
-        % Determine type of data
+
         if isa(val, 'ValueDetails')
             % Copy type argument
             currentType = val;
             valueList = repmat({nan}, length(jLevel), 1);
         else
-            % Determine type by example data
             [valueList, currentType] = splitIntoLevelWiseData(length(jLevel), val);
         end
-        % Store type
+
+        % Store type and category
         if ~ismember(name, obj.label)
             obj.type(name) = currentType.adaptPrintWidthTo(name);
+            obj.category(name) = DataCategory.TIME;
         end
-        % Store variable as absolute variable
-        if ~ismember(name, obj.timeVariable)
-            obj.timeVariable{end+1} = name;
-        end
+
         % Store level-oriented data
         for k = 1:length(jLevel)
             obj.level(jLevel(k)).(name) = valueList{k};