diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dbafd0f0..1ae81133f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,7 +43,7 @@ Attention: The newest changes should be on top --> ### Changed - +- ENH: Display more information in MonteCarlo prints and plots [#760](https://github.com/RocketPy-Team/RocketPy/pull/760) - MNT: move piecewise functions to separate file [#746](https://github.com/RocketPy-Team/RocketPy/pull/746) - DOC: flight comparison improvements [#755](https://github.com/RocketPy-Team/RocketPy/pull/755) diff --git a/rocketpy/plots/monte_carlo_plots.py b/rocketpy/plots/monte_carlo_plots.py index 802fe7e57..e20474773 100644 --- a/rocketpy/plots/monte_carlo_plots.py +++ b/rocketpy/plots/monte_carlo_plots.py @@ -173,10 +173,25 @@ def all(self, keys=None): ) else: raise ValueError("The 'keys' argument must be a string, list, or tuple.") - for key in keys: - plt.figure() - plt.hist(self.monte_carlo.results[key]) - plt.title(f"Histogram of {key}") - plt.ylabel("Number of Occurrences") + # Create figure with GridSpec + fig = plt.figure(figsize=(8, 8)) + gs = fig.add_gridspec(2, 1, height_ratios=[1, 3]) + + # Create subplots using gridspec + ax1 = fig.add_subplot(gs[0]) + ax2 = fig.add_subplot(gs[1]) + + # Plot boxplot + ax1.boxplot(self.monte_carlo.results[key], vert=False) + ax1.set_title(f"Box Plot of {key}") + ax1.set_yticks([]) + + # Plot histogram + ax2.hist(self.monte_carlo.results[key]) + ax2.set_title(f"Histogram of {key}") + ax2.set_ylabel("Number of Occurrences") + ax1.set_xticks([]) + + plt.tight_layout() plt.show() diff --git a/rocketpy/prints/monte_carlo_prints.py b/rocketpy/prints/monte_carlo_prints.py index dc7cc1265..ad2c5c402 100644 --- a/rocketpy/prints/monte_carlo_prints.py +++ b/rocketpy/prints/monte_carlo_prints.py @@ -21,10 +21,16 @@ def all(self): print("Data Source: ", self.monte_carlo.filename) print("Number of simulations: ", self.monte_carlo.num_of_loaded_sims) print("Results: \n") - print(f"{'Parameter':>25} {'Mean':>15} {'Std. Dev.':>15}") - print("-" * 60) + print( + f"{'Parameter':>25} {'Mean':>15} {'Median':>15} {'Std. Dev.':>15} {'95% PI Lower':>15} {'95% PI Upper':>15}" + ) + print("-" * 110) for key, value in self.monte_carlo.processed_results.items(): try: - print(f"{key:>25} {value[0]:>15.3f} {value[1]:>15.3f}") + print( + f"{key:>25} {value[0]:>15.3f} {value[1]:>15.3f} {value[2]:>15.3f} {value[3]:>15.3f} {value[4]:>15.3f}" + ) except TypeError: - print(f"{key:>25} {str(value[0]):>15} {str(value[1]):>15}") + print( + f"{key:>25} {'N/A':>15} {'N/A':>15} {'N/A':>15} {'N/A':>15} {'N/A':>15}" + ) diff --git a/rocketpy/simulation/monte_carlo.py b/rocketpy/simulation/monte_carlo.py index 19c2e4f92..f92fe3f32 100644 --- a/rocketpy/simulation/monte_carlo.py +++ b/rocketpy/simulation/monte_carlo.py @@ -749,8 +749,16 @@ def set_processed_results(self): mean = np.mean(values) stdev = np.std(values) self.processed_results[result] = (mean, stdev) + pi_low = np.quantile(values, 0.025) + pi_high = np.quantile(values, 0.975) + median = np.median(values) except TypeError: - self.processed_results[result] = (None, None) + mean = None + stdev = None + pi_low = None + pi_high = None + median = None + self.processed_results[result] = (mean, median, stdev, pi_low, pi_high) # Import methods