11import math
22from itertools import product
3+ from collections import Iterable
34import warnings
45import numpy as np
56import scipy as sp
@@ -242,10 +243,10 @@ def plot_homline(lines, *args, ax=None, xlim=None, ylim=None, **kwargs):
242243
243244def plot_box (
244245 * fmt ,
245- bl = None ,
246- tl = None ,
247- br = None ,
248- tr = None ,
246+ lb = None ,
247+ lt = None ,
248+ rb = None ,
249+ rt = None ,
249250 wh = None ,
250251 centre = None ,
251252 l = None ,
@@ -256,6 +257,7 @@ def plot_box(
256257 h = None ,
257258 ax = None ,
258259 bbox = None ,
260+ ltrb = None ,
259261 filled = False ,
260262 ** kwargs
261263):
@@ -268,10 +270,10 @@ def plot_box(
268270 :type tl: [array_like(2), optional
269271 :param br: bottom-right corner, defaults to None
270272 :type br: array_like(2), optional
271- :param tr: top -ight corner, defaults to None
273+ :param tr: top-right corner, defaults to None
272274 :type tr: array_like(2), optional
273- :param wh: width and height, defaults to None
274- :type wh: array_like(2), optional
275+ :param wh: width and height, if both are the same provide scalar, defaults to None
276+ :type wh: scalar, array_like(2), optional
275277 :param centre: centre of box, defaults to None
276278 :type centre: array_like(2), optional
277279 :param l: left side of box, minimum x, defaults to None
@@ -304,35 +306,48 @@ def plot_box(
304306 The box can be specified in many ways:
305307
306308 - bounding box which is a 2x2 matrix [xmin, xmax; ymin, ymax]
309+ - bounding box [xmin, xmax, ymin, ymax]
310+ - alternative box [xmin, ymin, xmax, ymax]
307311 - centre and width+height
308312 - bottom-left and top-right corners
309313 - bottom-left corner and width+height
310314 - top-right corner and width+height
311315 - top-left corner and width+height
312316
317+ For plots where the y-axis is inverted (eg. for images) then top is the
318+ smaller vertical coordinate.
319+
313320 Example:
314321
315322 .. runblock:: pycon
316323
317324 >>> from spatialmath.base import plotvol2, plot_box
318325 >>> plotvol2(5)
319- >>> plot_box('r', centre=(2,3), wh=(1,1))
326+ >>> plot_box('r', centre=(2,3), wh=1) # w=h=1
320327 >>> plot_box(tl=(1,1), br=(0,2), filled=True, color='b')
321328 """
322329
323330 if bbox is not None :
324- l , r , b , t = bbox
331+ if isinstance (bbox , ndarray ) and bbox .ndims > 1 :
332+ # case of [l r; t b]
333+ bbox = bbox .ravel ()
334+ l , r , t , b = bbox
335+ elif ltrb is not None :
336+ l , t , r , b = ltrb
325337 else :
326- if tl is not None :
327- l , t = tl
328- if tr is not None :
329- r , t = tr
330- if bl is not None :
331- l , b = bl
332- if br is not None :
333- r , b = br
338+ if lt is not None :
339+ l , t = lt
340+ if rt is not None :
341+ r , t = rt
342+ if lb is not None :
343+ l , b = lb
344+ if rb is not None :
345+ r , b = rb
334346 if wh is not None :
335- w , h = wh
347+ if isinstance (wh , Iterable ):
348+ w , h = wh
349+ else :
350+ w = wh ; h = wh
336351 if centre is not None :
337352 cx , cy = centre
338353 if l is None :
@@ -347,17 +362,26 @@ def plot_box(
347362 pass
348363 if b is None :
349364 try :
350- b = t - h
365+ t = b + h
351366 except :
352367 pass
353368 if b is None :
354369 try :
355- b = cy + h / 2
370+ t = cy - h / 2
356371 except :
357372 pass
358373
359374 ax = axes_logic (ax , 2 )
360375
376+ if ax .yaxis_inverted ():
377+ # if y-axis is flipped, switch top and bottom
378+ t , b = b , t
379+
380+ if l >= r :
381+ raise ValueError ("left must be less than right" )
382+ if b >= t :
383+ raise ValueError ("bottom must be less than top" )
384+
361385 if filled :
362386 if w is None :
363387 try :
@@ -392,9 +416,9 @@ def plot_box(
392416 t = cy + h / 2
393417 except :
394418 pass
395- r = plt .plot ([l , l , r , r , l ], [b , t , t , b , b ], * fmt , ** kwargs )
419+ r = plt .plot ([l , l , r , r , l ], [b , t , t , b , b ], * fmt , ** kwargs )[ 0 ]
396420
397- return [ r ]
421+ return r
398422
399423def plot_poly (vertices , * fmt , close = False ,** kwargs ):
400424
0 commit comments