From 1b49b50d1743a40da7b6bce0b401437a528b159d Mon Sep 17 00:00:00 2001 From: robjmcgibbon Date: Tue, 6 Feb 2024 11:35:36 +0100 Subject: [PATCH 1/5] Add interactive_plot method to emulator class --- swiftemulator/emulators/base.py | 49 +++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/swiftemulator/emulators/base.py b/swiftemulator/emulators/base.py index df2cbbc..e15ea40 100644 --- a/swiftemulator/emulators/base.py +++ b/swiftemulator/emulators/base.py @@ -123,3 +123,52 @@ def predict_values( ) raise NotImplementedError + + def interactive_plot(self, x: np.array, xlabel: str = '', ylabel: str = ''): + """ + Generates an interactive plot over which shows the emulator predictions + for the input data passed to this method + """ + import matplotlib.pyplot as plt + from matplotlib.widgets import Slider + fig, ax = plt.subplots() + model_specification = self.model_specification + param_means = {} + sliders = [] + n_param = model_specification.number_of_parameters + fig.subplots_adjust(bottom=0.12+n_param*0.1) + for i in range(n_param): + # Extracting information needed for slider + name = model_specification.parameter_names[i] + lo_lim = sorted(model_specification.parameter_limits[i])[0] + hi_lim = sorted(model_specification.parameter_limits[i])[1] + param_means[name] = (lo_lim + hi_lim)/2 + + # Adding slider + if model_specification.parameter_printable_names: + name = model_specification.parameter_printable_names[i] + slider_ax = fig.add_axes([0.35, i*0.1, 0.3, 0.1]) + slider = Slider(ax=slider_ax, label=name, + valmin=lo_lim, valmax=hi_lim, + valinit=(lo_lim + hi_lim)/2) + sliders.append(slider) + + # Setting up initial value + pred, pred_var = self.predict_values(x, param_means) + line, = ax.plot(x, pred) + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) + + # Define and enable update function + def update(val): + params = { + model_specification.parameter_names[i]: sliders[i].val + for i in range(n_param) + } + pred, pred_var = self.predict_values(x, params) + line.set_ydata(pred) + for slider in sliders: + slider.on_changed(update) + + plt.show() + plt.close() From 89c67f19e09d0785ad19eae89558237a5f277974 Mon Sep 17 00:00:00 2001 From: robjmcgibbon Date: Tue, 6 Feb 2024 11:53:38 +0100 Subject: [PATCH 2/5] Run formatter --- swiftemulator/emulators/base.py | 22 ++++++++++++------- .../emulators/multi_gaussian_process.py | 16 +++++++++----- swiftemulator/io/swift.py | 4 ++-- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/swiftemulator/emulators/base.py b/swiftemulator/emulators/base.py index e15ea40..09ccab9 100644 --- a/swiftemulator/emulators/base.py +++ b/swiftemulator/emulators/base.py @@ -124,38 +124,43 @@ def predict_values( raise NotImplementedError - def interactive_plot(self, x: np.array, xlabel: str = '', ylabel: str = ''): + def interactive_plot(self, x: np.array, xlabel: str = "", ylabel: str = ""): """ Generates an interactive plot over which shows the emulator predictions for the input data passed to this method """ import matplotlib.pyplot as plt from matplotlib.widgets import Slider + fig, ax = plt.subplots() model_specification = self.model_specification param_means = {} sliders = [] n_param = model_specification.number_of_parameters - fig.subplots_adjust(bottom=0.12+n_param*0.1) + fig.subplots_adjust(bottom=0.12 + n_param * 0.1) for i in range(n_param): # Extracting information needed for slider name = model_specification.parameter_names[i] lo_lim = sorted(model_specification.parameter_limits[i])[0] hi_lim = sorted(model_specification.parameter_limits[i])[1] - param_means[name] = (lo_lim + hi_lim)/2 + param_means[name] = (lo_lim + hi_lim) / 2 # Adding slider if model_specification.parameter_printable_names: name = model_specification.parameter_printable_names[i] - slider_ax = fig.add_axes([0.35, i*0.1, 0.3, 0.1]) - slider = Slider(ax=slider_ax, label=name, - valmin=lo_lim, valmax=hi_lim, - valinit=(lo_lim + hi_lim)/2) + slider_ax = fig.add_axes([0.35, i * 0.1, 0.3, 0.1]) + slider = Slider( + ax=slider_ax, + label=name, + valmin=lo_lim, + valmax=hi_lim, + valinit=(lo_lim + hi_lim) / 2, + ) sliders.append(slider) # Setting up initial value pred, pred_var = self.predict_values(x, param_means) - line, = ax.plot(x, pred) + (line,) = ax.plot(x, pred) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) @@ -167,6 +172,7 @@ def update(val): } pred, pred_var = self.predict_values(x, params) line.set_ydata(pred) + for slider in sliders: slider.on_changed(update) diff --git a/swiftemulator/emulators/multi_gaussian_process.py b/swiftemulator/emulators/multi_gaussian_process.py index 2b5f45e..3802a4f 100644 --- a/swiftemulator/emulators/multi_gaussian_process.py +++ b/swiftemulator/emulators/multi_gaussian_process.py @@ -231,12 +231,16 @@ def predict_values( for index, (low, high) in enumerate(self.independent_regions): mask = np.logical_and( - independent > low - if low is not None - else np.ones_like(independent).astype(bool), - independent < high - if high is not None - else np.ones_like(independent).astype(bool), + ( + independent > low + if low is not None + else np.ones_like(independent).astype(bool) + ), + ( + independent < high + if high is not None + else np.ones_like(independent).astype(bool) + ), ) predicted, errors = self.emulators[index].predict_values( diff --git a/swiftemulator/io/swift.py b/swiftemulator/io/swift.py index e9b3247..8429525 100644 --- a/swiftemulator/io/swift.py +++ b/swiftemulator/io/swift.py @@ -103,8 +103,8 @@ def load_pipeline_outputs( "adaptive_mass_function", "histogram", ] - recursive_search = ( - lambda d, k: d.get(k[0], recursive_search(d, k[1:])) if len(k) > 0 else None + recursive_search = lambda d, k: ( + d.get(k[0], recursive_search(d, k[1:])) if len(k) > 0 else None ) line_search = lambda d: recursive_search(d, line_types) From fc057658928f1a4238fe1b9a727615b0843215fb Mon Sep 17 00:00:00 2001 From: robjmcgibbon Date: Tue, 6 Feb 2024 15:10:36 +0100 Subject: [PATCH 3/5] Add reference data --- swiftemulator/emulators/base.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/swiftemulator/emulators/base.py b/swiftemulator/emulators/base.py index 09ccab9..1fcadaf 100644 --- a/swiftemulator/emulators/base.py +++ b/swiftemulator/emulators/base.py @@ -124,7 +124,7 @@ def predict_values( raise NotImplementedError - def interactive_plot(self, x: np.array, xlabel: str = "", ylabel: str = ""): + def interactive_plot(self, x: np.array, xlabel: str = "", ylabel: str = "", x_data: np.array = None, y_data: np.array = None): """ Generates an interactive plot over which shows the emulator predictions for the input data passed to this method @@ -160,6 +160,10 @@ def interactive_plot(self, x: np.array, xlabel: str = "", ylabel: str = ""): # Setting up initial value pred, pred_var = self.predict_values(x, param_means) + if (x_data is None) or (y_data is None): + ax.plot(x, pred, 'k--') + else: + ax.plot(x_data, y_data, 'k.') (line,) = ax.plot(x, pred) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) From f42aba2bfa9e2ef4aac7d5a7efe887e9d22a9f58 Mon Sep 17 00:00:00 2001 From: robjmcgibbon Date: Tue, 6 Feb 2024 16:09:27 +0100 Subject: [PATCH 4/5] Add documentation --- docs/source/emulator_analysis/index.rst | 21 ++++++++- .../emulator_analysis/interactive_plot.png | Bin 0 -> 31340 bytes swiftemulator/emulators/base.py | 44 ++++++++++++++---- 3 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 docs/source/emulator_analysis/interactive_plot.png diff --git a/docs/source/emulator_analysis/index.rst b/docs/source/emulator_analysis/index.rst index 0c36324..492a526 100644 --- a/docs/source/emulator_analysis/index.rst +++ b/docs/source/emulator_analysis/index.rst @@ -153,6 +153,25 @@ This is implemented into the SWIFT-Emulator with sweep as `ModelValues` and `ModelParameters` containers, that are easy to parse. +Interactive plots +----------------- + +Another way to explore the effect of varying the parameters is +to try an interactive plot. Every emulator object contains an +`interactive_plot` method. This generates a plot with a slider +for each parameter. The plot will update to show the emulator +predictions when sliders are adjusted. + +.. code-block:: python + + schecter_emulator.interactive_plot(predict_x, xlabel="Stellar mass", ylabel="dn/dlogM") + +.. image:: interactive_plot.png + +It is possible to pass reference data to be plotted when calling +:meth:`swiftemulator.emulators.base.BaseEmulator.interactive\_plot`. + + Model Parameters Features ------------------------- @@ -234,4 +253,4 @@ This method is a lot slower than the default hyperparameter optimisation, and may take some time to compute. The main take away from plots like this is to see whether the hyperparameters are converged, and whether they are -consistent with the faster optimisation method. \ No newline at end of file +consistent with the faster optimisation method. diff --git a/docs/source/emulator_analysis/interactive_plot.png b/docs/source/emulator_analysis/interactive_plot.png new file mode 100644 index 0000000000000000000000000000000000000000..0fc8ea53c1a3fb0169ee8161e35b0e5db34d6728 GIT binary patch literal 31340 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 Rd0ez)hWT8xlP1gj{{!&DVr&2a literal 0 HcmV?d00001 diff --git a/swiftemulator/emulators/base.py b/swiftemulator/emulators/base.py index 1fcadaf..298d9b2 100644 --- a/swiftemulator/emulators/base.py +++ b/swiftemulator/emulators/base.py @@ -85,7 +85,7 @@ def predict_values( Parameters ---------- - independent, np.array + independent: np.array Independent continuous variables to evaluate the emulator at. If the emulator is discrete, these are only allowed to be the discrete independent variables that the emulator was trained at @@ -98,12 +98,12 @@ def predict_values( Returns ------- - dependent_predictions, np.array + dependent_predictions: np.array Array of predictions, if the emulator is a function f, these are the predicted values of f(independent) evaluted at the position of the input ``model_parameters``. - dependent_prediction_errors, np.array + dependent_prediction_errors: np.array Errors on the model predictions. For models where the errors are unconstrained, this is an array of zeroes. @@ -124,10 +124,38 @@ def predict_values( raise NotImplementedError - def interactive_plot(self, x: np.array, xlabel: str = "", ylabel: str = "", x_data: np.array = None, y_data: np.array = None): + def interactive_plot( + self, + x: np.array, + xlabel: str = "", + ylabel: str = "", + x_data: np.array = None, + y_data: np.array = None, + ): """ - Generates an interactive plot over which shows the emulator predictions - for the input data passed to this method + Generates an interactive plot which displays the emulator predictions. + If no reference data is passed to be overplotted then the plot will + display a line which corresponds to the predictions for the mean + of the parameter values. + + Parameters + ---------- + + x: np.array + Array of data for which the emulator should make predictions. + + xlabel: str, optional + Label for horizontal axis on the resultant figure. + + ylabel: str, optional + Label for vertical axis on the resultant figure. + + x_data: np.array, optional + Array containing x-values of reference data to plot. + + y_data: np.array, optional + Array containing y-values of reference data to plot. + Must be the same shape as x_data """ import matplotlib.pyplot as plt from matplotlib.widgets import Slider @@ -161,9 +189,9 @@ def interactive_plot(self, x: np.array, xlabel: str = "", ylabel: str = "", x_da # Setting up initial value pred, pred_var = self.predict_values(x, param_means) if (x_data is None) or (y_data is None): - ax.plot(x, pred, 'k--') + ax.plot(x, pred, "k--") else: - ax.plot(x_data, y_data, 'k.') + ax.plot(x_data, y_data, "k.") (line,) = ax.plot(x, pred) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) From 3dce39ed726f6e6b4ba34ffa5e98e7979feac5d8 Mon Sep 17 00:00:00 2001 From: robjmcgibbon Date: Wed, 7 Feb 2024 12:27:19 +0100 Subject: [PATCH 5/5] Add initial_params argument --- docs/source/emulator_analysis/index.rst | 16 ++++++---- .../emulator_analysis/interactive_plot.png | Bin 31340 -> 25396 bytes swiftemulator/emulators/base.py | 28 +++++++++++------- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/docs/source/emulator_analysis/index.rst b/docs/source/emulator_analysis/index.rst index 492a526..a93e7b4 100644 --- a/docs/source/emulator_analysis/index.rst +++ b/docs/source/emulator_analysis/index.rst @@ -160,17 +160,23 @@ Another way to explore the effect of varying the parameters is to try an interactive plot. Every emulator object contains an `interactive_plot` method. This generates a plot with a slider for each parameter. The plot will update to show the emulator -predictions when sliders are adjusted. +predictions when sliders are adjusted. The emulator will make +its initial prediction using the parameter values passed to it. +If no parameters are passed if will default to the midpoint of +each parameter range. It is also possible to pass reference data +to overplot on the emulator predictions. If no reference data is +passed the plot will display a fixed dashed line corresponding to +the prediction using the initial parameter values. .. code-block:: python - schecter_emulator.interactive_plot(predict_x, xlabel="Stellar mass", ylabel="dn/dlogM") + schecter_emulator.interactive_plot(predict_x, initial_params=center, + xlabel="Stellar mass", ylabel="dn/dlogM", + x_data=[10.5, 11, 11.5], + y_data=[-10, -11, -12]) .. image:: interactive_plot.png -It is possible to pass reference data to be plotted when calling -:meth:`swiftemulator.emulators.base.BaseEmulator.interactive\_plot`. - Model Parameters Features ------------------------- diff --git a/docs/source/emulator_analysis/interactive_plot.png b/docs/source/emulator_analysis/interactive_plot.png index 0fc8ea53c1a3fb0169ee8161e35b0e5db34d6728..5e20c48e3127f43f23c53924babcb70907a74cfa 100644 GIT binary patch literal 25396 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 I=qb@G0F@U%u1#WB<=bP`0B1|5RwB_F3L^0sA4| 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 literal 31340 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 Rd0ez)hWT8xlP1gj{{!&DVr&2a diff --git a/swiftemulator/emulators/base.py b/swiftemulator/emulators/base.py index 298d9b2..276f242 100644 --- a/swiftemulator/emulators/base.py +++ b/swiftemulator/emulators/base.py @@ -127,6 +127,7 @@ def predict_values( def interactive_plot( self, x: np.array, + initial_params: Dict[str, float] = {}, xlabel: str = "", ylabel: str = "", x_data: np.array = None, @@ -134,9 +135,11 @@ def interactive_plot( ): """ Generates an interactive plot which displays the emulator predictions. - If no reference data is passed to be overplotted then the plot will - display a line which corresponds to the predictions for the mean - of the parameter values. + If initial_params should contain the initial parameter values to make a + prediction for. If initial_params is not passed the midpoint of each of + the parameter values will be used instead. If no reference data is + passed to be overplotted then the plot will display a line which + corresponds to the predictions for the initial parameter values. Parameters ---------- @@ -144,6 +147,10 @@ def interactive_plot( x: np.array Array of data for which the emulator should make predictions. + initial_params: Dict[str, float], optional + What parameters values to plot the predicition for initally. + If missing the midpoint of each parameter range will be used. + xlabel: str, optional Label for horizontal axis on the resultant figure. @@ -162,7 +169,6 @@ def interactive_plot( fig, ax = plt.subplots() model_specification = self.model_specification - param_means = {} sliders = [] n_param = model_specification.number_of_parameters fig.subplots_adjust(bottom=0.12 + n_param * 0.1) @@ -171,23 +177,25 @@ def interactive_plot( name = model_specification.parameter_names[i] lo_lim = sorted(model_specification.parameter_limits[i])[0] hi_lim = sorted(model_specification.parameter_limits[i])[1] - param_means[name] = (lo_lim + hi_lim) / 2 + if not name in initial_params: + initial_params[name] = (lo_lim + hi_lim) / 2 # Adding slider + printable_name = name if model_specification.parameter_printable_names: - name = model_specification.parameter_printable_names[i] + printable_name = model_specification.parameter_printable_names[i] slider_ax = fig.add_axes([0.35, i * 0.1, 0.3, 0.1]) slider = Slider( ax=slider_ax, - label=name, + label=printable_name, valmin=lo_lim, valmax=hi_lim, - valinit=(lo_lim + hi_lim) / 2, + valinit=initial_params[name], ) sliders.append(slider) - # Setting up initial value - pred, pred_var = self.predict_values(x, param_means) + # Plotting lines and reference data + pred, pred_var = self.predict_values(x, initial_params) if (x_data is None) or (y_data is None): ax.plot(x, pred, "k--") else: