Repository: fitbenchmarking/fitbenchmarking

Issue:
Making plotting optional
**Is your feature request related to a problem? Please describe.**
Adds option to the options file whether or not to produce plots.

**Describe the solution you'd like**
Create new `make_plots` option in options file.

Comments:

Patch:
diff --git a/examples/options_template.ini b/examples/options_template.ini
index 050d0fae..27946dfb 100644
--- a/examples/options_template.ini
+++ b/examples/options_template.ini
@@ -106,6 +106,11 @@ use_errors: no
 ##############################################################################
 [PLOTTING]
 
+# make_plots is used to allow the user to either create plots during runtime.
+#            Toggling this False will be much faster on small data sets.
+# default True (yes/no can also be used)
+# make_plots: yes
+
 # colour_scale lists thresholds for each colour in the html table
 #              In the below example, this means that values less than 1.1 will
 #              have the top ranking (brightest) and values over 3 will show as
diff --git a/fitbenchmarking/HTML_templates/results_template.html b/fitbenchmarking/HTML_templates/results_template.html
index 3014d968..e844abe8 100644
--- a/fitbenchmarking/HTML_templates/results_template.html
+++ b/fitbenchmarking/HTML_templates/results_template.html
@@ -25,8 +25,12 @@
 </tr>
 </tbody>
 </table>
+{% if make_plots %}
 <div align="center" class="figure align-center">
 <img alt={{ initial_plot }} src={{ initial_plot }} />
+{% else %}
+<h3>{{ initial_plot }}</h3>
+{% endif %}
 </div>
 </div>
 <div class="section" id="plot-of-the-solution-found">
@@ -49,8 +53,12 @@
 </tr>
 </tbody>
 </table>
+{% if make_plots %}
 <div align="center" class="figure align-center">
 <img alt={{ fitted_plot }} src={{ fitted_plot }} />
+{% else %}
+<h3>{{ fitted_plot }}</h3>
+{% endif %}
 </div>
 </div>
 </body>
diff --git a/fitbenchmarking/results_processing/visual_pages.py b/fitbenchmarking/results_processing/visual_pages.py
index bee3ed68..dde59dd9 100644
--- a/fitbenchmarking/results_processing/visual_pages.py
+++ b/fitbenchmarking/results_processing/visual_pages.py
@@ -79,19 +79,22 @@ def create(prob_results, group_name, results_dir, count, options):
     prob_name = prob_name.replace(' ', '_')
     directory = os.path.join(results_dir, group_name)
 
-    plot = plots.Plot(problem=best_result.problem,
-                      options=options,
-                      count=count,
-                      group_results_dir=directory)
-    plot.plot_initial_guess()
-    plot.plot_best_fit(best_result.minimizer, best_result.params)
-
     support_pages_dir, file_path = \
         get_filename_and_path(group_name, prob_name,
                               best_result, results_dir, count)
-    fig_fit, fig_start = \
-        get_figure_paths(support_pages_dir, prob_name, count)
-
+    if options.make_plots:
+        plot = plots.Plot(problem=best_result.problem,
+                          options=options,
+                          count=count,
+                          group_results_dir=directory)
+        plot.plot_initial_guess()
+        plot.plot_best_fit(best_result.minimizer, best_result.params)
+
+        fig_fit, fig_start = \
+            get_figure_paths(support_pages_dir, prob_name, count)
+    else:
+        fig_fit = fig_start = "Re-run with make_plots set to yes in the " \
+                              "ini file to generate plots"
     root = os.path.dirname(os.path.abspath(__file__))
     main_dir = os.path.dirname(root)
     html_page_dir = os.path.join(main_dir, "HTML_templates")
@@ -106,6 +109,7 @@ def create(prob_results, group_name, results_dir, count, options):
             css_style_sheet=style_css,
             title=prob_name,
             equation=best_result.problem.equation,
+            make_plots=options.make_plots,
             initial_guess=best_result.ini_function_params,
             best_minimiser=best_result.minimizer,
             initial_plot=fig_start,
diff --git a/fitbenchmarking/utils/default_options.ini b/fitbenchmarking/utils/default_options.ini
index 12004776..4df7b3d2 100644
--- a/fitbenchmarking/utils/default_options.ini
+++ b/fitbenchmarking/utils/default_options.ini
@@ -110,6 +110,11 @@ use_errors: yes
 ##############################################################################
 [PLOTTING]
 
+# make_plots is used to allow the user to either create plots during runtime.
+#            Toggling this False will be much faster on small data sets.
+# default True (yes/no can also be used)
+make_plots: yes
+
 # colour_scale lists thresholds for each colour in the html table
 #              In the below example, this means that values less than 1.1 will
 #              have the top ranking (brightest) and values over 3 will show as
diff --git a/fitbenchmarking/utils/options.py b/fitbenchmarking/utils/options.py
index 8cca7218..44215347 100644
--- a/fitbenchmarking/utils/options.py
+++ b/fitbenchmarking/utils/options.py
@@ -5,6 +5,7 @@ This file will handle all interaction with the options configuration file.
 import configparser
 
 import os
+import sys
 
 
 class Options(object):
@@ -24,6 +25,9 @@ class Options(object):
         :param file_name: The options file to load
         :type file_name: str
         """
+        template = "ERROR IN OPTIONS FILE:\n" \
+                   "The option {0} must be of type {1}. \n" \
+                   "Please alter the ini file to reflect this and re-run."
         self._results_dir = ''
         config = configparser.ConfigParser(converters={'list': read_list,
                                                        'str': str})
@@ -43,6 +47,13 @@ class Options(object):
         self.use_errors = fitting.getboolean('use_errors')
 
         plotting = config['PLOTTING']
+        # sys.exit() will be addressed in future FitBenchmarking
+        # error handling issue
+        try:
+            self.make_plots = plotting.getboolean('make_plots')
+        except ValueError:
+            print(template.format('make_plots', "boolean"))
+            sys.exit()
         self.colour_scale = plotting.getlist('colour_scale')
         self.colour_scale = [(float(cs.split(',', 1)[0].strip()),
                               cs.split(',', 1)[1].strip())


Test patch:
diff --git a/fitbenchmarking/utils/tests/test_options.py b/fitbenchmarking/utils/tests/test_options.py
index 6b4077b7..d64003f3 100644
--- a/fitbenchmarking/utils/tests/test_options.py
+++ b/fitbenchmarking/utils/tests/test_options.py
@@ -31,6 +31,7 @@ class OptionsTests(unittest.TestCase):
                       bar
 
             [PLOTTING]
+            make_plots: no
             colour_scale: 17.1, b_string?
                           inf, final_string
             comparison_mode: abs
@@ -38,13 +39,18 @@ class OptionsTests(unittest.TestCase):
                         runtime
             results_dir: new_results
             """
+        incorrect_config_str = """
+            [PLOTTING]
+            make_plots: incorrect_falue
+            """
         opts = {'MINIMIZERS': {'scipy': ['nonesense',
                                          'another_fake_minimizer'],
                                'dfogn': ['test']},
                 'FITTING': {'use_errors': False,
                             'num_runs': 2,
                             'software': ['foo', 'bar']},
-                'PLOTTING': {'colour_scale': [(17.1, 'b_string?'),
+                'PLOTTING': {'make_plots': False,
+                             'colour_scale': [(17.1, 'b_string?'),
                                               (float('inf'), 'final_string')],
                              'comparison_mode': 'abs',
                              'table_type': ['acc', 'runtime'],
@@ -58,8 +64,15 @@ class OptionsTests(unittest.TestCase):
         self.options = opts
         self.options_file = opts_file
 
+        opts_file_incorrect = 'test_incorrect_options_tests_{}.txt'.format(
+            datetime.datetime.now())
+        with open(opts_file_incorrect, 'w') as f:
+            f.write(incorrect_config_str)
+        self.options_file_incorrect = opts_file_incorrect
+
     def tearDown(self):
         os.remove(self.options_file)
+        os.remove(self.options_file_incorrect)
 
     def test_from_file(self):
         options = Options(file_name=self.options_file)
@@ -81,6 +94,15 @@ class OptionsTests(unittest.TestCase):
         self.assertTrue(
             options.results_dir.endswith(plotting_opts['results_dir']))
 
+    def test_make_plots_false(self):
+        with self.assertRaises(SystemExit):
+            Options(file_name=self.options_file_incorrect)
+
+    def test_make_plots_true(self):
+        options = Options(file_name=self.options_file)
+        plotting_opts = self.options['PLOTTING']
+        self.assertEqual(plotting_opts['make_plots'], options.make_plots)
+
 
 if __name__ == '__main__':
     unittest.main()