Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 896fb81

Browse files
timhoffmQuLogic
andauthored
Document and test _get_packed_offsets() (#14516)
* Document and test _get_packed_offsets() * Update lib/matplotlib/offsetbox.py Co-Authored-By: Elliott Sales de Andrade <[email protected]> * Update lib/matplotlib/offsetbox.py Co-Authored-By: Elliott Sales de Andrade <[email protected]> * Update lib/matplotlib/offsetbox.py Co-Authored-By: Elliott Sales de Andrade <[email protected]> * Update lib/matplotlib/offsetbox.py Co-Authored-By: Elliott Sales de Andrade <[email protected]>
1 parent 110f297 commit 896fb81

File tree

2 files changed

+102
-7
lines changed

2 files changed

+102
-7
lines changed

lib/matplotlib/offsetbox.py

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
2-
The OffsetBox is a simple container artist. The child artist are meant
3-
to be drawn at a relative position to its parent. The [VH]Packer,
2+
The `.OffsetBox` is a simple container artist. Its child artists are
3+
meant to be drawn at a relative position to OffsetBox. The [VH]Packer,
44
DrawingArea and TextArea are derived from the OffsetBox.
55
66
The [VH]Packer automatically adjust the relative positions of their
@@ -49,12 +49,48 @@ def _get_packed_offsets(wd_list, total, sep, mode="fixed"):
4949
*mode*. xdescent is analogous to the usual descent, but along the
5050
x-direction. xdescent values are currently ignored.
5151
52-
*wd_list* : list of (width, xdescent) of boxes to be packed.
53-
*sep* : spacing between boxes
54-
*total* : Intended total length. None if not used.
55-
*mode* : packing mode. 'fixed', 'expand', or 'equal'.
52+
For simplicity of the description, the terminology used here assumes a
53+
horizontal layout, but the function works equally for a vertical layout.
54+
55+
There are three packing modes:
56+
57+
- 'fixed': The elements are packed tight to the left with a spacing of
58+
*sep* in between. If *total* is *None* the returned total will be the
59+
right edge of the last box. A non-*None* total will be passed unchecked
60+
to the output. In particular this means that right edge of the last
61+
box may be further to the right than the returned total.
62+
63+
- 'expand': Distribute the boxes with equal spacing so that the left edge
64+
of the first box is at 0, and the right edge of the last box is at
65+
*total*. The parameter *sep* is ignored in this mode. A total of *None*
66+
is accepted and considered equal to 1. The total is returned unchanged
67+
(except for the conversion *None* to 1). If the total is smaller than
68+
the sum of the widths, the laid out boxes will overlap.
69+
70+
- 'equal': If *total* is given, the total space is divided in N equal
71+
ranges and each box is left-aligned within its subspace.
72+
Otherwise (*total* is *None*), *sep* must be provided and each box is
73+
left-aligned in its subspace of width ``(max(widths) + sep)``. The
74+
total width is then calculated to be ``N * (max(widths) + sep)``.
75+
76+
Parameters
77+
----------
78+
wd_list : list of (float, float)
79+
(width, xdescent) of boxes to be packed.
80+
total : float or None
81+
Intended total length. *None* if not used.
82+
sep : float
83+
Spacing between boxes.
84+
mode : {'fixed', 'expand', 'equal'}
85+
The packing mode.
86+
87+
Returns
88+
-------
89+
total : float
90+
The total width needed to accommodate the laid out boxes.
91+
offsets : array of float
92+
The left offsets of the boxes.
5693
"""
57-
5894
w_list, d_list = zip(*wd_list)
5995
# d_list is currently not used.
6096

@@ -81,6 +117,9 @@ def _get_packed_offsets(wd_list, total, sep, mode="fixed"):
81117
elif mode == "equal":
82118
maxh = max(w_list)
83119
if total is None:
120+
if sep is None:
121+
raise ValueError("total and sep cannot both be None when "
122+
"using layout mode 'equal'.")
84123
total = (maxh + sep) * len(w_list)
85124
else:
86125
sep = total / len(w_list) - maxh

lib/matplotlib/tests/test_offsetbox.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from collections import namedtuple
2+
import numpy.testing as nptest
13
import pytest
24
from matplotlib.testing.decorators import image_comparison
35
import matplotlib.pyplot as plt
@@ -123,4 +125,58 @@ def test_get_packed_offsets(wd_list, total, sep, mode):
123125
# issue tickets (at least #10476 and #10784) related to corner cases
124126
# triggered inside this function when calling higher-level functions
125127
# (e.g. `Axes.legend`).
128+
# These are just some additional smoke tests. The output is untested.
126129
_get_packed_offsets(wd_list, total, sep, mode=mode)
130+
131+
132+
_Params = namedtuple('_params', 'wd_list, total, sep, expected')
133+
134+
135+
@pytest.mark.parametrize('wd_list, total, sep, expected', [
136+
_Params( # total=None
137+
[(3, 0), (1, 0), (2, 0)], total=None, sep=1, expected=(8, [0, 4, 6])),
138+
_Params( # total larger than required
139+
[(3, 0), (1, 0), (2, 0)], total=10, sep=1, expected=(10, [0, 4, 6])),
140+
_Params( # total smaller than required
141+
[(3, 0), (1, 0), (2, 0)], total=5, sep=1, expected=(5, [0, 4, 6])),
142+
])
143+
def test_get_packed_offsets_fixed(wd_list, total, sep, expected):
144+
result = _get_packed_offsets(wd_list, total, sep, mode='fixed')
145+
assert result[0] == expected[0]
146+
nptest.assert_allclose(result[1], expected[1])
147+
148+
149+
@pytest.mark.parametrize('wd_list, total, sep, expected', [
150+
_Params( # total=None (implicit 1)
151+
[(.1, 0)] * 3, total=None, sep=None, expected=(1, [0, .45, .9])),
152+
_Params( # total larger than sum of widths
153+
[(3, 0), (1, 0), (2, 0)], total=10, sep=1, expected=(10, [0, 5, 8])),
154+
_Params( # total smaller sum of widths: overlapping boxes
155+
[(3, 0), (1, 0), (2, 0)], total=5, sep=1, expected=(5, [0, 2.5, 3])),
156+
])
157+
def test_get_packed_offsets_expand(wd_list, total, sep, expected):
158+
result = _get_packed_offsets(wd_list, total, sep, mode='expand')
159+
assert result[0] == expected[0]
160+
nptest.assert_allclose(result[1], expected[1])
161+
162+
163+
@pytest.mark.parametrize('wd_list, total, sep, expected', [
164+
_Params( # total larger than required
165+
[(3, 0), (2, 0), (1, 0)], total=6, sep=None, expected=(6, [0, 2, 4])),
166+
_Params( # total smaller sum of widths: overlapping boxes
167+
[(3, 0), (2, 0), (1, 0), (.5, 0)], total=2, sep=None,
168+
expected=(2, [0, 0.5, 1, 1.5])),
169+
_Params( # total larger than required
170+
[(.5, 0), (1, 0), (.2, 0)], total=None, sep=1,
171+
expected=(6, [0, 2, 4])),
172+
# the case total=None, sep=None is tested separately below
173+
])
174+
def test_get_packed_offsets_equal(wd_list, total, sep, expected):
175+
result = _get_packed_offsets(wd_list, total, sep, mode='equal')
176+
assert result[0] == expected[0]
177+
nptest.assert_allclose(result[1], expected[1])
178+
179+
180+
def test_get_packed_offsets_equal_total_none_sep_none():
181+
with pytest.raises(ValueError):
182+
_get_packed_offsets([(1, 0)] * 3, total=None, sep=None, mode='equal')

0 commit comments

Comments
 (0)