1414import matplotlib .pyplot as plt
1515import torch
1616from botorch .models import SingleTaskGP
17+ from boxcrete .units import DEFAULT_UNIT_SYSTEM , PSI_TO_MPA , UnitSystem , strength_label
1718from linear_operator .utils .cholesky import psd_safe_cholesky
1819from matplotlib .ticker import MultipleLocator
1920from torch import Tensor
@@ -34,11 +35,12 @@ def plot_strength_curve(
3435 num_t : int = 1024 ,
3536 nsigma : int = 2 ,
3637 xlim : tuple [float , float ] = (0 , 28 ),
37- ylim : tuple [float , float ] = ( - 500 , 16000 ) ,
38+ ylim : tuple [float , float ] | None = None ,
3839 figsize : tuple [float , float ] = (4 , 4 ),
3940 dpi : int = 600 ,
4041 create_fig : bool = True ,
4142 colors : list [str ] | None = None ,
43+ unit_system : UnitSystem | None = None ,
4244) -> plt .Figure :
4345 """Plots predicted compressive strength curves as a function of curing time.
4446
@@ -62,16 +64,24 @@ def plot_strength_curve(
6264 num_t: Number of time points to evaluate.
6365 nsigma: Number of standard deviations for the uncertainty band.
6466 xlim: X-axis limits (days).
65- ylim: Y-axis limits (strength in psi).
67+ ylim: Y-axis limits. Defaults to (-500, 16000) for psi or
68+ (-3.5, 110) for MPa.
6669 figsize: Figure size in inches (width, height).
6770 dpi: Figure resolution.
6871 create_fig: Whether to create a new figure or plot on the current axes.
6972 colors: Optional list of colors for each composition. If None, uses
7073 matplotlib's Tableau color cycle.
74+ unit_system: Unit system for the y-axis. If None, uses
75+ ``DEFAULT_UNIT_SYSTEM``.
7176
7277 Returns:
7378 The matplotlib Figure object containing the plot.
7479 """
80+ if unit_system is None :
81+ unit_system = DEFAULT_UNIT_SYSTEM
82+ scale = PSI_TO_MPA if unit_system == UnitSystem .METRIC else 1.0
83+ if ylim is None :
84+ ylim = (- 3.5 , 110.0 ) if unit_system == UnitSystem .METRIC else (- 500 , 16000 )
7585 if compositions .dim () == 1 :
7686 compositions = compositions .unsqueeze (0 )
7787
@@ -95,20 +105,26 @@ def plot_strength_curve(
95105 curve_std = curve_post .variance .sqrt ().detach ().squeeze ()
96106
97107 color = tableau [i % len (tableau )]
98- plt .plot (plot_times , curve_mean , color = color )
108+ plt .plot (plot_times , curve_mean * scale , color = color )
99109
100110 if plot_uncertainties :
101111 plt .fill_between (
102112 plot_times ,
103- curve_mean - nsigma * curve_std ,
104- curve_mean + nsigma * curve_std ,
113+ ( curve_mean - nsigma * curve_std ) * scale ,
114+ ( curve_mean + nsigma * curve_std ) * scale ,
105115 alpha = 0.2 ,
106116 label = "Predicted" if i == 0 else None ,
107117 color = color ,
108118 )
109119
110120 if observed_data is not None and observed_times is not None :
111- plt .plot (observed_times , observed_data , "o" , label = "Observations" , c = color )
121+ plt .plot (
122+ observed_times ,
123+ observed_data * scale ,
124+ "o" ,
125+ label = "Observations" ,
126+ c = color ,
127+ )
112128 plt .legend ()
113129
114130 # Configure axes (once, after all curves are plotted)
@@ -126,9 +142,10 @@ def plot_strength_curve(
126142 plt .xlim (xlim )
127143 plt .ylim (ylim )
128144 ax .set_xlabel ("Curing Age (days)" , fontsize = 9 )
129- ax .set_ylabel ("Compressive Strength (psi)" , fontsize = 9 )
130- ax .yaxis .set_major_locator (MultipleLocator (4000 ))
131- ax .yaxis .set_minor_locator (MultipleLocator (2000 ))
145+ ax .set_ylabel (f"Compressive Strength ({ strength_label (unit_system )} )" , fontsize = 9 )
146+ major_tick = 20 if unit_system == UnitSystem .METRIC else 4000
147+ ax .yaxis .set_major_locator (MultipleLocator (major_tick ))
148+ ax .yaxis .set_minor_locator (MultipleLocator (major_tick / 2 ))
132149 for spine in ax .spines .values ():
133150 spine .set_linewidth (1 )
134151 ax .tick_params (which = "major" , width = 1 , length = 8 )
0 commit comments