@@ -88,6 +88,8 @@ class BasePlotOptions:
8888 axes_synchronised: If True, the axes are synchronised
8989 force_colorbar_enabled: If True, the colorbar is always enabled
9090 show_axes_tab: If True, the axes tab is shown in the parameters dialog
91+ autoscale_margin_percent: The percentage margin added when autoscaling
92+ (0.2% by default)
9193 """
9294
9395 title : str | None = None
@@ -107,6 +109,7 @@ class BasePlotOptions:
107109 axes_synchronised : bool = False
108110 force_colorbar_enabled : bool = False
109111 show_axes_tab : bool = True
112+ autoscale_margin_percent : float = 0.2
110113
111114 def __post_init__ (self ) -> None :
112115 """Check arguments"""
@@ -120,6 +123,11 @@ def __post_init__(self) -> None:
120123 # Check aspect ratio
121124 if self .aspect_ratio <= 0 :
122125 raise ValueError ("aspect_ratio must be strictly positive" )
126+ # Check autoscale margin percentage
127+ if self .autoscale_margin_percent < 0 :
128+ raise ValueError ("autoscale_margin_percent must be non-negative" )
129+ if self .autoscale_margin_percent > 50 :
130+ raise ValueError ("autoscale_margin_percent must be <= 50%" )
123131 # Show a warning if force_colorbar_enabled is True and type is "curve"
124132 if self .force_colorbar_enabled and self .type == "curve" :
125133 warnings .warn (
@@ -309,6 +317,7 @@ def __init__(
309317 self .options = options = options if options is not None else BasePlotOptions ()
310318
311319 self .__autoscale_excluded_items : list [itf .IBasePlotItem ] = []
320+ self .autoscale_margin_percent = options .autoscale_margin_percent
312321 self .lock_aspect_ratio = options .lock_aspect_ratio
313322 self .__autoLockAspectRatio = False
314323 if self .lock_aspect_ratio is None :
@@ -1105,6 +1114,32 @@ def set_scales(self, xscale: str, yscale: str) -> None:
11051114 self .set_axis_scale (ay , yscale )
11061115 self .replot ()
11071116
1117+ def get_autoscale_margin_percent (self ) -> float :
1118+ """Get autoscale margin percentage
1119+
1120+ Returns:
1121+ float: the autoscale margin percentage
1122+ """
1123+ return self .autoscale_margin_percent
1124+
1125+ def set_autoscale_margin_percent (self , margin_percent : float ) -> None :
1126+ """Set autoscale margin percentage
1127+
1128+ Args:
1129+ margin_percent (float): the autoscale margin percentage (0-50)
1130+
1131+ Raises:
1132+ ValueError: if margin_percent is not in valid range
1133+ """
1134+ if margin_percent < 0 :
1135+ raise ValueError ("autoscale_margin_percent must be non-negative" )
1136+ if margin_percent > 50 :
1137+ raise ValueError ("autoscale_margin_percent must be <= 50%" )
1138+
1139+ self .autoscale_margin_percent = margin_percent
1140+ # Trigger an autoscale to apply the new margin immediately
1141+ self .do_autoscale (replot = True )
1142+
11081143 def enable_used_axes (self ):
11091144 """
11101145 Enable only used axes
@@ -2037,12 +2072,14 @@ def do_autoscale(self, replot: bool = True, axis_id: int | None = None) -> None:
20372072 vmax += 1
20382073 elif self .get_axis_scale (axis_id ) == "lin" :
20392074 dv = vmax - vmin
2040- vmin -= 0.002 * dv
2041- vmax += 0.002 * dv
2075+ margin = self .autoscale_margin_percent / 100.0
2076+ vmin -= margin * dv
2077+ vmax += margin * dv
20422078 elif vmin > 0 and vmax > 0 : # log scale
20432079 dv = np .log10 (vmax ) - np .log10 (vmin )
2044- vmin = 10 ** (np .log10 (vmin ) - 0.002 * dv )
2045- vmax = 10 ** (np .log10 (vmax ) + 0.002 * dv )
2080+ margin = self .autoscale_margin_percent / 100.0
2081+ vmin = 10 ** (np .log10 (vmin ) - margin * dv )
2082+ vmax = 10 ** (np .log10 (vmax ) + margin * dv )
20462083 self .set_axis_limits (axis_id , vmin , vmax )
20472084 self .setAutoReplot (auto )
20482085 self .updateAxes ()
0 commit comments