Skip to content

Change exception types, improve argument checking, and cleanups in mpl_toolkits #23550

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/api/next_api_changes/behavior/23550-OG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Specified exception types in Grid
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In a few cases an `Exception` was thrown when an incorrect argument value
was set in the `mpl_toolkits.axes_grid1.axes_grid.Grid`
(= `mpl_toolkits.axisartist.axes_grid.Grid`) constructor. These are replaced
as follows:

* Providing an incorrect value for *ngrids* now raises a `ValueError`
* Providing an incorrect type for *rect* now raises a `TypeError`
41 changes: 19 additions & 22 deletions lib/mpl_toolkits/axes_grid1/axes_divider.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def __init__(self, fig, pos, horizontal, vertical,
aspect : bool
Whether overall rectangular area is reduced so that the relative
part of the horizontal and vertical scales have the same scale.
anchor : {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', 'NW', 'W'}
anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \
'NW', 'W'}
Placement of the reduced rectangle, when *aspect* is True.
"""

Expand All @@ -48,6 +49,7 @@ def __init__(self, fig, pos, horizontal, vertical,
self._horizontal = horizontal
self._vertical = vertical
self._anchor = anchor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can drop this line now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't some code quality tools complain if it is defined outside of __init__? That was the reason anyway.

self.set_anchor(anchor)
self._aspect = aspect
self._xrefindex = 0
self._yrefindex = 0
Expand Down Expand Up @@ -106,7 +108,8 @@ def set_anchor(self, anchor):
"""
Parameters
----------
anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', ...}
anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \
'NW', 'W'}
Either an (*x*, *y*) pair of relative coordinates (0 is left or
bottom, 1 is right or top), 'C' (center), or a cardinal direction
('SW', southwest, is bottom left, etc.).
Expand All @@ -115,8 +118,10 @@ def set_anchor(self, anchor):
--------
.Axes.set_anchor
"""
if len(anchor) != 2:
if isinstance(anchor, str):
_api.check_in_list(mtransforms.Bbox.coefs, anchor=anchor)
elif not isinstance(anchor, (tuple, list)) or len(anchor) != 2:
raise TypeError("anchor must be str or 2-tuple")
self._anchor = anchor

def get_anchor(self):
Expand Down Expand Up @@ -250,6 +255,8 @@ def new_locator(self, nx, ny, nx1=None, ny1=None):
ny1 if ny1 is not None else ny + 1)

def append_size(self, position, size):
_api.check_in_list(["left", "right", "bottom", "top"],
position=position)
if position == "left":
self._horizontal.insert(0, size)
self._xrefindex += 1
Expand All @@ -258,11 +265,8 @@ def append_size(self, position, size):
elif position == "bottom":
self._vertical.insert(0, size)
self._yrefindex += 1
elif position == "top":
else: # 'top'
self._vertical.append(size)
else:
_api.check_in_list(["left", "right", "bottom", "top"],
position=position)

def add_auto_adjustable_area(self, use_axes, pad=0.1, adjust_dirs=None):
"""
Expand Down Expand Up @@ -512,21 +516,14 @@ def append_axes(self, position, size, pad=None, add_to_figure=True, *,
**kwargs
All extra keywords arguments are passed to the created axes.
"""
if position == "left":
ax = self.new_horizontal(
size, pad, pack_start=True, axes_class=axes_class, **kwargs)
elif position == "right":
ax = self.new_horizontal(
size, pad, pack_start=False, axes_class=axes_class, **kwargs)
elif position == "bottom":
ax = self.new_vertical(
size, pad, pack_start=True, axes_class=axes_class, **kwargs)
elif position == "top":
ax = self.new_vertical(
size, pad, pack_start=False, axes_class=axes_class, **kwargs)
else:
_api.check_in_list(["left", "right", "bottom", "top"],
position=position)
create_axes, pack_start = _api.check_getitem({
"left": (self.new_horizontal, True),
"right": (self.new_horizontal, False),
"bottom": (self.new_vertical, True),
"top": (self.new_vertical, False),
}, position=position)
ax = create_axes(
size, pad, pack_start=pack_start, axes_class=axes_class, **kwargs)
if add_to_figure:
self._fig.add_axes(ax)
return ax
Expand Down
12 changes: 9 additions & 3 deletions lib/mpl_toolkits/axes_grid1/axes_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ def __init__(self, fig,
ngrids = self._nrows * self._ncols
else:
if not 0 < ngrids <= self._nrows * self._ncols:
raise Exception("")
raise ValueError(
"ngrids must be positive and not larger than nrows*ncols")

self.ngrids = ngrids

Expand All @@ -147,7 +148,7 @@ def __init__(self, fig,
elif len(rect) == 4:
self._divider = Divider(fig, rect, **kw)
else:
raise Exception("")
raise TypeError("Incorrect rect format")

rect = self._divider.get_position()

Expand Down Expand Up @@ -270,6 +271,7 @@ def set_label_mode(self, mode):
- "1": Only the bottom left axes is labelled.
- "all": all axes are labelled.
"""
_api.check_in_list(["all", "L", "1"], mode=mode)
if mode == "all":
for ax in self.axes_all:
_tick_only(ax, False, False)
Expand All @@ -290,7 +292,7 @@ def set_label_mode(self, mode):
ax = col[-1]
_tick_only(ax, bottom_on=False, left_on=True)

elif mode == "1":
else: # "1"
for ax in self.axes_all:
_tick_only(ax, bottom_on=True, left_on=True)

Expand Down Expand Up @@ -378,6 +380,10 @@ def __init__(self, fig,
to associated *cbar_axes*.
axes_class : subclass of `matplotlib.axes.Axes`, default: None
"""
_api.check_in_list(["each", "single", "edge", None],
cbar_mode=cbar_mode)
_api.check_in_list(["left", "right", "bottom", "top"],
cbar_location=cbar_location)
self._colorbar_mode = cbar_mode
self._colorbar_location = cbar_location
self._colorbar_pad = cbar_pad
Expand Down
2 changes: 1 addition & 1 deletion lib/mpl_toolkits/mplot3d/axes3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ def set_proj_type(self, proj_type, focal_length=None):
raise ValueError(f"focal_length = {focal_length} must be "
"greater than 0")
self._focal_length = focal_length
elif proj_type == 'ortho':
else: # 'ortho':
if focal_length not in (None, np.inf):
raise ValueError(f"focal_length = {focal_length} must be "
f"None for proj_type = {proj_type}")
Expand Down
29 changes: 26 additions & 3 deletions lib/mpl_toolkits/tests/test_axes_grid1.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from mpl_toolkits.axes_grid1.anchored_artists import (
AnchoredSizeBar, AnchoredDirectionArrows)
from mpl_toolkits.axes_grid1.axes_divider import (
HBoxDivider, make_axes_area_auto_adjustable)
Divider, HBoxDivider, make_axes_area_auto_adjustable)
from mpl_toolkits.axes_grid1.axes_rgb import RGBAxes
from mpl_toolkits.axes_grid1.inset_locator import (
zoomed_inset_axes, mark_inset, inset_axes, BboxConnectorPatch)
Expand Down Expand Up @@ -376,10 +376,9 @@ def test_image_grid():

fig = plt.figure(1, (4, 4))
grid = ImageGrid(fig, 111, nrows_ncols=(2, 2), axes_pad=0.1)

assert grid.get_axes_pad() == (0.1, 0.1)
for i in range(4):
grid[i].imshow(im, interpolation='nearest')
grid[i].set_title('test {0}{0}'.format(i))


def test_gettightbbox():
Expand Down Expand Up @@ -492,6 +491,7 @@ def test_grid_axes_lists():
assert_array_equal(grid, grid.axes_all)
assert_array_equal(grid.axes_row, np.transpose(grid.axes_column))
assert_array_equal(grid, np.ravel(grid.axes_row), "row")
assert grid.get_geometry() == (2, 3)
grid = Grid(fig, 111, (2, 3), direction="column")
assert_array_equal(grid, np.ravel(grid.axes_column), "column")

Expand All @@ -507,6 +507,29 @@ def test_grid_axes_position(direction):
assert loc[3]._nx == loc[1]._nx and loc[3]._ny == loc[2]._ny


@pytest.mark.parametrize('rect, ngrids, error, message', (
((1, 1), None, TypeError, "Incorrect rect format"),
(111, -1, ValueError, "ngrids must be positive"),
(111, 7, ValueError, "ngrids must be positive"),
))
def test_grid_errors(rect, ngrids, error, message):
fig = plt.figure()
with pytest.raises(error, match=message):
Grid(fig, rect, (2, 3), ngrids=ngrids)


@pytest.mark.parametrize('anchor, error, message', (
(None, TypeError, "anchor must be str"),
("CC", ValueError, "'CC' is not a valid value for anchor"),
((1, 1, 1), TypeError, "anchor must be str"),
))
def test_divider_errors(anchor, error, message):
fig = plt.figure()
with pytest.raises(error, match=message):
Divider(fig, [0, 0, 1, 1], [Size.Fixed(1)], [Size.Fixed(1)],
anchor=anchor)


@check_figures_equal(extensions=["png"])
def test_mark_inset_unstales_viewlim(fig_test, fig_ref):
inset, full = fig_test.subplots(1, 2)
Expand Down