@@ -275,6 +275,76 @@ def title_inside(
275275 )
276276
277277
278+ def _get_axes_aspect_ratio (ax ):
279+ pos = ax .get_position ()
280+ width = pos .width * ax .figure .get_figwidth ()
281+ height = pos .height * ax .figure .get_figheight ()
282+ return width / height
283+
284+
285+ def get_inset_map_bounds (
286+ ax : plt .Axes ,
287+ extent : Union [tuple [float ], list [float ]],
288+ height : Optional [float ] = None ,
289+ width : Optional [float ] = None ,
290+ margin : Optional [float ] = 0.025 ,
291+ right : Optional [bool ] = True ,
292+ bottom : Optional [bool ] = True ,
293+ ):
294+ """Get the bounds of the inset_map from a width or height, and a margin.
295+
296+ These bounds can be used for the parameter `axes_bounds` in the `inset_map` method.
297+ The horizontal and vertical margin (in pixels) around this map are equal (unless the
298+ figure is reshaped).
299+
300+ Parameters
301+ ----------
302+ ax : matplotlib.Axes
303+ The axes to add the inset map to.
304+ extent : list of 4 floats
305+ The extent of the inset map.
306+ height : float, optional
307+ The height of the inset axes, in axes coordinates. Either height or width needs
308+ to be specified. The default is None.
309+ width : float, optional
310+ The width of the inset axes, in axes coordinates. Either height or width needs
311+ to be specified. The default is None.
312+ margin : float, optional
313+ The margin around, in axes coordinates. When height is specified, margin is
314+ relative to the height of ax. When width is specified, margin is relative to the
315+ width of ax. The default is 0.025.
316+ right : bool, optional
317+ If True, the inset axes is placed at the right corner. The default is True.
318+ bottom : bool, optional
319+ If True, the inset axes is placed at the bottom corner. The default is True.
320+
321+ Returns
322+ -------
323+ bounds: list of 4 floats
324+ The bounds (left, right, width, height) of the inset axes.
325+
326+ """
327+ msg = "Please specify either height or width"
328+ assert (height is None ) + (width is None ) == 1 , msg
329+ ar = _get_axes_aspect_ratio (ax )
330+ dxdy = (extent [1 ] - extent [0 ]) / (extent [3 ] - extent [2 ])
331+ if height is None :
332+ # the bounds are determined by width
333+ height = width * ar / dxdy
334+ bounds = [margin , margin * ar , width , height ]
335+ else :
336+ # the bounds are determined by height
337+ width = height * dxdy / ar
338+ bounds = [margin / ar , margin , width , height ]
339+ if right :
340+ # put the axes on the right side
341+ bounds [0 ] = 1 - bounds [0 ] - width
342+ if not bottom :
343+ # put the axes on the top side
344+ bounds [1 ] = 1 - bounds [1 ] - height
345+ return bounds
346+
347+
278348def inset_map (
279349 ax : plt .Axes ,
280350 extent : Union [tuple [float ], list [float ]],
@@ -291,9 +361,9 @@ def inset_map(
291361 The axes to add the inset map to.
292362 extent : list of 4 floats
293363 The extent of the inset map.
294- axes_bounds : list of 4 floats, optional
295- The bounds (left, right, width height) of the inset axes, default
296- is [ 0.63, 0.025, 0.35, 0.35] . This is rescaled according to the extent of
364+ axes_bounds : list or tuple of 4 floats, optional
365+ The bounds (left, right, width, height) of the inset axes, default
366+ is ( 0.63, 0.025, 0.35, 0.35) . This is rescaled according to the extent of
297367 the inset map.
298368 anchor : str, optional
299369 The anchor point of the inset map, default is 'SE'.
0 commit comments