diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index ce52abc67663..cff5e7f70dfc 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -1,5 +1,5 @@ """ -This is an object-orient plotting library. +This is an object-oriented plotting library. A procedural interface is provided by the companion pyplot module, which may be imported directly, e.g:: @@ -99,7 +99,7 @@ """ from __future__ import print_function -__version__ = '1.2.0rc1' +__version__ = '1.3.x' __version__numpy__ = '1.4' # minimum required numpy version import os, re, shutil, subprocess, sys, warnings diff --git a/lib/matplotlib/backends/backend_qt4.py b/lib/matplotlib/backends/backend_qt4.py index 6c22bbb92e25..60a6cd560586 100644 --- a/lib/matplotlib/backends/backend_qt4.py +++ b/lib/matplotlib/backends/backend_qt4.py @@ -501,6 +501,9 @@ def __init__(self, canvas, parent, coordinates=True): """ coordinates: should we show the coordinates on the right? """ self.canvas = canvas self.coordinates = coordinates + self._actions = {} + """A mapping of toolitem method names to their QActions""" + QtGui.QToolBar.__init__( self, parent ) NavigationToolbar2.__init__( self, canvas ) @@ -516,6 +519,9 @@ def _init_toolbar(self): else: a = self.addAction(self._icon(image_file + '.png'), text, getattr(self, callback)) + self._actions[callback] = a + if callback in ['zoom', 'pan']: + a.setCheckable(True) if tooltip_text is not None: a.setToolTip(tooltip_text) @@ -574,6 +580,18 @@ def edit_parameters(self): figureoptions.figure_edit(axes, self) + def _update_buttons_checked(self): + #sync button checkstates to match active mode + self._actions['pan'].setChecked(self._active == 'PAN') + self._actions['zoom'].setChecked(self._active == 'ZOOM') + + def pan(self, *args): + super(NavigationToolbar2QT, self).pan(*args) + self._update_buttons_checked() + + def zoom(self, *args): + super(NavigationToolbar2QT, self).zoom(*args) + self._update_buttons_checked() def dynamic_update( self ): self.canvas.draw() diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index 595147ff0ad3..48472d887ddc 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -1246,7 +1246,7 @@ def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, If *format* is *None* and *fname* is a string, the output format is deduced from the extension of the filename. *arr*: - A 2D array. + An MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA) array. Keyword arguments: *vmin*/*vmax*: [ None | scalar ] *vmin* and *vmax* set the color scaling for the image by fixing the @@ -1269,7 +1269,7 @@ def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None, from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from matplotlib.figure import Figure - figsize = [x / float(dpi) for x in arr.shape[::-1]] + figsize = [x / float(dpi) for x in (arr.shape[1], arr.shape[0])] fig = Figure(figsize=figsize, dpi=dpi, frameon=False) canvas = FigureCanvas(fig) im = fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin) diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index 587fd94c5618..f06192534581 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -128,6 +128,26 @@ def test_imsave(): assert_array_equal(arr_dpi1, arr_dpi100) +def test_imsave_color_alpha(): + # The goal is to test that imsave will accept arrays with ndim=3 where + # the third dimension is color and alpha without raising any exceptions + from numpy import random + random.seed(1) + data = random.rand(256, 128, 4) + + buff = io.BytesIO() + plt.imsave(buff, data) + + buff.seek(0) + arr_buf = plt.imread(buff) + + assert arr_buf.shape == data.shape + + # Unfortunately, the AGG process "flattens" the RGBA data + # into an equivalent RGB data with no transparency. So we + # Can't directly compare the arrays like we could in some + # other imsave tests. + @image_comparison(baseline_images=['image_clip']) def test_image_clip(): from math import pi diff --git a/lib/six.py b/lib/six.py index 6bee4a99252e..34f737fb3db0 100644 --- a/lib/six.py +++ b/lib/six.py @@ -5,7 +5,7 @@ import types __author__ = "Benjamin Peterson " -__version__ = "1.1.0-mpl" +__version__ = "1.2.0-mpl" # True if we are running on Python 3. @@ -26,19 +26,23 @@ text_type = unicode binary_type = str - # It's possible to have sizeof(long) != sizeof(Py_ssize_t). - class X(object): - def __len__(self): - return 1 << 31 - try: - len(X()) - except OverflowError: - # 32-bit + if sys.platform == "java": + # Jython always uses 32 bits. MAXSIZE = int((1 << 31) - 1) else: - # 64-bit - MAXSIZE = int((1 << 63) - 1) - del X + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X def _add_doc(func, doc): @@ -113,6 +117,7 @@ class _MovedItems(types.ModuleType): _moved_attributes = [ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), MovedAttribute("map", "itertools", "builtins", "imap", "map"), MovedAttribute("reload_module", "__builtin__", "imp", "reload"), MovedAttribute("reduce", "__builtin__", "functools"), @@ -200,12 +205,19 @@ def remove_move(name): _iteritems = "iteritems" +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + if PY3: def get_unbound_function(unbound): return unbound - - advance_iterator = next + Iterator = object def callable(obj): return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) @@ -213,9 +225,10 @@ def callable(obj): def get_unbound_function(unbound): return unbound.im_func + class Iterator(object): - def advance_iterator(it): - return it.next() + def next(self): + return type(self).__next__(self) callable = callable _add_doc(get_unbound_function, @@ -230,15 +243,15 @@ def advance_iterator(it): def iterkeys(d): """Return an iterator over the keys of a dictionary.""" - return getattr(d, _iterkeys)() + return iter(getattr(d, _iterkeys)()) def itervalues(d): """Return an iterator over the values of a dictionary.""" - return getattr(d, _itervalues)() + return iter(getattr(d, _itervalues)()) def iteritems(d): """Return an iterator over the (key, value) pairs of a dictionary.""" - return getattr(d, _iteritems)() + return iter(getattr(d, _iteritems)()) if PY3: