8000 Merge pull request #3167 from tacaswell/subplot_index_fix · matplotlib/matplotlib@5f5599b · GitHub
[go: up one dir, main page]

Skip to content

Commit 5f5599b

Browse files
committed
Merge pull request #3167 from tacaswell/subplot_index_fix
BUG : raise exception in subplot if num out of range
2 parents 522bfcf + a0c7728 commit 5f5599b

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

doc/api/api_changes.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,21 @@ original location:
189189
If `fontpropreties` is not passed in, but `prop` is, then `prop` is used inplace
190190
of `fontpropreties`. If both are passed in, `prop` is silently ignored.
191191

192+
193+
* The use of the index 0 in `plt.subplot` and related commands is
194+
deprecated. Due to a lack of validation calling `plt.subplots(2, 2,
195+
0)` does not raise an exception, but puts an axes in the _last_
196+
position. This is due to the indexing in subplot being 1-based (to
197+
mirror MATLAB) so before indexing into the `GridSpec` object used to
198+
determine where the axes should go, 1 is subtracted off. Passing in
199+
0 results in passing -1 to `GridSpec` which results in getting the
200+
last position back. Even though this behavior is clearly wrong and
201+
not intended, we are going through a deprecation cycle in an
202+
abundance of caution that any users are exploiting this 'feature'.
203+
The use of 0 as an index will raise a warning in 1.4 and an
204+
exception in 1.5.
205+
206+
192207
Code removal
193208
------------
194209

lib/matplotlib/axes/_subplots.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import matplotlib.artist as martist
1010
from matplotlib.axes._axes import Axes
1111

12+
import warnings
13+
from matplotlib.cbook import mplDeprecation
14+
1215

1316
class SubplotBase(object):
1417
"""
@@ -55,6 +58,15 @@ def __init__(self, fig, *args, **kwargs):
5558
num = [int(n) for n in num]
5659
self._subplotspec = GridSpec(rows, cols)[num[0] - 1:num[1]]
5760
else:
61+
if num < 0 or num > rows*cols:
62+
raise ValueError(
63+
"num must be 0 <= num <= {maxn}, not {num}".format(
64+
maxn=rows*cols, num=num))
65+
if num == 0:
66+
warnings.warn("The use of 0 (which ends up being the "
67+
"_last_ sub-plot) is deprecated in 1.4 "
68+
"and will raise an error in 1.5",
69+
mplDeprecation)
5870
self._subplotspec = GridSpec(rows, cols)[int(num) - 1]
5971
# num - 1 for converting from MATLAB to python indexing
6072
else:

lib/matplotlib/tests/test_subplots.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import numpy
88
import matplotlib.pyplot as plt
9-
from matplotlib.testing.decorators import image_comparison
9+
from matplotlib.testing.decorators import image_comparison, cleanup
1010

1111
from nose.tools import assert_raises
1212

@@ -105,19 +105,24 @@ def test_exceptions():
105105
# TODO should this test more options?
106106
assert_raises(ValueError, plt.subplots, 2, 2, sharex='blah')
107107
assert_raises(ValueError, plt.subplots, 2, 2, sharey='blah')
108+
assert_raises(ValueError, plt.subplots, 2, 2, -1)
109+
# uncomment this for 1.5
110+
# assert_raises(ValueError, plt.subplots, 2, 2, 0)
111+
assert_raises(ValueError, plt.subplots, 2, 2, 5)
108112

109113

110114
@image_comparison(baseline_images=['subplots_offset_text'], remove_text=False)
111115
def test_subplots_offsettext():
112-
x = numpy.arange(0,1e10,1e9)
113-
y = numpy.arange(0,100,10)+1e4
114-
fig,axes = plt.subplots(2,2, sharex = 'col', sharey = 'all')
115-
axes[0,0].plot(x,x)
116-
axes[1,0].plot(x,x)
117-
axes[0,1].plot(y,x)
118-
axes[1,1].plot(y,x)
116+
x = numpy.arange(0, 1e10, 1e9)
117+
y = numpy.arange(0, 100, 10)+1e4
118+
fig, axes = plt.subplots(2, 2, sharex='col', sharey='all')
119+
axes[0, 0].plot(x, x)
120+
axes[1, 0].plot(x, x)
121+
axes[0, 1].plot(y, x)
122+
axes[1, 1].plot(y, x)
119123

120124

125+
@cleanup
121126
def test_subplots():
122127
# things to test
123128
# - are axes actually shared?

0 commit comments

Comments
 (0)
0