@@ -207,18 +207,34 @@ def is_relative(self) -> bool:
207207 return False
208208
209209 def _nrows (self , dy : float ) -> int :
210- total_height = abs (self .top - self .bottom ) + dy
211- return math .ceil (total_height / dy )
210+ if self .fov_height is None :
211+ total_height = abs (self .top - self .bottom ) + dy
212+ return math .ceil (total_height / dy )
213+
214+ span = abs (self .top - self .bottom )
215+ # if the span is smaller than one FOV, just one row
216+ if span <= self .fov_height :
217+ return 1
218+ # otherwise: one FOV plus (nrows-1)⋅dy must cover span
219+ return math .ceil ((span - self .fov_height ) / dy ) + 1
212220
213221 def _ncolumns (self , dx : float ) -> int :
214- total_width = abs (self .right - self .left ) + dx
215- return math .ceil (total_width / dx )
222+ if self .fov_width is None :
223+ total_width = abs (self .right - self .left ) + dx
224+ return math .ceil (total_width / dx )
225+
226+ span = abs (self .right - self .left )
227+ if span <= self .fov_width :
228+ return 1
229+ return math .ceil ((span - self .fov_width ) / dx ) + 1
216230
217231 def _offset_x (self , dx : float ) -> float :
218- return min (self .left , self .right )
232+ # start the _centre_ half a FOV in from the left edge
233+ return min (self .left , self .right ) + (self .fov_width or 0 ) / 2
219234
220235 def _offset_y (self , dy : float ) -> float :
221- return max (self .top , self .bottom )
236+ # start the _centre_ half a FOV down from the top edge
237+ return max (self .top , self .bottom ) - (self .fov_height or 0 ) / 2
222238
223239 def plot (self , * , show : bool = True ) -> Axes :
224240 """Plot the positions in the plan."""
0 commit comments