Hi matplotlib developers, I was answering a question on the -users list and came across a gridspec __getitem__ bug which causes an infinite loop if the user tries to iterate over it, because getitem never did a sanity-check when given an integer key.
from matplotlib import gridspec gs = gridspec.GridSpec(1,2) gs[100] # no error is given, a SubplotSpec is returned [x for x in gs] # causes infinite loop before applying patch # after applying the patch - which is just lines 171-172 in the # traceback below In [9]: gs[100] ---------------------------------------------------------- IndexError Traceback (most recent call last) ./matplotlib/<ipython console> in <module>() ./matplotlib/gridspec.pyc in __getitem__(self, key) 170 key += total 171 if key >= total or key < 0: --> 172 raise IndexError("index out of range") 173 num1, num2 = key, None 174 IndexError: index out of range In [10]: [x for x in gs] Out[10]: [<matplotlib.gridspec.SubplotSpec object at 0x9b7edcc>, <matplotlib.gridspec.SubplotSpec object at 0x9b8834c>] I'm also including a patch for the gridspec docs which create a grid-of-grids using gridspec in a colorful manner. Note that there, I explicitly create indexes in the right range, like so: outer_grid = GridSpec(4, 4) for i in xrange(16): inner_grid = GridSpecFromSubplotSpec(3, 3, subplot_spec=outer_grid[i]) for j in xrange(9): ax = plt.Subplot(f, inner_grid[j]) ... because before applying the getitem patch described above, one *can't* currently iterate over the spec itself like this: outer_grid = GridSpec(4, 4) for cell in outer_grid: inner_grid = GridSpecFromSubplotSpec(3, 3, subplot_spec=cell) for subcell in inner_grid: ax = plt.Subplot(f, subcell) ... The doc patch also fixes the currently broken .. _gridspec-guide: anchor name which can be seen peeking out at the top of: http://matplotlib.sourceforge.net/users/gridspec.html because there was previously a misplaced leading \ on line 1 of doc/users/gridspec.rst best, -- Paul Ivanov 314 address only used for lists, off-list direct email at: http://pirsquared.org | GPG/PGP key id: 0x0F3E28F7
Index: doc/users/plotting/examples/demo_gridspec06.py =================================================================== --- doc/users/plotting/examples/demo_gridspec06.py (revision 0) +++ doc/users/plotting/examples/demo_gridspec06.py (revision 0) @@ -0,0 +1,41 @@ +import matplotlib.pyplot as plt +import matplotlib.gridspec as gridspec +import numpy as np +from itertools import product + +def squiggle_xy(a, b, c, d, i=np.arange(0.0, 2*np.pi, 0.05)): + return np.sin(i*a)*np.cos(i*b), np.sin(i*c)*np.cos(i*d) + +f = plt.figure(figsize=(8, 8)) + +# gridspec inside gridspec +outer_grid = gridspec.GridSpec(4, 4, wspace=0.0, hspace=0.0) + +for i in xrange(16): + inner_grid = gridspec.GridSpecFromSubplotSpec(3, 3, + subplot_spec=outer_grid[i], wspace=0.0, hspace=0.0) + a, b = int(i/4)+1,i%4+1 + for j, (c, d) in enumerate(product(range(1, 4), repeat=2)): + ax = plt.Subplot(f, inner_grid[j]) + ax.plot(*squiggle_xy(a, b, c, d)) + ax.set_xticks([]) + ax.set_yticks([]) + f.add_subplot(ax) + +all_axes = f.get_axes() + +#show only the outside spines +for ax in all_axes: + for sp in ax.spines.values(): + sp.set_visible(False) + if ax.is_first_row(): + ax.spines['top'].set_visible(True) + if ax.is_last_row(): + ax.spines['bottom'].set_visible(True) + if ax.is_first_col(): + ax.spines['left'].set_visible(True) + if ax.is_last_col(): + ax.spines['right'].set_visible(True) + +plt.show() + Index: doc/users/gridspec.rst =================================================================== --- doc/users/gridspec.rst (revision 8885) +++ doc/users/gridspec.rst (working copy) @@ -1,4 +1,4 @@ -\.. _gridspec-guide: +.. _gridspec-guide: ************************************************ @@ -129,6 +129,16 @@ .. plot:: users/plotting/examples/demo_gridspec04.py +A Complex Nested GridSpec using SubplotSpec +=========================================== + +Here's a more sophisticated example of nested gridspec where we put +a box around each cell of the outer 4x4 grid, by hiding appropriate +spines in each of the inner 3x3 grids. :: + +.. plot:: users/plotting/examples/demo_gridspec06.py + + GridSpec with Varying Cell Sizes ================================
Index: lib/matplotlib/gridspec.py =================================================================== --- lib/matplotlib/gridspec.py (revision 8885) +++ lib/matplotlib/gridspec.py (working copy) @@ -167,6 +167,8 @@ else: if key < 0: key += total + if key >= total or key < 0: + raise IndexError("index out of range") num1, num2 = key, None
signature.asc
Description: Digital signature
------------------------------------------------------------------------------ Learn how Oracle Real Application Clusters (RAC) One Node allows customers to consolidate database storage, standardize their database environment, and, should the need arise, upgrade to a full multi-node Oracle RAC database without downtime or disruption http://p.sf.net/sfu/oracle-sfdevnl
_______________________________________________ Matplotlib-devel mailing list Matplotlib-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-devel