Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Document and test _get_packed_offsets()#14516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
67af4a6
30f5d9a
6a96ad9
a4f7ef5
09230d7
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,6 @@ | ||||||
""" | ||||||
The`.OffsetBox` is a simple container artist.Its childartists are | ||||||
meantto be drawn at a relative position toOffsetBox. The [VH]Packer, | ||||||
DrawingArea and TextArea are derived from the OffsetBox. | ||||||
The [VH]Packer automatically adjust the relative positions of their | ||||||
@@ -49,12 +49,48 @@ def _get_packed_offsets(wd_list, total, sep, mode="fixed"): | ||||||
*mode*. xdescent is analogous to the usual descent, but along the | ||||||
x-direction. xdescent values are currently ignored. | ||||||
For simplicity of the description, the terminology used here assumes a | ||||||
horizontal layout, but the function works equally for a vertical layout. | ||||||
There are three packing modes: | ||||||
- 'fixed': The elements are packed tight to the left with a spacing of | ||||||
*sep* in between. If *total* is *None* the returned total will be the | ||||||
right edge of the last box. A non-*None* total will be passed unchecked | ||||||
to the output. In particular this means that right edge of the last | ||||||
box may be further to the right than the returned total. | ||||||
- 'expand': Distribute the boxes with equal spacing so that the left edge | ||||||
of the first box is at 0, and the right edge of the last box is at | ||||||
*total*. The parameter *sep* is ignored in this mode. A total of *None* | ||||||
is accepted and considered equal to 1. The total is returned unchanged | ||||||
(except for the conversion *None* to 1). If the total is smaller than | ||||||
the sum of the widths, the laid out boxes will overlap. | ||||||
- 'equal': If *total* is given, the total space is divided in N equal | ||||||
ranges and each box is left-aligned within its subspace. | ||||||
Otherwise (*total* is *None*), *sep* must be provided and each box is | ||||||
left-aligned in its subspace of width ``(max(widths) + sep)``. The | ||||||
total width is then calculated to be ``N * (max(widths) + sep)``. | ||||||
Parameters | ||||||
---------- | ||||||
wd_list : list of (float, float) | ||||||
(width, xdescent) of boxes to be packed. | ||||||
total : float or None | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Generally, I don't think we style parameter types. | ||||||
Intended total length. *None* if not used. | ||||||
sep : float | ||||||
Spacing between boxes. | ||||||
mode : {'fixed', 'expand', 'equal'} | ||||||
The packing mode. | ||||||
Returns | ||||||
------- | ||||||
total : float | ||||||
The total width needed to accommodate the laid out boxes. | ||||||
offsets : array of float | ||||||
The left offsets of the boxes. | ||||||
""" | ||||||
w_list, d_list = zip(*wd_list) | ||||||
# d_list is currently not used. | ||||||
@@ -81,6 +117,9 @@ def _get_packed_offsets(wd_list, total, sep, mode="fixed"): | ||||||
elif mode == "equal": | ||||||
maxh = max(w_list) | ||||||
if total is None: | ||||||
if sep is None: | ||||||
raise ValueError("total and sep cannot both be None when " | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. This raised a TypeError before in the line below (int + None). Since the function is private, we can do the change without announcement. | ||||||
"using layout mode 'equal'.") | ||||||
total = (maxh + sep) * len(w_list) | ||||||
else: | ||||||
sep = total / len(w_list) - maxh | ||||||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
from collections import namedtuple | ||
import numpy.testing as nptest | ||
import pytest | ||
from matplotlib.testing.decorators import image_comparison | ||
import matplotlib.pyplot as plt | ||
@@ -123,4 +125,58 @@ def test_get_packed_offsets(wd_list, total, sep, mode): | ||
# issue tickets (at least #10476 and #10784) related to corner cases | ||
# triggered inside this function when calling higher-level functions | ||
# (e.g. `Axes.legend`). | ||
# These are just some additional smoke tests. The output is untested. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. It looks like this test could just be deleted as it is essentially covered by the tests below? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Not exactly, e.g. I do not test negative Since it is not documented whatshould happen in this cases, I've left this as is (unresolved). IMHO that discussion is worth some thought and a separate PR. | ||
_get_packed_offsets(wd_list, total, sep, mode=mode) | ||
_Params = namedtuple('_params', 'wd_list, total, sep, expected') | ||
@pytest.mark.parametrize('wd_list, total, sep, expected', [ | ||
_Params( # total=None | ||
[(3, 0), (1, 0), (2, 0)], total=None, sep=1, expected=(8, [0, 4, 6])), | ||
_Params( # total larger than required | ||
[(3, 0), (1, 0), (2, 0)], total=10, sep=1, expected=(10, [0, 4, 6])), | ||
_Params( # total smaller than required | ||
[(3, 0), (1, 0), (2, 0)], total=5, sep=1, expected=(5, [0, 4, 6])), | ||
]) | ||
def test_get_packed_offsets_fixed(wd_list, total, sep, expected): | ||
result = _get_packed_offsets(wd_list, total, sep, mode='fixed') | ||
assert result[0] == expected[0] | ||
nptest.assert_allclose(result[1], expected[1]) | ||
@pytest.mark.parametrize('wd_list, total, sep, expected', [ | ||
_Params( # total=None (implicit 1) | ||
[(.1, 0)] * 3, total=None, sep=None, expected=(1, [0, .45, .9])), | ||
_Params( # total larger than sum of widths | ||
[(3, 0), (1, 0), (2, 0)], total=10, sep=1, expected=(10, [0, 5, 8])), | ||
_Params( # total smaller sum of widths: overlapping boxes | ||
[(3, 0), (1, 0), (2, 0)], total=5, sep=1, expected=(5, [0, 2.5, 3])), | ||
]) | ||
def test_get_packed_offsets_expand(wd_list, total, sep, expected): | ||
result = _get_packed_offsets(wd_list, total, sep, mode='expand') | ||
assert result[0] == expected[0] | ||
nptest.assert_allclose(result[1], expected[1]) | ||
@pytest.mark.parametrize('wd_list, total, sep, expected', [ | ||
_Params( # total larger than required | ||
[(3, 0), (2, 0), (1, 0)], total=6, sep=None, expected=(6, [0, 2, 4])), | ||
_Params( # total smaller sum of widths: overlapping boxes | ||
[(3, 0), (2, 0), (1, 0), (.5, 0)], total=2, sep=None, | ||
expected=(2, [0, 0.5, 1, 1.5])), | ||
_Params( # total larger than required | ||
[(.5, 0), (1, 0), (.2, 0)], total=None, sep=1, | ||
expected=(6, [0, 2, 4])), | ||
# the case total=None, sep=None is tested separately below | ||
]) | ||
def test_get_packed_offsets_equal(wd_list, total, sep, expected): | ||
result = _get_packed_offsets(wd_list, total, sep, mode='equal') | ||
assert result[0] == expected[0] | ||
nptest.assert_allclose(result[1], expected[1]) | ||
def test_get_packed_offsets_equal_total_none_sep_none(): | ||
with pytest.raises(ValueError): | ||
_get_packed_offsets([(1, 0)] * 3, total=None, sep=None, mode='equal') |