diff --git a/doc/api/api_changes/2016-03-13-PMH.rst b/doc/api/api_changes/2016-03-13-PMH.rst
new file mode 100644
index 000000000000..209df726cd0e
--- /dev/null
+++ b/doc/api/api_changes/2016-03-13-PMH.rst
@@ -0,0 +1,10 @@
+Changed default ``autorange`` behavior in boxplots
+``````````````````````````````````````````````````
+
+Prior to v1.5.2, the whiskers of boxplots would extend to the mininum
+and maximum values if the quartiles were all equal (i.e., Q1 = median
+= Q3). This behavior has been disabled by default to restore consistency
+with other plotting packages.
+
+To restore the old behavior, simply set ``autorange=True`` when
+calling ``plt.boxplot``.
diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py
index dc6082f222a0..423a714d021a 100644
--- a/lib/matplotlib/animation.py
+++ b/lib/matplotlib/animation.py
@@ -755,8 +755,8 @@ def save(self, filename, writer=None, fps=None, dpi=None, codec=None,
# Re-use the savefig DPI for ours if none is given
if dpi is None:
dpi = rcParams['savefig.dpi']
- if dpi == 'figure':
- dpi = self._fig.dpi
+ if dpi == 'figure':
+ dpi = self._fig.dpi
if codec is None:
codec = rcParams['animation.codec']
diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py
index c68fc0f0dbc0..46420c5e72e0 100644
--- a/lib/matplotlib/axes/_axes.py
+++ b/lib/matplotlib/axes/_axes.py
@@ -1491,13 +1491,13 @@ def plot_date(self, x, y, fmt='o', tz=None, xdate=True, ydate=False,
if not self._hold:
self.cla()
- ret = self.plot(x, y, fmt, **kwargs)
-
if xdate:
self.xaxis_date(tz)
if ydate:
self.yaxis_date(tz)
+ ret = self.plot(x, y, fmt, **kwargs)
+
self.autoscale_view()
return ret
@@ -3049,9 +3049,10 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
positions=None, widths=None, patch_artist=None,
bootstrap=None, usermedians=None, conf_intervals=None,
meanline=None, showmeans=None, showcaps=None,
- showbox=None, showfliers=None, boxprops=None, labels=None,
- flierprops=None, medianprops=None, meanprops=None,
- capprops=None, whiskerprops=None, manage_xticks=True):
+ showbox=None, showfliers=None, boxprops=None,
+ labels=None, flierprops=None, medianprops=None,
+ meanprops=None, capprops=None, whiskerprops=None,
+ manage_xticks=True, autorange=False):
"""
Make a box and whisker plot.
@@ -3061,12 +3062,13 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
positions=None, widths=None, patch_artist=False,
bootstrap=None, usermedians=None, conf_intervals=None,
meanline=False, showmeans=False, showcaps=True,
- showbox=True, showfliers=True, boxprops=None, labels=None,
- flierprops=None, medianprops=None, meanprops=None,
- capprops=None, whiskerprops=None, manage_xticks=True):
+ showbox=True, showfliers=True, boxprops=None,
+ labels=None, flierprops=None, medianprops=None,
+ meanprops=None, capprops=None, whiskerprops=None,
+ manage_xticks=True, autorange=False):
- Make a box and whisker plot for each column of *x* or each
- vector in sequence *x*. The box extends from the lower to
+ Make a box and whisker plot for each column of ``x`` or each
+ vector in sequence ``x``. The box extends from the lower to
upper quartile values of the data, with a line at the median.
The whiskers extend from the box to show the range of the
data. Flier points are those past the end of the whiskers.
@@ -3074,140 +3076,145 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
Parameters
----------
x : Array or a sequence of vectors.
- The input data.
-
- notch : bool, default = False
- If False, produces a rectangular box plot.
- If True, will produce a notched box plot
-
- sym : str or None, default = None
- The default symbol for flier points.
- Enter an empty string ('') if you don't want to show fliers.
- If `None`, then the fliers default to 'b+' If you want more
- control use the flierprops kwarg.
-
- vert : bool, default = True
- If True (default), makes the boxes vertical.
- If False, makes horizontal boxes.
-
- whis : float, sequence (default = 1.5) or string
- As a float, determines the reach of the whiskers past the first
- and third quartiles (e.g., Q3 + whis*IQR, IQR = interquartile
- range, Q3-Q1). Beyond the whiskers, data are considered outliers
- and are plotted as individual points. Set this to an unreasonably
- high value to force the whiskers to show the min and max values.
- Alternatively, set this to an ascending sequence of percentile
- (e.g., [5, 95]) to set the whiskers at specific percentiles of
- the data. Finally, *whis* can be the string 'range' to force the
- whiskers to the min and max of the data. In the edge case that
- the 25th and 75th percentiles are equivalent, *whis* will be
- automatically set to 'range'.
-
- bootstrap : None (default) or integer
- Specifies whether to bootstrap the confidence intervals
- around the median for notched boxplots. If bootstrap==None,
- no bootstrapping is performed, and notches are calculated
- using a Gaussian-based asymptotic approximation (see McGill, R.,
- Tukey, J.W., and Larsen, W.A., 1978, and Kendall and Stuart,
- 1967). Otherwise, bootstrap specifies the number of times to
- bootstrap the median to determine it's 95% confidence intervals.
- Values between 1000 and 10000 are recommended.
-
- usermedians : array-like or None (default)
- An array or sequence whose first dimension (or length) is
- compatible with *x*. This overrides the medians computed by
- matplotlib for each element of *usermedians* that is not None.
- When an element of *usermedians* == None, the median will be
- computed by matplotlib as normal.
-
- conf_intervals : array-like or None (default)
- Array or sequence whose first dimension (or length) is compatible
- with *x* and whose second dimension is 2. When the current element
- of *conf_intervals* is not None, the notch locations computed by
- matplotlib are overridden (assuming notch is True). When an
- element of *conf_intervals* is None, boxplot compute notches the
- method specified by the other kwargs (e.g., *bootstrap*).
-
- positions : array-like, default = [1, 2, ..., n]
- Sets the positions of the boxes. The ticks and limits
- are automatically set to match the positions.
-
- widths : array-like, default = 0.5
- Either a scalar or a vector and sets the width of each box. The
- default is 0.5, or ``0.15*(distance between extreme positions)``
- if that is smaller.
-
- labels : sequence or None (default)
- Labels for each dataset. Length must be compatible with
- dimensions of *x*
-
- patch_artist : bool, default = False
- If False produces boxes with the Line2D artist
- If True produces boxes with the Patch artist
-
- showmeans : bool, default = False
- If True, will toggle on the rendering of the means
-
- showcaps : bool, default = True
- If True, will toggle on the rendering of the caps
-
- showbox : bool, default = True
- If True, will toggle on the rendering of the box
-
- showfliers : bool, default = True
- If True, will toggle on the rendering of the fliers
-
- boxprops : dict or None (default)
- If provided, will set the plotting style of the boxes
-
- whiskerprops : dict or None (default)
- If provided, will set the plotting style of the whiskers
+ The input data.
+
+ notch : bool, optional (False)
+ If `True`, will produce a notched box plot. Otherwise, a
+ rectangular boxplot is produced.
+
+ sym : str, optional
+ The default symbol for flier points. Enter an empty string
+ ('') if you don't want to show fliers. If `None`, then the
+ fliers default to 'b+' If you want more control use the
+ flierprops kwarg.
+
+ vert : bool, optional (True)
+ If `True` (default), makes the boxes vertical. If `False`,
+ everything is drawn horizontally.
+
+ whis : float, sequence, or string (default = 1.5)
+ As a float, determines the reach of the whiskers past the
+ first and third quartiles (e.g., Q3 + whis*IQR,
+ IQR = interquartile range, Q3-Q1). Beyond the whiskers, data
+ are considered outliers and are plotted as individual
+ points. Set this to an unreasonably high value to force the
+ whiskers to show the min and max values. Alternatively, set
+ this to an ascending sequence of percentile (e.g., [5, 95])
+ to set the whiskers at specific percentiles of the data.
+ Finally, ``whis`` can be the string ``'range'`` to force the
+ whiskers to the min and max of the data.
+
+ bootstrap : int, optional
+ Specifies whether to bootstrap the confidence intervals
+ around the median for notched boxplots. If `bootstrap` is None,
+ no bootstrapping is performed, and notches are calculated
+ using a Gaussian-based asymptotic approximation (see McGill,
+ R., Tukey, J.W., and Larsen, W.A., 1978, and Kendall and
+ Stuart, 1967). Otherwise, bootstrap specifies the number of
+ times to bootstrap the median to determine its 95%
+ confidence intervals. Values between 1000 and 10000 are
+ recommended.
+
+ usermedians : array-like, optional
+ An array or sequence whose first dimension (or length) is
+ compatible with ``x``. This overrides the medians computed
+ by matplotlib for each element of ``usermedians`` that is not
+ `None`. When an element of ``usermedians`` is None, the median
+ will be computed by matplotlib as normal.
+
+ conf_intervals : array-like, optional
+ Array or sequence whose first dimension (or length) is
+ compatible with ``x`` and whose second dimension is 2. When
+ the an element of ``conf_intervals`` is not None, the
+ notch locations computed by matplotlib are overridden
+ (provided ``notch`` is `True`). When an element of
+ ``conf_intervals`` is `None`, the notches are computed by the
+ method specified by the other kwargs (e.g., ``bootstrap``).
+
+ positions : array-like, optional
+ Sets the positions of the boxes. The ticks and limits are
+ automatically set to match the positions. Defaults to
+ `range(1, N+1)` where N is the number of boxes to be drawn.
+
+ widths : scalar or array-like
+ Sets the width of each box either with a scalar or a
+ sequence. The default is 0.5, or ``0.15*(distance between
+ extreme positions)``, if that is smaller.
+
+ patch_artist : bool, optional (False)
+ If `False` produces boxes with the Line2D artist. Otherwise,
+ boxes and drawn with Patch artists.
+
+ labels : sequence, optional
+ Labels for each dataset. Length must be compatible with
+ dimensions of ``x``.
+
+ manage_xticks : bool, optional (True)
+ If the function should adjust the xlim and xtick locations.
- capprops : dict or None (default)
- If provided, will set the plotting style of the caps
+ autorange : bool, optional (False)
+ When `True` and the data are distributed such that the 25th and
+ 75th percentiles are equal, ``whis`` is set to ``'range'`` such
+ that the whisker ends are at the minimum and maximum of the
+ data.
+
+ meanline : bool, optional (False)
+ If `True` (and ``showmeans`` is `True`), will try to render
+ the mean as a line spanning the full width of the box
+ according to ``meanprops`` (see below). Not recommended if
+ ``shownotches`` is also True. Otherwise, means will be shown
+ as points.
+
+ Additional Options
+ ---------------------
+ The following boolean options toggle the drawing of individual
+ components of the boxplots:
+ - showcaps: the caps on the ends of whiskers
+ (default is True)
+ - showbox: the central box (default is True)
+ - showfliers: the outliers beyond the caps (default is True)
+ - showmeans: the arithmetic means (default is False)
+
+ The remaining options can accept dictionaries that specify the
+ style of the individual artists:
+ - capprops
+ - boxprops
+ - whiskerprops
+ - flierprops
+ - medianprops
+ - meanprops
- flierprops : dict or None (default)
- If provided, will set the plotting style of the fliers
+ Returns
+ -------
+ result : dict
+ A dictionary mapping each component of the boxplot to a list
+ of the :class:`matplotlib.lines.Line2D` instances
+ created. That dictionary has the following keys (assuming
+ vertical boxplots):
- medianprops : dict or None (default)
- If provided, will set the plotting style of the medians
+ - ``boxes``: the main body of the boxplot showing the
+ quartiles and the median's confidence intervals if
+ enabled.
- meanprops : dict or None (default)
- If provided, will set the plotting style of the means
+ - ``medians``: horizontal lines at the median of each box.
- meanline : bool, default = False
- If True (and *showmeans* is True), will try to render the mean
- as a line spanning the full width of the box according to
- *meanprops*. Not recommended if *shownotches* is also True.
- Otherwise, means will be shown as points.
+ - ``whiskers``: the vertical lines extending to the most
+ extreme, non-outlier data points.
- manage_xticks : bool, default = True
- If the function should adjust the xlim and xtick locations.
+ - ``caps``: the horizontal lines at the ends of the
+ whiskers.
- Returns
- -------
+ - ``fliers``: points representing data that extend beyond
+ the whiskers (fliers).
- result : dict
- A dictionary mapping each component of the boxplot
- to a list of the :class:`matplotlib.lines.Line2D`
- instances created. That dictionary has the following keys
- (assuming vertical boxplots):
-
- - boxes: the main body of the boxplot showing the quartiles
- and the median's confidence intervals if enabled.
- - medians: horizonal lines at the median of each box.
- - whiskers: the vertical lines extending to the most extreme,
- n-outlier data points.
- - caps: the horizontal lines at the ends of the whiskers.
- - fliers: points representing data that extend beyond the
- whiskers (outliers).
- - means: points or lines representing the means.
+ - ``means``: points or lines representing the means.
Examples
--------
-
.. plot:: mpl_examples/statistics/boxplot_demo.py
+
"""
+
# If defined in matplotlibrc, apply the value from rc file
# Overridden if argument is passed
if whis is None:
@@ -3215,7 +3222,7 @@ def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
if bootstrap is None:
bootstrap = rcParams['boxplot.bootstrap']
bxpstats = cbook.boxplot_stats(x, whis=whis, bootstrap=bootstrap,
- labels=labels)
+ labels=labels, autorange=autorange)
if notch is None:
notch = rcParams['boxplot.notch']
if vert is None:
@@ -3461,10 +3468,10 @@ def bxp(self, bxpstats, positions=None, widths=None, vert=True,
quartiles and the median's confidence intervals if
enabled.
- - ``medians``: horizonal lines at the median of each box.
+ - ``medians``: horizontal lines at the median of each box.
- ``whiskers``: the vertical lines extending to the most
- extreme, n-outlier data points.
+ extreme, non-outlier data points.
- ``caps``: the horizontal lines at the ends of the
whiskers.
@@ -3724,7 +3731,7 @@ def scatter(self, x, y, s=20, c=None, marker='o', cmap=None, norm=None,
**kwargs):
"""
Make a scatter plot of x vs y, where x and y are sequence like objects
- of the same lengths.
+ of the same length.
Parameters
----------
@@ -3734,7 +3741,7 @@ def scatter(self, x, y, s=20, c=None, marker='o', cmap=None, norm=None,
s : scalar or array_like, shape (n, ), optional, default: 20
size in points^2.
- c : color or sequence of color, optional, default : 'b'
+ c : color, sequence, or sequence of color, optional, default: 'b'
`c` can be a single color format string, or a sequence of color
specifications of length `N`, or a sequence of `N` numbers to be
mapped to colors using the `cmap` and `norm` specified via kwargs
diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py
index 7475adc66bdf..08b54b503b10 100644
--- a/lib/matplotlib/backend_bases.py
+++ b/lib/matplotlib/backend_bases.py
@@ -2141,8 +2141,8 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
if dpi is None:
dpi = rcParams['savefig.dpi']
- if dpi == 'figure':
- dpi = self.figure.dpi
+ if dpi == 'figure':
+ dpi = self.figure.dpi
origDPI = self.figure.dpi
origfacecolor = self.figure.get_facecolor()
diff --git a/lib/matplotlib/backends/backend_qt5agg.py b/lib/matplotlib/backends/backend_qt5agg.py
index 656c837e5e65..5920ab09c7cf 100644
--- a/lib/matplotlib/backends/backend_qt5agg.py
+++ b/lib/matplotlib/backends/backend_qt5agg.py
@@ -172,6 +172,9 @@ def draw_idle(self):
QtCore.QTimer.singleShot(0, self.__draw_idle_agg)
def __draw_idle_agg(self, *args):
+ if self.height() < 0 or self.width() < 0:
+ self._agg_draw_pending = False
+ return
try:
FigureCanvasAgg.draw(self)
self.update()
diff --git a/lib/matplotlib/backends/qt_compat.py b/lib/matplotlib/backends/qt_compat.py
index 67d0687a7ca7..0546bdc7b1e1 100644
--- a/lib/matplotlib/backends/qt_compat.py
+++ b/lib/matplotlib/backends/qt_compat.py
@@ -42,7 +42,23 @@
QT_API = None
-if (QT_API_ENV is not None):
+# check if any binding is already imported, if so silently ignore the
+# rcparams/ENV settings and use what ever is already imported.
+if 'PySide' in sys.modules:
+ # user has imported PySide before importing mpl
+ QT_API = QT_API_PYSIDE
+
+if 'PyQt4' in sys.modules:
+ # user has imported PyQt4 before importing mpl
+ # this case also handles the PyQt4v2 case as once sip is imported
+ # the API versions can not be changed so do not try
+ QT_API = QT_API_PYQT
+
+if 'PyQt5' in sys.modules:
+ # the user has imported PyQt5 before importing mpl
+ QT_API = QT_API_PYQT5
+
+if (QT_API_ENV is not None) and QT_API is None:
try:
QT_ENV_MAJOR_VERSION = ETS[QT_API_ENV][1]
except KeyError:
@@ -61,15 +77,12 @@
elif rcParams['backend'] == 'Qt4Agg':
QT_API = rcParams['backend.qt4']
else:
- # A different backend was specified, but we still got here because a Qt
- # related file was imported. This is allowed, so lets try and guess
- # what we should be using.
- if "PyQt4" in sys.modules or "PySide" in sys.modules:
- # PyQt4 or PySide is actually used.
- QT_API = rcParams['backend.qt4']
- else:
- # This is a fallback: PyQt5
- QT_API = rcParams['backend.qt5']
+ # A non-Qt backend was specified, no version of the Qt
+ # bindings is imported, but we still got here because a Qt
+ # related file was imported. This is allowed, fall back to Qt5
+ # using which ever binding the rparams ask for.
+
+ QT_API = rcParams['backend.qt5']
# We will define an appropriate wrapper for the differing versions
# of file dialog.
diff --git a/lib/matplotlib/cbook.py b/lib/matplotlib/cbook.py
index ec106cf78860..a43971c5a169 100644
--- a/lib/matplotlib/cbook.py
+++ b/lib/matplotlib/cbook.py
@@ -715,6 +715,17 @@ def is_sequence_of_strings(obj):
return True
+def is_hashable(obj):
+ """
+ Returns true if *obj* can be hashed
+ """
+ try:
+ hash(obj)
+ except TypeError:
+ return False
+ return True
+
+
def is_writable_file_like(obj):
'return true if *obj* looks like a file object with a *write* method'
return hasattr(obj, 'write') and six.callable(obj.write)
@@ -1863,39 +1874,46 @@ def delete_masked_points(*args):
return margs
-def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None):
- '''
- Returns list of dictionaries of staticists to be use to draw a series of
- box and whisker plots. See the `Returns` section below to the required
- keys of the dictionary. Users can skip this function and pass a user-
- defined set of dictionaries to the new `axes.bxp` method instead of
- relying on MPL to do the calcs.
+def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None,
+ autorange=False):
+ """
+ Returns list of dictionaries of statistics used to draw a series
+ of box and whisker plots. The `Returns` section enumerates the
+ required keys of the dictionary. Users can skip this function and
+ pass a user-defined set of dictionaries to the new `axes.bxp` method
+ instead of relying on MPL to do the calculations.
Parameters
----------
X : array-like
- Data that will be represented in the boxplots. Should have 2 or fewer
- dimensions.
+ Data that will be represented in the boxplots. Should have 2 or
+ fewer dimensions.
whis : float, string, or sequence (default = 1.5)
- As a float, determines the reach of the whiskers past the first and
- third quartiles (e.g., Q3 + whis*IQR, QR = interquartile range, Q3-Q1).
- Beyond the whiskers, data are considered outliers and are plotted as
- individual points. Set this to an unreasonably high value to force the
- whiskers to show the min and max data. Alternatively, set this to an
- ascending sequence of percentile (e.g., [5, 95]) to set the whiskers
- at specific percentiles of the data. Finally, can `whis` be the
- string 'range' to force the whiskers to the min and max of the data.
- In the edge case that the 25th and 75th percentiles are equivalent,
- `whis` will be automatically set to 'range'
-
- bootstrap : int or None (default)
- Number of times the confidence intervals around the median should
- be bootstrapped (percentile method).
-
- labels : sequence
- Labels for each dataset. Length must be compatible with dimensions
- of `X`
+ As a float, determines the reach of the whiskers past the first
+ and third quartiles (e.g., Q3 + whis*IQR, QR = interquartile
+ range, Q3-Q1). Beyond the whiskers, data are considered outliers
+ and are plotted as individual points. This can be set this to an
+ ascending sequence of percentile (e.g., [5, 95]) to set the
+ whiskers at specific percentiles of the data. Finally, `whis`
+ can be the string ``'range'`` to force the whiskers to the
+ minimum and maximum of the data. In the edge case that the 25th
+ and 75th percentiles are equivalent, `whis` can be automatically
+ set to ``'range'`` via the `autorange` option.
+
+ bootstrap : int, optional
+ Number of times the confidence intervals around the median
+ should be bootstrapped (percentile method).
+
+ labels : array-like, optional
+ Labels for each dataset. Length must be compatible with
+ dimensions of `X`.
+
+ autorange : bool, optional (False)
+ When `True` and the data are distributed such that the 25th and
+ 75th percentiles are equal, ``whis`` is set to ``'range'`` such
+ that the whisker ends are at the minimum and maximum of the
+ data.
Returns
-------
@@ -1920,8 +1938,8 @@ def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None):
Notes
-----
- Non-bootstrapping approach to confidence interval uses Gaussian-based
- asymptotic approximation:
+ Non-bootstrapping approach to confidence interval uses Gaussian-
+ based asymptotic approximation:
.. math::
@@ -1931,7 +1949,7 @@ def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None):
McGill, R., Tukey, J.W., and Larsen, W.A. (1978) "Variations of
Boxplots", The American Statistician, 32:12-16.
- '''
+ """
def _bootstrap_median(data, N=5000):
# determine 95% confidence intervals of the median
@@ -2011,7 +2029,7 @@ def _compute_conf_interval(data, med, iqr, bootstrap):
# interquartile range
stats['iqr'] = q3 - q1
- if stats['iqr'] == 0:
+ if stats['iqr'] == 0 and autorange:
whis = 'range'
# conf. interval around median
diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py
index 2a33ba21b374..5576def9d440 100644
--- a/lib/matplotlib/collections.py
+++ b/lib/matplotlib/collections.py
@@ -151,7 +151,7 @@ def _get_value(val):
except TypeError:
if cbook.iterable(val) and len(val):
try:
- float(val[0])
+ float(cbook.safe_first_element(val))
except (TypeError, ValueError):
pass # raise below
else:
@@ -164,7 +164,7 @@ def _get_bool(val):
if not cbook.iterable(val):
val = (val,)
try:
- bool(val[0])
+ bool(cbook.safe_first_element(val))
except (TypeError, IndexError):
raise TypeError('val must be a bool or nonzero sequence of them')
return val
@@ -532,7 +532,7 @@ def set_linestyle(self, ls):
The line style.
"""
try:
- if cbook.is_string_like(ls):
+ if cbook.is_string_like(ls) and cbook.is_hashable(ls):
ls = cbook.ls_mapper.get(ls, ls)
dashes = [mlines.get_dash_pattern(ls)]
elif cbook.iterable(ls):
diff --git a/lib/matplotlib/colors.py b/lib/matplotlib/colors.py
index 73509990d41d..043a7986571c 100644
--- a/lib/matplotlib/colors.py
+++ b/lib/matplotlib/colors.py
@@ -821,7 +821,8 @@ def __init__(self, colors, name='from_list', N=None):
if N is None:
N = len(self.colors)
else:
- if cbook.is_string_like(self.colors):
+ if (cbook.is_string_like(self.colors) and
+ cbook.is_hashable(self.colors)):
self.colors = [self.colors] * N
self.monochrome = True
elif cbook.iterable(self.colors):
diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py
index 5557cb517738..d6bad2652961 100644
--- a/lib/matplotlib/figure.py
+++ b/lib/matplotlib/figure.py
@@ -1508,8 +1508,6 @@ def savefig(self, *args, **kwargs):
"""
kwargs.setdefault('dpi', rcParams['savefig.dpi'])
- if kwargs['dpi'] == 'figure':
- kwargs['dpi'] = self.get_dpi()
frameon = kwargs.pop('frameon', rcParams['savefig.frameon'])
transparent = kwargs.pop('transparent',
rcParams['savefig.transparent'])
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_false_whiskers.png b/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_false_whiskers.png
new file mode 100644
index 000000000000..788c38e8effa
Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_false_whiskers.png differ
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_whiskers.png b/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_true_whiskers.png
similarity index 100%
rename from lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_whiskers.png
rename to lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_true_whiskers.png
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_whiskers.pdf b/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_whiskers.pdf
deleted file mode 100644
index 933a067b2d06..000000000000
Binary files a/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_whiskers.pdf and /dev/null differ
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_whiskers.svg b/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_whiskers.svg
deleted file mode 100644
index 6e3a395ea6ee..000000000000
--- a/lib/matplotlib/tests/baseline_images/test_axes/boxplot_autorange_whiskers.svg
+++ /dev/null
@@ -1,374 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="432pt" version="1.1" viewBox="0 0 576 432" width="576pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 432
-L 576 432
-L 576 0
-L 0 0
-z
-" style="fill:#ffffff;"/>
- </g>
- <g id="axes_1">
- <g id="patch_2">
- <path d="M 72 388.8
-L 518.4 388.8
-L 518.4 43.2
-L 72 43.2
-z
-" style="fill:#ffffff;"/>
- </g>
- <g id="line2d_1">
- <path clip-path="url(#pc653b2bace)" d="M 166.86 181.44
-L 200.34 181.44
-L 200.34 181.44
-L 191.97 181.44
-L 200.34 181.44
-L 200.34 181.44
-L 166.86 181.44
-L 166.86 181.44
-L 175.23 181.44
-L 166.86 181.44
-L 166.86 181.44
-" style="fill:none;stroke:#0000ff;stroke-linecap:square;"/>
- </g>
- <g id="line2d_2">
- <path clip-path="url(#pc653b2bace)" d="M 183.6 181.44
-L 183.6 216
-" style="fill:none;stroke:#0000ff;stroke-dasharray:6.000000,6.000000;stroke-dashoffset:0.0;"/>
- </g>
- <g id="line2d_3">
- <path clip-path="url(#pc653b2bace)" d="M 183.6 181.44
-L 183.6 146.88
-" style="fill:none;stroke:#0000ff;stroke-dasharray:6.000000,6.000000;stroke-dashoffset:0.0;"/>
- </g>
- <g id="line2d_4">
- <path clip-path="url(#pc653b2bace)" d="M 175.23 216
-L 191.97 216
-" style="fill:none;stroke:#000000;stroke-linecap:square;"/>
- </g>
- <g id="line2d_5">
- <path clip-path="url(#pc653b2bace)" d="M 175.23 146.88
-L 191.97 146.88
-" style="fill:none;stroke:#000000;stroke-linecap:square;"/>
- </g>
- <g id="line2d_6">
- <path clip-path="url(#pc653b2bace)" d="M 175.23 181.44
-L 191.97 181.44
-" style="fill:none;stroke:#ff0000;stroke-linecap:square;"/>
- </g>
- <g id="line2d_7"/>
- <g id="line2d_8">
- <path clip-path="url(#pc653b2bace)" d="M 390.06 181.44
-L 423.54 181.44
-L 423.54 181.44
-L 415.17 181.44
-L 423.54 181.44
-L 423.54 181.44
-L 390.06 181.44
-L 390.06 181.44
-L 398.43 181.44
-L 390.06 181.44
-L 390.06 181.44
-" style="fill:none;stroke:#0000ff;stroke-linecap:square;"/>
- </g>
- <g id="line2d_9">
- <path clip-path="url(#pc653b2bace)" d="M 406.8 181.44
-L 406.8 216
-" style="fill:none;stroke:#0000ff;stroke-dasharray:6.000000,6.000000;stroke-dashoffset:0.0;"/>
- </g>
- <g id="line2d_10">
- <path clip-path="url(#pc653b2bace)" d="M 406.8 181.44
-L 406.8 146.88
-" style="fill:none;stroke:#0000ff;stroke-dasharray:6.000000,6.000000;stroke-dashoffset:0.0;"/>
- </g>
- <g id="line2d_11">
- <path clip-path="url(#pc653b2bace)" d="M 398.43 216
-L 415.17 216
-" style="fill:none;stroke:#000000;stroke-linecap:square;"/>
- </g>
- <g id="line2d_12">
- <path clip-path="url(#pc653b2bace)" d="M 398.43 146.88
-L 415.17 146.88
-" style="fill:none;stroke:#000000;stroke-linecap:square;"/>
- </g>
- <g id="line2d_13">
- <path clip-path="url(#pc653b2bace)" d="M 398.43 181.44
-L 415.17 181.44
-" style="fill:none;stroke:#ff0000;stroke-linecap:square;"/>
- </g>
- <g id="line2d_14"/>
- <g id="patch_3">
- <path d="M 72 388.8
-L 72 43.2
-" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;"/>
- </g>
- <g id="patch_4">
- <path d="M 518.4 388.8
-L 518.4 43.2
-" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;"/>
- </g>
- <g id="patch_5">
- <path d="M 72 388.8
-L 518.4 388.8
-" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;"/>
- </g>
- <g id="patch_6">
- <path d="M 72 43.2
-L 518.4 43.2
-" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;"/>
- </g>
- <g id="matplotlib.axis_1">
- <g id="xtick_1">
- <g id="line2d_15">
- <defs>
- <path d="M 0 0
-L 0 -4
-" id="md896a425d7" style="stroke:#000000;stroke-width:0.500000;"/>
- </defs>
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="183.6" xlink:href="#md896a425d7" y="388.8"/>
- </g>
- </g>
- <g id="line2d_16">
- <defs>
- <path d="M 0 0
-L 0 4
-" id="me12a3a8566" style="stroke:#000000;stroke-width:0.500000;"/>
- </defs>
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="183.6" xlink:href="#me12a3a8566" y="43.2"/>
- </g>
- </g>
- <g id="text_1">
- <!-- 1 -->
- <defs>
- <path d="M 12.40625 8.296875
-L 28.515625 8.296875
-L 28.515625 63.921875
-L 10.984375 60.40625
-L 10.984375 69.390625
-L 28.421875 72.90625
-L 38.28125 72.90625
-L 38.28125 8.296875
-L 54.390625 8.296875
-L 54.390625 0
-L 12.40625 0
-z
-" id="DejaVuSans-31"/>
- </defs>
- <g transform="translate(179.782500 401.918125)scale(0.120000 -0.120000)">
- <use xlink:href="#DejaVuSans-31"/>
- </g>
- </g>
- </g>
- <g id="xtick_2">
- <g id="line2d_17">
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="406.8" xlink:href="#md896a425d7" y="388.8"/>
- </g>
- </g>
- <g id="line2d_18">
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="406.8" xlink:href="#me12a3a8566" y="43.2"/>
- </g>
- </g>
- <g id="text_2">
- <!-- 2 -->
- <defs>
- <path d="M 19.1875 8.296875
-L 53.609375 8.296875
-L 53.609375 0
-L 7.328125 0
-L 7.328125 8.296875
-Q 12.9375 14.109375 22.625 23.890625
-Q 32.328125 33.6875 34.8125 36.53125
-Q 39.546875 41.84375 41.421875 45.53125
-Q 43.3125 49.21875 43.3125 52.78125
-Q 43.3125 58.59375 39.234375 62.25
-Q 35.15625 65.921875 28.609375 65.921875
-Q 23.96875 65.921875 18.8125 64.3125
-Q 13.671875 62.703125 7.8125 59.421875
-L 7.8125 69.390625
-Q 13.765625 71.78125 18.9375 73
-Q 24.125 74.21875 28.421875 74.21875
-Q 39.75 74.21875 46.484375 68.546875
-Q 53.21875 62.890625 53.21875 53.421875
-Q 53.21875 48.921875 51.53125 44.890625
-Q 49.859375 40.875 45.40625 35.40625
-Q 44.1875 33.984375 37.640625 27.21875
-Q 31.109375 20.453125 19.1875 8.296875
-" id="DejaVuSans-32"/>
- </defs>
- <g transform="translate(402.982500 401.918125)scale(0.120000 -0.120000)">
- <use xlink:href="#DejaVuSans-32"/>
- </g>
- </g>
- </g>
- </g>
- <g id="matplotlib.axis_2">
- <g id="ytick_1">
- <g id="line2d_19">
- <defs>
- <path d="M 0 0
-L 4 0
-" id="m57755297b5" style="stroke:#000000;stroke-width:0.500000;"/>
- </defs>
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="72.0" xlink:href="#m57755297b5" y="354.24"/>
- </g>
- </g>
- <g id="line2d_20">
- <defs>
- <path d="M 0 0
-L -4 0
-" id="mb7f6c3044e" style="stroke:#000000;stroke-width:0.500000;"/>
- </defs>
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="518.4" xlink:href="#mb7f6c3044e" y="354.24"/>
- </g>
- </g>
- <g id="text_3">
- <!-- −4 -->
- <defs>
- <path d="M 10.59375 35.5
-L 73.1875 35.5
-L 73.1875 27.203125
-L 10.59375 27.203125
-z
-" id="DejaVuSans-2212"/>
- <path d="M 37.796875 64.3125
-L 12.890625 25.390625
-L 37.796875 25.390625
-z
-M 35.203125 72.90625
-L 47.609375 72.90625
-L 47.609375 25.390625
-L 58.015625 25.390625
-L 58.015625 17.1875
-L 47.609375 17.1875
-L 47.609375 0
-L 37.796875 0
-L 37.796875 17.1875
-L 4.890625 17.1875
-L 4.890625 26.703125
-z
-" id="DejaVuSans-34"/>
- </defs>
- <g transform="translate(50.309375 357.551250)scale(0.120000 -0.120000)">
- <use xlink:href="#DejaVuSans-2212"/>
- <use x="83.7890625" xlink:href="#DejaVuSans-34"/>
- </g>
- </g>
- </g>
- <g id="ytick_2">
- <g id="line2d_21">
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="72.0" xlink:href="#m57755297b5" y="285.12"/>
- </g>
- </g>
- <g id="line2d_22">
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="518.4" xlink:href="#mb7f6c3044e" y="285.12"/>
- </g>
- </g>
- <g id="text_4">
- <!-- −2 -->
- <g transform="translate(50.309375 288.431250)scale(0.120000 -0.120000)">
- <use xlink:href="#DejaVuSans-2212"/>
- <use x="83.7890625" xlink:href="#DejaVuSans-32"/>
- </g>
- </g>
- </g>
- <g id="ytick_3">
- <g id="line2d_23">
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="72.0" xlink:href="#m57755297b5" y="216.0"/>
- </g>
- </g>
- <g id="line2d_24">
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="518.4" xlink:href="#mb7f6c3044e" y="216.0"/>
- </g>
- </g>
- <g id="text_5">
- <!-- 0 -->
- <defs>
- <path d="M 31.78125 66.40625
-Q 24.171875 66.40625 20.328125 58.90625
-Q 16.5 51.421875 16.5 36.375
-Q 16.5 21.390625 20.328125 13.890625
-Q 24.171875 6.390625 31.78125 6.390625
-Q 39.453125 6.390625 43.28125 13.890625
-Q 47.125 21.390625 47.125 36.375
-Q 47.125 51.421875 43.28125 58.90625
-Q 39.453125 66.40625 31.78125 66.40625
-M 31.78125 74.21875
-Q 44.046875 74.21875 50.515625 64.515625
-Q 56.984375 54.828125 56.984375 36.375
-Q 56.984375 17.96875 50.515625 8.265625
-Q 44.046875 -1.421875 31.78125 -1.421875
-Q 19.53125 -1.421875 13.0625 8.265625
-Q 6.59375 17.96875 6.59375 36.375
-Q 6.59375 54.828125 13.0625 64.515625
-Q 19.53125 74.21875 31.78125 74.21875
-" id="DejaVuSans-30"/>
- </defs>
- <g transform="translate(60.365000 219.311250)scale(0.120000 -0.120000)">
- <use xlink:href="#DejaVuSans-30"/>
- </g>
- </g>
- </g>
- <g id="ytick_4">
- <g id="line2d_25">
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="72.0" xlink:href="#m57755297b5" y="146.88"/>
- </g>
- </g>
- <g id="line2d_26">
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="518.4" xlink:href="#mb7f6c3044e" y="146.88"/>
- </g>
- </g>
- <g id="text_6">
- <!-- 2 -->
- <g transform="translate(60.365000 150.191250)scale(0.120000 -0.120000)">
- <use xlink:href="#DejaVuSans-32"/>
- </g>
- </g>
- </g>
- <g id="ytick_5">
- <g id="line2d_27">
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="72.0" xlink:href="#m57755297b5" y="77.76"/>
- </g>
- </g>
- <g id="line2d_28">
- <g>
- <use style="stroke:#000000;stroke-width:0.500000;" x="518.4" xlink:href="#mb7f6c3044e" y="77.76"/>
- </g>
- </g>
- <g id="text_7">
- <!-- 4 -->
- <g transform="translate(60.365000 81.071250)scale(0.120000 -0.120000)">
- <use xlink:href="#DejaVuSans-34"/>
- </g>
- </g>
- </g>
- </g>
- </g>
- </g>
- <defs>
- <clipPath id="pc653b2bace">
- <rect height="345.6" width="446.4" x="72.0" y="43.2"/>
- </clipPath>
- </defs>
-</svg>
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/date_timezone_x.png b/lib/matplotlib/tests/baseline_images/test_axes/date_timezone_x.png
new file mode 100644
index 000000000000..aee04d055421
Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/date_timezone_x.png differ
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/date_timezone_x_and_y.png b/lib/matplotlib/tests/baseline_images/test_axes/date_timezone_x_and_y.png
new file mode 100644
index 000000000000..b13dfc53953a
Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/date_timezone_x_and_y.png differ
diff --git a/lib/matplotlib/tests/baseline_images/test_axes/date_timezone_y.png b/lib/matplotlib/tests/baseline_images/test_axes/date_timezone_y.png
new file mode 100644
index 000000000000..be77b5d0c8bc
Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/date_timezone_y.png differ
diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py
index cc71df7c2d7d..3eebc8e97320 100644
--- a/lib/matplotlib/tests/test_axes.py
+++ b/lib/matplotlib/tests/test_axes.py
@@ -11,6 +11,8 @@
import datetime
+import pytz
+
import numpy as np
from numpy import ma
from numpy import arange
@@ -1782,14 +1784,22 @@ def test_boxplot_sym():
ax.set_ylim((-30, 30))
-@image_comparison(baseline_images=['boxplot_autorange_whiskers'])
+@image_comparison(
+ baseline_images=['boxplot_autorange_false_whiskers',
+ 'boxplot_autorange_true_whiskers'],
+ extensions=['png'],
+)
def test_boxplot_autorange_whiskers():
x = np.ones(140)
x = np.hstack([0, x, 2])
- fig, ax = plt.subplots()
-
- ax.boxplot([x, x], bootstrap=10000, notch=1)
- ax.set_ylim((-5, 5))
+
+ fig1, ax1 = plt.subplots()
+ ax1.boxplot([x, x], bootstrap=10000, notch=1)
+ ax1.set_ylim((-5, 5))
+
+ fig2, ax2 = plt.subplots()
+ ax2.boxplot([x, x], bootstrap=10000, notch=1, autorange=True)
+ ax2.set_ylim((-5, 5))
def _rc_test_bxp_helper(ax, rc_dict):
x = np.linspace(-7, 7, 140)
@@ -4330,6 +4340,7 @@ def test_pandas_indexing_hist():
fig, axes = plt.subplots()
axes.hist(ser_2)
+
@cleanup
def test_axis_set_tick_params_labelsize_labelcolor():
# Tests fix for issue 4346
@@ -4342,6 +4353,58 @@ def test_axis_set_tick_params_labelsize_labelcolor():
assert axis_1.yaxis.majorTicks[0]._labelsize == 30.0
assert axis_1.yaxis.majorTicks[0]._labelcolor == 'red'
+
+@image_comparison(baseline_images=['date_timezone_x'], extensions=['png'])
+def test_date_timezone_x():
+ # Tests issue 5575
+ time_index = [pytz.timezone('Canada/Eastern').localize(datetime.datetime(
+ year=2016, month=2, day=22, hour=x)) for x in range(3)]
+
+ # Same Timezone
+ fig = plt.figure(figsize=(20, 12))
+ plt.subplot(2, 1, 1)
+ plt.plot_date(time_index, [3] * 3, tz='Canada/Eastern')
+
+ # Different Timezone
+ plt.subplot(2, 1, 2)
+ plt.plot_date(time_index, [3] * 3, tz='UTC')
+
+
+@image_comparison(baseline_images=['date_timezone_y'],
+ extensions=['png'])
+def test_date_timezone_y():
+ # Tests issue 5575
+ time_index = [pytz.timezone('Canada/Eastern').localize(datetime.datetime(
+ year=2016, month=2, day=22, hour=x)) for x in range(3)]
+
+ # Same Timezone
+ fig = plt.figure(figsize=(20, 12))
+ plt.subplot(2, 1, 1)
+ plt.plot_date([3] * 3,
+ time_index, tz='Canada/Eastern', xdate=False, ydate=True)
+
+ # Different Timezone
+ plt.subplot(2, 1, 2)
+ plt.plot_date([3] * 3, time_index, tz='UTC', xdate=False, ydate=True)
+
+
+@image_comparison(baseline_images=['date_timezone_x_and_y'],
+ extensions=['png'])
+def test_date_timezone_x_and_y():
+ # Tests issue 5575
+ time_index = [pytz.timezone('UTC').localize(datetime.datetime(
+ year=2016, month=2, day=22, hour=x)) for x in range(3)]
+
+ # Same Timezone
+ fig = plt.figure(figsize=(20, 12))
+ plt.subplot(2, 1, 1)
+ plt.plot_date(time_index, time_index, tz='UTC', ydate=True)
+
+ # Different Timezone
+ plt.subplot(2, 1, 2)
+ plt.plot_date(time_index, time_index, tz='US/Eastern', ydate=True)
+
+
if __name__ == '__main__':
import nose
import sys
diff --git a/lib/matplotlib/tests/test_cbook.py b/lib/matplotlib/tests/test_cbook.py
index b7d2e62f1aa5..26d96e6dc97c 100644
--- a/lib/matplotlib/tests/test_cbook.py
+++ b/lib/matplotlib/tests/test_cbook.py
@@ -48,6 +48,14 @@ def test_is_sequence_of_strings():
assert cbook.is_sequence_of_strings(y)
+def test_is_hashable():
+ s = 'string'
+ assert cbook.is_hashable(s)
+
+ lst = ['list', 'of', 'stings']
+ assert not cbook.is_hashable(lst)
+
+
def test_restrict_dict():
d = {'foo': 'bar', 1: 2}
d1 = cbook.restrict_dict(d, ['foo', 1])
@@ -265,6 +273,20 @@ def test_bad_dims(self):
data = np.random.normal(size=(34, 34, 34))
results = cbook.boxplot_stats(data)
+ def test_boxplot_stats_autorange_false(self):
+ x = np.zeros(shape=140)
+ x = np.hstack([-25, x, 25])
+ bstats_false = cbook.boxplot_stats(x, autorange=False)
+ bstats_true = cbook.boxplot_stats(x, autorange=True)
+
+ assert_equal(bstats_false[0]['whislo'], 0)
+ assert_equal(bstats_false[0]['whishi'], 0)
+ assert_array_almost_equal(bstats_false[0]['fliers'], [-25, 25])
+
+ assert_equal(bstats_true[0]['whislo'], -25)
+ assert_equal(bstats_true[0]['whishi'], 25)
+ assert_array_almost_equal(bstats_true[0]['fliers'], [])
+
class Test_callback_registry(object):
def setup(self):
diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py
index 3001147b1841..5bffd9172ff9 100644
--- a/lib/matplotlib/tests/test_collections.py
+++ b/lib/matplotlib/tests/test_collections.py
@@ -11,11 +11,12 @@
from nose.tools import assert_equal
import numpy as np
from numpy.testing import assert_array_equal, assert_array_almost_equal
+from nose.plugins.skip import SkipTest
import matplotlib.pyplot as plt
import matplotlib.collections as mcollections
import matplotlib.transforms as mtransforms
-from matplotlib.collections import EventCollection
+from matplotlib.collections import Collection, EventCollection
from matplotlib.testing.decorators import cleanup, image_comparison
@@ -617,6 +618,27 @@ def test_size_in_xy():
ax.set_ylim(0, 30)
+def test_pandas_indexing():
+ try:
+ import pandas as pd
+ except ImportError:
+ raise SkipTest("Pandas not installed")
+
+ # Should not fail break when faced with a
+ # non-zero indexed series
+ index = [11, 12, 13]
+ ec = fc = pd.Series(['red', 'blue', 'green'], index=index)
+ lw = pd.Series([1, 2, 3], index=index)
+ ls = pd.Series(['solid', 'dashed', 'dashdot'], index=index)
+ aa = pd.Series([True, False, True], index=index)
+
+ Collection(edgecolors=ec)
+ Collection(facecolors=fc)
+ Collection(linewidths=lw)
+ Collection(linestyles=ls)
+ Collection(antialiaseds=aa)
+
+
if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
diff --git a/lib/matplotlib/tests/test_colors.py b/lib/matplotlib/tests/test_colors.py
index 0ac1bceff80a..ec7918db610d 100644
--- a/lib/matplotlib/tests/test_colors.py
+++ b/lib/matplotlib/tests/test_colors.py
@@ -7,8 +7,15 @@
from nose.tools import assert_raises, assert_equal, assert_true
+try:
+ # this is not available in nose + py2.6
+ from nose.tools import assert_sequence_equal
+except ImportError:
+ assert_sequence_equal = None
+
import numpy as np
from numpy.testing.utils import assert_array_equal, assert_array_almost_equal
+from nose.plugins.skip import SkipTest
import matplotlib.colors as mcolors
import matplotlib.cm as cm
@@ -563,6 +570,23 @@ def _azimuth2math(azimuth, elevation):
return theta, phi
+def test_pandas_iterable():
+ try:
+ import pandas as pd
+ except ImportError:
+ raise SkipTest("Pandas not installed")
+ if assert_sequence_equal is None:
+ raise SkipTest("nose lacks required function")
+ # Using a list or series yields equivalent
+ # color maps, i.e the series isn't seen as
+ # a single color
+ lst = ['red', 'blue', 'green']
+ s = pd.Series(lst)
+ cm1 = mcolors.ListedColormap(lst, N=5)
+ cm2 = mcolors.ListedColormap(s, N=5)
+ assert_sequence_equal(cm1.colors, cm2.colors)
+
+
if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)