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

Skip to content

Commit 199a87a

Browse files
committed
Don't check iterable() before len().
... because the former does not imply the latter anyways, e.g. generators are iterables but unsized. Now `plot(zip([1, 2], [3, 4]))` (py3) raises `RuntimeError: matplotlib does not support generators` (from `cbook.safe_first_element`) which is probably the intended exception, rather than `TypeError: object of type 'zip' has no len()`. Perhaps this exception should be changed to a `TypeError`, by the way...
1 parent 7b79174 commit 199a87a

10 files changed

Lines changed: 56 additions & 89 deletions

File tree

lib/matplotlib/axes/_axes.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import six
55
from six.moves import reduce, xrange, zip, zip_longest
66

7+
from collections import Sized
78
import itertools
89
import math
910
import warnings
@@ -2940,8 +2941,11 @@ def extract_err(err, data):
29402941
data : iterable
29412942
x or y from errorbar
29422943
'''
2943-
if (iterable(err) and len(err) == 2):
2944+
try:
29442945
a, b = err
2946+
except (TypeError, ValueError):
2947+
pass
2948+
else:
29452949
if iterable(a) and iterable(b):
29462950
# using list comps rather than arrays to preserve units
29472951
low = [thisx - thiserr for (thisx, thiserr)
@@ -2955,8 +2959,8 @@ def extract_err(err, data):
29552959
# special case for empty lists
29562960
if len(err) > 1:
29572961
fe = safe_first_element(err)
2958-
if not ((len(err) == len(data) and not (iterable(fe) and
2959-
len(fe) > 1))):
2962+
if (len(err) != len(data)
2963+
or isinstance(fe, Sized) and len(fe) > 1):
29602964
raise ValueError("err must be [ scalar | N, Nx1 "
29612965
"or 2xN array-like ]")
29622966
# using list comps rather than arrays to preserve units

lib/matplotlib/axes/_base.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,11 +1925,9 @@ def update_datalim(self, xys, updatex=True, updatey=True):
19251925
# limits and set the bound to be the bounds of the xydata.
19261926
# Otherwise, it will compute the bounds of it's current data
19271927
# and the data in xydata
1928-
1929-
if iterable(xys) and not len(xys):
1928+
xys = np.asarray(xys)
1929+
if not len(xys):
19301930
return
1931-
if not isinstance(xys, np.ma.MaskedArray):
1932-
xys = np.asarray(xys)
19331931
self.dataLim.update_from_data_xy(xys, self.ignore_existing_data_limits,
19341932
updatex=updatex, updatey=updatey)
19351933
self.ignore_existing_data_limits = False

lib/matplotlib/cm.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,11 @@ def set_clim(self, vmin=None, vmax=None):
305305
306306
ACCEPTS: a length 2 sequence of floats
307307
"""
308-
if (vmin is not None and vmax is None and
309-
cbook.iterable(vmin) and len(vmin) == 2):
310-
vmin, vmax = vmin
311-
308+
if vmax is None:
309+
try:
310+
vmin, vmax = vmin
311+
except (TypeError, ValueError):
312+
pass
312313
if vmin is not None:
313314
self.norm.vmin = vmin
314315
if vmax is not None:

lib/matplotlib/collections.py

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -156,31 +156,6 @@ def __init__(self,
156156
self.update(kwargs)
157157
self._paths = None
158158

159-
@staticmethod
160-
def _get_value(val):
161-
try:
162-
return (float(val), )
163-
except TypeError:
164-
if cbook.iterable(val) and len(val):
165-
try:
166-
float(cbook.safe_first_element(val))
167-
except (TypeError, ValueError):
168-
pass # raise below
169-
else:
170-
return val
171-
172-
raise TypeError('val must be a float or nonzero sequence of floats')
173-
174-
@staticmethod
175-
def _get_bool(val):
176-
if not cbook.iterable(val):
177-
val = (val,)
178-
try:
179-
bool(cbook.safe_first_element(val))
180-
except (TypeError, IndexError):
181-
raise TypeError('val must be a bool or nonzero sequence of them')
182-
return val
183-
184159
def get_paths(self):
185160
return self._paths
186161

@@ -486,7 +461,7 @@ def set_linewidth(self, lw):
486461
if lw is None:
487462
lw = mpl.rcParams['lines.linewidth']
488463
# get the un-scaled/broadcast lw
489-
self._us_lw = self._get_value(lw)
464+
self._us_lw = np.atleast_1d(np.asarray(lw))
490465

491466
# scale all of the dash patterns.
492467
self._linewidths, self._linestyles = self._bcast_lwls(
@@ -608,7 +583,7 @@ def set_antialiased(self, aa):
608583
"""
609584
if aa is None:
610585
aa = mpl.rcParams['patch.antialiased']
611-
self._antialiaseds = self._get_bool(aa)
586+
self._antialiaseds = np.atleast_1d(np.asarray(aa, bool))
612587
self.stale = True
613588

614589
def set_antialiaseds(self, aa):

lib/matplotlib/colors.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@
5858

5959
from __future__ import (absolute_import, division, print_function,
6060
unicode_literals)
61-
import re
6261
import six
6362
from six.moves import zip
63+
64+
from collections import Sized
65+
import re
6466
import warnings
6567

6668
import numpy as np
@@ -693,12 +695,12 @@ def from_list(name, colors, N=256, gamma=1.0):
693695
if not cbook.iterable(colors):
694696
raise ValueError('colors must be iterable')
695697

696-
if cbook.iterable(colors[0]) and len(colors[0]) == 2 and \
697-
not cbook.is_string_like(colors[0]):
698+
if (isinstance(colors[0], Sized) and len(colors[0]) == 2
699+
and not cbook.is_string_like(colors[0])):
698700
# List of value, color pairs
699-
vals, colors = list(zip(*colors))
701+
vals, colors = zip(*colors)
700702
else:
701-
vals = np.linspace(0., 1., len(colors))
703+
vals = np.linspace(0, 1, len(colors))
702704

703705
cdict = dict(red=[], green=[], blue=[], alpha=[])
704706
for val, color in zip(vals, colors):

lib/matplotlib/legend.py

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
from matplotlib import rcParams
3535
from matplotlib.artist import Artist, allow_rasterization
36-
from matplotlib.cbook import is_string_like, iterable, silent_list, is_hashable
36+
from matplotlib.cbook import is_string_like, silent_list, is_hashable
3737
from matplotlib.font_manager import FontProperties
3838
from matplotlib.lines import Line2D
3939
from matplotlib.patches import Patch, Rectangle, Shadow, FancyBboxPatch
@@ -408,17 +408,6 @@ def _set_loc(self, loc):
408408
# find_offset function will be provided to _legend_box and
409409
# _legend_box will draw itself at the location of the return
410410
# value of the find_offset.
411-
self._loc_real = loc
412-
if loc == 0:
413-
_findoffset = self._findoffset_best
414-
else:
415-
_findoffset = self._findoffset_loc
416-
417-
# def findoffset(width, height, xdescent, ydescent):
418-
# return _findoffset(width, height, xdescent, ydescent, renderer)
419-
420-
self._legend_box.set_offset(_findoffset)
421-
422411
self._loc_real = loc
423412
self.stale = True
424413

@@ -427,24 +416,20 @@ def _get_loc(self):
427416

428417
_loc = property(_get_loc, _set_loc)
429418

430-
def _findoffset_best(self, width, height, xdescent, ydescent, renderer):
431-
"Helper function to locate the legend at its best position"
432-
ox, oy = self._find_best_position(width, height, renderer)
433-
return ox + xdescent, oy + ydescent
434-
435-
def _findoffset_loc(self, width, height, xdescent, ydescent, renderer):
436-
"Helper function to locate the legend using the location code"
419+
def _findoffset(self, width, height, xdescent, ydescent, renderer):
420+
"Helper function to locate the legend"
437421

438-
if iterable(self._loc) and len(self._loc) == 2:
439-
# when loc is a tuple of axes(or figure) coordinates.
440-
fx, fy = self._loc
441-
bbox = self.get_bbox_to_anchor()
442-
x, y = bbox.x0 + bbox.width * fx, bbox.y0 + bbox.height * fy
443-
else:
422+
if self._loc == 0: # "best".
423+
x, y = self._find_best_position(width, height, renderer)
424+
elif self._loc in Legend.codes.values(): # Fixed location.
444425
bbox = Bbox.from_bounds(0, 0, width, height)
445426
x, y = self._get_anchored_bbox(self._loc, bbox,
446427
self.get_bbox_to_anchor(),
447428
renderer)
429+
else: # Axes or figure coordinates.
430+
fx, fy = self._loc
431+
bbox = self.get_bbox_to_anchor()
432+
x, y = bbox.x0 + bbox.width * fx, bbox.y0 + bbox.height * fy
448433

449434
return x + xdescent, y + ydescent
450435

@@ -701,6 +686,7 @@ def _init_legend_box(self, handles, labels, markerfirst=True):
701686
children=[self._legend_title_box,
702687
self._legend_handle_box])
703688
self._legend_box.set_figure(self.figure)
689+
self._legend_box.set_offset(self._findoffset)
704690
self.texts = text_list
705691
self.legendHandles = handle_list
706692

lib/matplotlib/markers.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,12 @@
8989
import six
9090
from six.moves import xrange
9191

92+
from collections import Sized
93+
9294
import numpy as np
9395

94-
from .cbook import is_math_text, is_string_like, is_numlike, iterable
95-
from matplotlib import rcParams
96+
from . import rcParams
97+
from .cbook import is_math_text, is_string_like, is_numlike
9698
from .path import Path
9799
from .transforms import IdentityTransform, Affine2D
98100

@@ -247,7 +249,7 @@ def get_marker(self):
247249
return self._marker
248250

249251
def set_marker(self, marker):
250-
if (iterable(marker) and len(marker) in (2, 3) and
252+
if (isinstance(marker, Sized) and len(marker) in (2, 3) and
251253
marker[1] in (0, 1, 2, 3)):
252254
self._marker_function = self._set_tuple_marker
253255
elif isinstance(marker, np.ndarray):

lib/matplotlib/rcsetup.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,13 @@
1818

1919
import six
2020

21+
from collections import Iterable, Mapping
2122
from functools import reduce
2223
import operator
2324
import os
2425
import warnings
2526
import re
2627

27-
try:
28-
import collections.abc as abc
29-
except ImportError:
30-
# python 2
31-
import collections as abc
32-
3328
from matplotlib.cbook import mplDeprecation
3429
from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
3530
from matplotlib.colors import is_color_like
@@ -92,7 +87,7 @@ def f(s):
9287
# Numpy ndarrays, and pandas data structures. However, unordered
9388
# sequences, such as sets, should be allowed but discouraged unless the
9489
# user desires pseudorandom behavior.
95-
elif isinstance(s, abc.Iterable) and not isinstance(s, abc.Mapping):
90+
elif isinstance(s, Iterable) and not isinstance(s, Mapping):
9691
# The condition on this list comprehension will preserve the
9792
# behavior of filtering out any empty strings (behavior was
9893
# from the original validate_stringlist()), while allowing

lib/matplotlib/tests/test_collections.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import io
88

99
import numpy as np
10-
from numpy.testing import assert_array_equal, assert_array_almost_equal
11-
from numpy.testing import assert_equal
10+
from numpy.testing import (
11+
assert_array_equal, assert_array_almost_equal, assert_equal)
1212
import pytest
1313

1414
import matplotlib.pyplot as plt
@@ -641,9 +641,9 @@ def test_lslw_bcast():
641641
col.set_linestyles(['-', '-'])
642642
col.set_linewidths([1, 2, 3])
643643

644-
assert col.get_linestyles() == [(None, None)] * 6
645-
assert col.get_linewidths() == [1, 2, 3] * 2
644+
assert_equal(col.get_linestyles(), [(None, None)] * 6)
645+
assert_equal(col.get_linewidths(), [1, 2, 3] * 2)
646646

647647
col.set_linestyles(['-', '-', '-'])
648-
assert col.get_linestyles() == [(None, None)] * 3
649-
assert col.get_linewidths() == [1, 2, 3]
648+
assert_equal(col.get_linestyles(), [(None, None)] * 3)
649+
assert_equal(col.get_linewidths(), [1, 2, 3])

lib/matplotlib/units.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,15 @@ def get_converter(self, x):
157157
converter = self.get_converter(next_item)
158158
return converter
159159

160-
if converter is None and iterable(x) and (len(x) > 0):
161-
thisx = safe_first_element(x)
162-
if classx and classx != getattr(thisx, '__class__', None):
163-
converter = self.get_converter(thisx)
164-
return converter
160+
if converter is None:
161+
try:
162+
thisx = safe_first_element(x)
163+
except (TypeError, StopIteration):
164+
pass
165+
else:
166+
if classx and classx != getattr(thisx, '__class__', None):
167+
converter = self.get_converter(thisx)
168+
return converter
165169

166170
# DISABLED self._cached[idx] = converter
167171
return converter

0 commit comments

Comments
 (0)