1 2 3Changes for 0.98.0 4================== 5 6* :func:`matplotlib.image.imread` now no longer always returns RGBA data---if 7 the image is luminance or RGB, it will return a MxN or MxNx3 array 8 if possible. Also uint8 is no longer always forced to float. 9 10* Rewrote the :class:`matplotlib.cm.ScalarMappable` callback 11 infrastructure to use :class:`matplotlib.cbook.CallbackRegistry` 12 rather than custom callback handling. Any users of 13 ``matplotlib.cm.ScalarMappable.add_observer`` of the 14 :class:`~matplotlib.cm.ScalarMappable` should use the 15 :attr:`matplotlib.cm.ScalarMappable.callbacksSM` 16 :class:`~matplotlib.cbook.CallbackRegistry` instead. 17 18* New axes function and Axes method provide control over the plot 19 color cycle: ``matplotlib.axes.set_default_color_cycle`` and 20 ``matplotlib.axes.Axes.set_color_cycle``. 21 22* Matplotlib now requires Python 2.4, so :mod:`matplotlib.cbook` will 23 no longer provide :class:`set`, :func:`enumerate`, :func:`reversed` 24 or ``izip`` compatibility functions. 25 26* In Numpy 1.0, bins are specified by the left edges only. The axes 27 method :meth:`matplotlib.axes.Axes.hist` now uses future Numpy 1.3 28 semantics for histograms. Providing ``binedges``, the last value gives 29 the upper-right edge now, which was implicitly set to +infinity in 30 Numpy 1.0. This also means that the last bin doesn't contain upper 31 outliers any more by default. 32 33* New axes method and pyplot function, 34 :func:`~matplotlib.pyplot.hexbin`, is an alternative to 35 :func:`~matplotlib.pyplot.scatter` for large datasets. It makes 36 something like a :func:`~matplotlib.pyplot.pcolor` of a 2-D 37 histogram, but uses hexagonal bins. 38 39* New kwarg, ``symmetric``, in :class:`matplotlib.ticker.MaxNLocator` 40 allows one require an axis to be centered around zero. 41 42* Toolkits must now be imported from ``mpl_toolkits`` (not ``matplotlib.toolkits``) 43 44Notes about the transforms refactoring 45-------------------------------------- 46 47A major new feature of the 0.98 series is a more flexible and 48extensible transformation infrastructure, written in Python/Numpy 49rather than a custom C extension. 50 51The primary goal of this refactoring was to make it easier to 52extend matplotlib to support new kinds of projections. This is 53mostly an internal improvement, and the possible user-visible 54changes it allows are yet to come. 55 56See :mod:`matplotlib.transforms` for a description of the design of 57the new transformation framework. 58 59For efficiency, many of these functions return views into Numpy 60arrays. This means that if you hold on to a reference to them, 61their contents may change. If you want to store a snapshot of 62their current values, use the Numpy array method copy(). 63 64The view intervals are now stored only in one place -- in the 65:class:`matplotlib.axes.Axes` instance, not in the locator instances 66as well. This means locators must get their limits from their 67:class:`matplotlib.axis.Axis`, which in turn looks up its limits from 68the :class:`~matplotlib.axes.Axes`. If a locator is used temporarily 69and not assigned to an Axis or Axes, (e.g., in 70:mod:`matplotlib.contour`), a dummy axis must be created to store its 71bounds. Call :meth:`matplotlib.ticker.TickHelper.create_dummy_axis` to 72do so. 73 74The functionality of ``Pbox`` has been merged with 75:class:`~matplotlib.transforms.Bbox`. Its methods now all return 76copies rather than modifying in place. 77 78The following lists many of the simple changes necessary to update 79code from the old transformation framework to the new one. In 80particular, methods that return a copy are named with a verb in the 81past tense, whereas methods that alter an object in place are named 82with a verb in the present tense. 83 84:mod:`matplotlib.transforms` 85~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 86 87+--------------------------------------------+------------------------------------------------------+ 88| Old method | New method | 89+============================================+======================================================+ 90| ``Bbox.get_bounds`` | :attr:`.transforms.Bbox.bounds` | 91+--------------------------------------------+------------------------------------------------------+ 92| ``Bbox.width`` | :attr:`transforms.Bbox.width | 93| | <.transforms.BboxBase.width>` | 94+--------------------------------------------+------------------------------------------------------+ 95| ``Bbox.height`` | :attr:`transforms.Bbox.height | 96| | <.transforms.BboxBase.height>` | 97+--------------------------------------------+------------------------------------------------------+ 98| ``Bbox.intervalx().get_bounds()`` | :attr:`.transforms.Bbox.intervalx` | 99| ``Bbox.intervalx().set_bounds()`` | [It is now a property.] | 100+--------------------------------------------+------------------------------------------------------+ 101| ``Bbox.intervaly().get_bounds()`` | :attr:`.transforms.Bbox.intervaly` | 102| ``Bbox.intervaly().set_bounds()`` | [It is now a property.] | 103+--------------------------------------------+------------------------------------------------------+ 104| ``Bbox.xmin`` | :attr:`.transforms.Bbox.x0` or | 105| | :attr:`transforms.Bbox.xmin | 106| | <.transforms.BboxBase.xmin>` [1]_ | 107+--------------------------------------------+------------------------------------------------------+ 108| ``Bbox.ymin`` | :attr:`.transforms.Bbox.y0` or | 109| | :attr:`transforms.Bbox.ymin | 110| | <.transforms.BboxBase.ymin>` [1]_ | 111+--------------------------------------------+------------------------------------------------------+ 112| ``Bbox.xmax`` | :attr:`.transforms.Bbox.x1` or | 113| | :attr:`transforms.Bbox.xmax | 114| | <.transforms.BboxBase.xmax>` [1]_ | 115+--------------------------------------------+------------------------------------------------------+ 116| ``Bbox.ymax`` | :attr:`.transforms.Bbox.y1` or | 117| | :attr:`transforms.Bbox.ymax | 118| | <.transforms.BboxBase.ymax>` [1]_ | 119+--------------------------------------------+------------------------------------------------------+ 120| ``Bbox.overlaps(bboxes)`` | `Bbox.count_overlaps(bboxes) | 121| | <.BboxBase.count_overlaps>` | 122+--------------------------------------------+------------------------------------------------------+ 123| ``bbox_all(bboxes)`` | `Bbox.union(bboxes) <.BboxBase.union>` | 124| | [It is a staticmethod.] | 125+--------------------------------------------+------------------------------------------------------+ 126| ``lbwh_to_bbox(l, b, w, h)`` | `Bbox.from_bounds(x0, y0, w, h) <.Bbox.from_bounds>` | 127| | [It is a staticmethod.] | 128+--------------------------------------------+------------------------------------------------------+ 129| ``inverse_transform_bbox(trans, bbox)`` | `Bbox.inverse_transformed(trans) | 130| | <.BboxBase.inverse_transformed>` | 131+--------------------------------------------+------------------------------------------------------+ 132| ``Interval.contains_open(v)`` | `interval_contains_open(tuple, v) | 133| | <.interval_contains_open>` | 134+--------------------------------------------+------------------------------------------------------+ 135| ``Interval.contains(v)`` | `interval_contains(tuple, v) <.interval_contains>` | 136+--------------------------------------------+------------------------------------------------------+ 137| ``identity_transform()`` | :class:`.transforms.IdentityTransform` | 138+--------------------------------------------+------------------------------------------------------+ 139| ``blend_xy_sep_transform(xtrans, ytrans)`` | `blended_transform_factory(xtrans, ytrans) | 140| | <.blended_transform_factory>` | 141+--------------------------------------------+------------------------------------------------------+ 142| ``scale_transform(xs, ys)`` | `Affine2D().scale(xs[, ys]) <.Affine2D.scale>` | 143+--------------------------------------------+------------------------------------------------------+ 144| ``get_bbox_transform(boxin, boxout)`` | `BboxTransform(boxin, boxout) <.BboxTransform>` or | 145| | `BboxTransformFrom(boxin) <.BboxTransformFrom>` or | 146| | `BboxTransformTo(boxout) <.BboxTransformTo>` | 147+--------------------------------------------+------------------------------------------------------+ 148| ``Transform.seq_xy_tup(points)`` | `Transform.transform(points) <.Transform.transform>` | 149+--------------------------------------------+------------------------------------------------------+ 150| ``Transform.inverse_xy_tup(points)`` | `Transform.inverted() | 151| | <.Transform.inverted>`.transform(points) | 152+--------------------------------------------+------------------------------------------------------+ 153 154.. [1] The :class:`~matplotlib.transforms.Bbox` is bound by the points 155 (x0, y0) to (x1, y1) and there is no defined order to these points, 156 that is, x0 is not necessarily the left edge of the box. To get 157 the left edge of the :class:`.Bbox`, use the read-only property 158 :attr:`xmin <matplotlib.transforms.BboxBase.xmin>`. 159 160:mod:`matplotlib.axes` 161~~~~~~~~~~~~~~~~~~~~~~ 162 163============================= ============================================== 164Old method New method 165============================= ============================================== 166``Axes.get_position()`` :meth:`matplotlib.axes.Axes.get_position` [2]_ 167----------------------------- ---------------------------------------------- 168``Axes.set_position()`` :meth:`matplotlib.axes.Axes.set_position` [3]_ 169----------------------------- ---------------------------------------------- 170``Axes.toggle_log_lineary()`` :meth:`matplotlib.axes.Axes.set_yscale` [4]_ 171----------------------------- ---------------------------------------------- 172``Subplot`` class removed 173============================= ============================================== 174 175The ``Polar`` class has moved to :mod:`matplotlib.projections.polar`. 176 177.. [2] :meth:`matplotlib.axes.Axes.get_position` used to return a list 178 of points, now it returns a :class:`matplotlib.transforms.Bbox` 179 instance. 180 181.. [3] :meth:`matplotlib.axes.Axes.set_position` now accepts either 182 four scalars or a :class:`matplotlib.transforms.Bbox` instance. 183 184.. [4] Since the recfactoring allows for more than two scale types 185 ('log' or 'linear'), it no longer makes sense to have a toggle. 186 ``Axes.toggle_log_lineary()`` has been removed. 187 188:mod:`matplotlib.artist` 189~~~~~~~~~~~~~~~~~~~~~~~~ 190 191============================== ============================================== 192Old method New method 193============================== ============================================== 194``Artist.set_clip_path(path)`` ``Artist.set_clip_path(path, transform)`` [5]_ 195============================== ============================================== 196 197.. [5] :meth:`matplotlib.artist.Artist.set_clip_path` now accepts a 198 :class:`matplotlib.path.Path` instance and a 199 :class:`matplotlib.transforms.Transform` that will be applied to 200 the path immediately before clipping. 201 202:mod:`matplotlib.collections` 203~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 204 205=========== ================= 206Old method New method 207=========== ================= 208*linestyle* *linestyles* [6]_ 209=========== ================= 210 211.. [6] Linestyles are now treated like all other collection 212 attributes, i.e. a single value or multiple values may be 213 provided. 214 215:mod:`matplotlib.colors` 216~~~~~~~~~~~~~~~~~~~~~~~~ 217 218================================== ===================================================== 219Old method New method 220================================== ===================================================== 221``ColorConvertor.to_rgba_list(c)`` ``colors.to_rgba_array(c)`` 222 [:meth:`matplotlib.colors.to_rgba_array` 223 returns an Nx4 NumPy array of RGBA color quadruples.] 224================================== ===================================================== 225 226:mod:`matplotlib.contour` 227~~~~~~~~~~~~~~~~~~~~~~~~~ 228 229===================== =================================================== 230Old method New method 231===================== =================================================== 232``Contour._segments`` ``matplotlib.contour.Contour.get_paths`` [Returns a 233 list of :class:`matplotlib.path.Path` instances.] 234===================== =================================================== 235 236:mod:`matplotlib.figure` 237~~~~~~~~~~~~~~~~~~~~~~~~ 238 239+----------------------+--------------------------------------+ 240| Old method | New method | 241+======================+======================================+ 242| ``Figure.dpi.get()`` | :attr:`matplotlib.figure.Figure.dpi` | 243| ``Figure.dpi.set()`` | *(a property)* | 244+----------------------+--------------------------------------+ 245 246:mod:`matplotlib.patches` 247~~~~~~~~~~~~~~~~~~~~~~~~~ 248 249===================== ==================================================== 250Old method New method 251===================== ==================================================== 252``Patch.get_verts()`` :meth:`matplotlib.patches.Patch.get_path` [Returns a 253 :class:`matplotlib.path.Path` instance] 254===================== ==================================================== 255 256:mod:`matplotlib.backend_bases` 257~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 258 259============================================= ========================================== 260Old method New method 261============================================= ========================================== 262``GraphicsContext.set_clip_rectangle(tuple)`` `GraphicsContext.set_clip_rectangle(bbox) 263 <.GraphicsContextBase.set_clip_rectangle>` 264--------------------------------------------- ------------------------------------------ 265``GraphicsContext.get_clip_path()`` `GraphicsContext.get_clip_path() 266 <.GraphicsContextBase.get_clip_path>` [7]_ 267--------------------------------------------- ------------------------------------------ 268``GraphicsContext.set_clip_path()`` `GraphicsContext.set_clip_path() 269 <.GraphicsContextBase.set_clip_path>` [8]_ 270============================================= ========================================== 271 272.. [7] :meth:`matplotlib.backend_bases.GraphicsContextBase.get_clip_path` 273 returns a tuple of the form (*path*, *affine_transform*), where *path* is a 274 :class:`matplotlib.path.Path` instance and *affine_transform* is a 275 :class:`matplotlib.transforms.Affine2D` instance. 276 277.. [8] :meth:`matplotlib.backend_bases.GraphicsContextBase.set_clip_path` now 278 only accepts a :class:`matplotlib.transforms.TransformedPath` instance. 279 280:class:`~matplotlib.backend_bases.RendererBase` 281~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 282 283New methods: 284 285 * :meth:`draw_path(self, gc, path, transform, rgbFace) 286 <matplotlib.backend_bases.RendererBase.draw_path>` 287 288 * :meth:`draw_markers(self, gc, marker_path, marker_trans, path, 289 trans, rgbFace) 290 <matplotlib.backend_bases.RendererBase.draw_markers>` 291 292 * :meth:`draw_path_collection(self, master_transform, cliprect, 293 clippath, clippath_trans, paths, all_transforms, offsets, 294 offsetTrans, facecolors, edgecolors, linewidths, linestyles, 295 antialiaseds) 296 <matplotlib.backend_bases.RendererBase.draw_path_collection>` 297 *[optional]* 298 299Changed methods: 300 301 * ``draw_image(self, x, y, im, bbox)`` is now 302 :meth:`draw_image(self, x, y, im, bbox, clippath, clippath_trans) 303 <matplotlib.backend_bases.RendererBase.draw_image>` 304 305Removed methods: 306 307 * ``draw_arc`` 308 309 * ``draw_line_collection`` 310 311 * ``draw_line`` 312 313 * ``draw_lines`` 314 315 * ``draw_point`` 316 317 * ``draw_quad_mesh`` 318 319 * ``draw_poly_collection`` 320 321 * ``draw_polygon`` 322 323 * ``draw_rectangle`` 324 325 * ``draw_regpoly_collection`` 326