You can subscribe to this list here.
| 2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(115) |
Aug
(120) |
Sep
(137) |
Oct
(170) |
Nov
(461) |
Dec
(263) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2008 |
Jan
(120) |
Feb
(74) |
Mar
(35) |
Apr
(74) |
May
(245) |
Jun
(356) |
Jul
(240) |
Aug
(115) |
Sep
(78) |
Oct
(225) |
Nov
(98) |
Dec
(271) |
| 2009 |
Jan
(132) |
Feb
(84) |
Mar
(74) |
Apr
(56) |
May
(90) |
Jun
(79) |
Jul
(83) |
Aug
(296) |
Sep
(214) |
Oct
(76) |
Nov
(82) |
Dec
(66) |
| 2010 |
Jan
(46) |
Feb
(58) |
Mar
(51) |
Apr
(77) |
May
(58) |
Jun
(126) |
Jul
(128) |
Aug
(64) |
Sep
(50) |
Oct
(44) |
Nov
(48) |
Dec
(54) |
| 2011 |
Jan
(68) |
Feb
(52) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <lee...@us...> - 2009-04-24 15:24:02
|
Revision: 7062
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7062&view=rev
Author: leejjoon
Date: 2009-04-24 15:23:57 +0000 (Fri, 24 Apr 2009)
Log Message:
-----------
axes_grid minor update.
Modified Paths:
--------------
trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_rgb.py
Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py 2009-04-23 14:22:27 UTC (rev 7061)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py 2009-04-24 15:23:57 UTC (rev 7062)
@@ -2,7 +2,7 @@
AxesGrid
"""
-
+import axes_size as Size
from axes_divider import Divider, SubplotDivider, LocatableAxes, \
make_axes_locatable
from axes_grid import AxesGrid
Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_rgb.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_rgb.py 2009-04-23 14:22:27 UTC (rev 7061)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_rgb.py 2009-04-24 15:23:57 UTC (rev 7062)
@@ -8,12 +8,10 @@
divider = make_axes_locatable(ax)
- pad_size = Size.Fraction(Size.AxesY(ax), pad)
+ pad_size = Size.Fraction(pad, Size.AxesY(ax))
- xsize = Size.Fraction((1.-2.*pad)/3.,
- Size.AxesX(ax),)
- ysize = Size.Fraction((1.-2.*pad)/3.,
- Size.AxesY(ax))
+ xsize = Size.Fraction(Size.AxesX(ax), (1.-2.*pad)/3.)
+ ysize = Size.Fraction(Size.AxesY(ax), (1.-2.*pad)/3.)
divider.set_horizontal([Size.AxesX(ax), pad_size, xsize])
divider.set_vertical([ysize, pad_size, ysize, pad_size, ysize])
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2009-04-23 14:22:37
|
Revision: 7061
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7061&view=rev
Author: mdboom
Date: 2009-04-23 14:22:27 +0000 (Thu, 23 Apr 2009)
Log Message:
-----------
Fix theoretical memory leak.
Modified Paths:
--------------
trunk/matplotlib/src/cntr.c
Modified: trunk/matplotlib/src/cntr.c
===================================================================
--- trunk/matplotlib/src/cntr.c 2009-04-23 14:22:11 UTC (rev 7060)
+++ trunk/matplotlib/src/cntr.c 2009-04-23 14:22:27 UTC (rev 7061)
@@ -1410,7 +1410,7 @@
PyObject *
cntr_trace(Csite *site, double levels[], int nlevels, int points, long nchunk)
{
- PyObject *c_list;
+ PyObject *c_list = NULL;
double *xp0;
double *yp0;
long *nseg0;
@@ -1502,6 +1502,7 @@
error:
PyMem_Free(xp0); PyMem_Free(yp0); PyMem_Free(nseg0);
site->xcp = NULL; site->ycp = NULL;
+ Py_XDECREF(c_list);
return NULL;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2009-04-23 14:22:15
|
Revision: 7060
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7060&view=rev
Author: mdboom
Date: 2009-04-23 14:22:11 +0000 (Thu, 23 Apr 2009)
Log Message:
-----------
Fix theoretical memory leak.
Modified Paths:
--------------
trunk/matplotlib/src/agg_py_path_iterator.h
Modified: trunk/matplotlib/src/agg_py_path_iterator.h
===================================================================
--- trunk/matplotlib/src/agg_py_path_iterator.h 2009-04-23 14:21:52 UTC (rev 7059)
+++ trunk/matplotlib/src/agg_py_path_iterator.h 2009-04-23 14:22:11 UTC (rev 7060)
@@ -52,6 +52,8 @@
if (!m_vertices ||
PyArray_DIM(m_vertices, 1) != 2)
{
+ Py_XDECREF(m_vertices);
+ m_vertices = NULL;
throw Py::ValueError("Invalid vertices array.");
}
@@ -59,10 +61,18 @@
{
m_codes = (PyArrayObject*)PyArray_FromObject
(codes_obj.ptr(), PyArray_UINT8, 1, 1);
- if (!m_codes)
+ if (!m_codes) {
+ Py_XDECREF(m_vertices);
+ m_vertices = NULL;
throw Py::ValueError("Invalid codes array.");
- if (PyArray_DIM(m_codes, 0) != PyArray_DIM(m_vertices, 0))
+ }
+ if (PyArray_DIM(m_codes, 0) != PyArray_DIM(m_vertices, 0)) {
+ Py_XDECREF(m_vertices);
+ m_vertices = NULL;
+ Py_XDECREF(m_codes);
+ m_codes = NULL;
throw Py::ValueError("Codes array is wrong length");
+ }
}
m_should_simplify = should_simplify_obj.isTrue();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2009-04-23 14:21:56
|
Revision: 7059
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7059&view=rev
Author: mdboom
Date: 2009-04-23 14:21:52 +0000 (Thu, 23 Apr 2009)
Log Message:
-----------
Fix theoretical memory leak.
Modified Paths:
--------------
trunk/matplotlib/src/_path.cpp
Modified: trunk/matplotlib/src/_path.cpp
===================================================================
--- trunk/matplotlib/src/_path.cpp 2009-04-23 14:21:38 UTC (rev 7058)
+++ trunk/matplotlib/src/_path.cpp 2009-04-23 14:21:52 UTC (rev 7059)
@@ -569,6 +569,7 @@
(PyArray_NDIM(offsets) == 2 && PyArray_DIM(offsets, 1) != 2) ||
(PyArray_NDIM(offsets) == 1 && PyArray_DIM(offsets, 0) != 0))
{
+ Py_XDECREF(offsets);
throw Py::ValueError("Offsets array must be Nx2");
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2009-04-23 14:21:49
|
Revision: 7058
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7058&view=rev
Author: mdboom
Date: 2009-04-23 14:21:38 +0000 (Thu, 23 Apr 2009)
Log Message:
-----------
Fix some uninitialized variable errors in valgrind.
Modified Paths:
--------------
trunk/matplotlib/src/path_converters.h
Modified: trunk/matplotlib/src/path_converters.h
===================================================================
--- trunk/matplotlib/src/path_converters.h 2009-04-23 14:20:27 UTC (rev 7057)
+++ trunk/matplotlib/src/path_converters.h 2009-04-23 14:21:38 UTC (rev 7058)
@@ -270,7 +270,8 @@
PathClipper(VertexSource& source, bool do_clipping,
double width, double height) :
m_source(&source), m_do_clipping(do_clipping),
- m_cliprect(0.0, 0.0, width, height), m_moveto(true)
+ m_cliprect(0.0, 0.0, width, height), m_moveto(true),
+ m_has_next(false)
{
// empty
}
@@ -278,7 +279,7 @@
PathClipper(VertexSource& source, bool do_clipping,
const agg::rect_base<double>& rect) :
m_source(&source), m_do_clipping(do_clipping),
- m_cliprect(rect), m_moveto(true)
+ m_cliprect(rect), m_moveto(true), m_has_next(false)
{
// empty
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <md...@us...> - 2009-04-23 14:20:38
|
Revision: 7057
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7057&view=rev
Author: mdboom
Date: 2009-04-23 14:20:27 +0000 (Thu, 23 Apr 2009)
Log Message:
-----------
Fix clipping of images in PS backend.
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backends/backend_ps.py
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_ps.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-04-21 03:12:53 UTC (rev 7056)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_ps.py 2009-04-23 14:20:27 UTC (rev 7057)
@@ -428,8 +428,8 @@
ps = []
last_points = None
if clip:
- clip = (0.0, 0.0, self.width * self.imagedpi,
- self.height * self.imagedpi)
+ clip = (0.0, 0.0, self.width * 72.0,
+ self.height * 72.0)
else:
clip = None
for points, code in path.iter_segments(transform, clip=clip):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2009-04-21 03:13:09
|
Revision: 7056
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7056&view=rev
Author: leejjoon
Date: 2009-04-21 03:12:53 +0000 (Tue, 21 Apr 2009)
Log Message:
-----------
Added axes_grid.inset_locator
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst
trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axes_divider.rst
trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst
trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst
trunk/matplotlib/examples/axes_grid/simple_axes_divider2.py
trunk/matplotlib/examples/axes_grid/simple_axes_divider3.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_grid.py
Added Paths:
-----------
trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/
trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_divider_api.rst
trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_grid_api.rst
trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_size_api.rst
trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/index.rst
trunk/matplotlib/examples/axes_grid/inset_locator_demo.py
trunk/matplotlib/examples/axes_grid/inset_locator_demo2.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_size.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/inset_locator.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-04-19 14:29:07 UTC (rev 7055)
+++ trunk/matplotlib/CHANGELOG 2009-04-21 03:12:53 UTC (rev 7056)
@@ -1,5 +1,8 @@
======================================================================
+2009-04-20 Worked on axes_grid documentation. Added
+ axes_grid.inset_locator. - JJL
+
2009-04-17 Initial check-in of the axes_grid toolkit. - JJL
2009-04-17 Added a support for bbox_to_anchor in
Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_divider_api.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_divider_api.rst (rev 0)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_divider_api.rst 2009-04-21 03:12:53 UTC (rev 7056)
@@ -0,0 +1,18 @@
+
+:mod:`mpl_toolkits.axes_grid.axes_divider`
+==========================================
+
+.. autoclass:: mpl_toolkits.axes_grid.axes_divider.Divider
+ :members:
+ :undoc-members:
+
+
+.. autoclass:: mpl_toolkits.axes_grid.axes_divider.AxesLocator
+ :members:
+ :undoc-members:
+
+.. autoclass:: mpl_toolkits.axes_grid.axes_divider.SubplotDivider
+ :members:
+
+.. autoclass:: mpl_toolkits.axes_grid.axes_divider.AxesDivider
+ :members:
Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_grid_api.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_grid_api.rst (rev 0)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_grid_api.rst 2009-04-21 03:12:53 UTC (rev 7056)
@@ -0,0 +1,7 @@
+
+:mod:`mpl_toolkits.axes_grid.axes_grid`
+=======================================
+
+.. autoclass:: mpl_toolkits.axes_grid.axes_grid.AxesGrid
+ :members:
+ :undoc-members:
Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_size_api.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_size_api.rst (rev 0)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/axes_size_api.rst 2009-04-21 03:12:53 UTC (rev 7056)
@@ -0,0 +1,6 @@
+:mod:`mpl_toolkits.axes_grid.axes_size`
+=======================================
+
+.. automodule:: mpl_toolkits.axes_grid.axes_size
+ :members: Fixed, Scaled, AxesX, AxesY, MaxWidth, MaxHeight, Fraction, Padded, from_any
+
Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/index.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/index.rst (rev 0)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/api/index.rst 2009-04-21 03:12:53 UTC (rev 7056)
@@ -0,0 +1,14 @@
+.. _axes_grid-api-index:
+
+#######################################
+ The Matplotlib AxesGrid Toolkit API
+#######################################
+
+:Release: |version|
+:Date: |today|
+
+.. toctree::
+
+ axes_size_api.rst
+ axes_divider_api.rst
+ axes_grid_api.rst
Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst 2009-04-19 14:29:07 UTC (rev 7055)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst 2009-04-21 03:12:53 UTC (rev 7056)
@@ -10,7 +10,6 @@
AxesGrid toolkit provides a framework to adjust the position of
multiple axes according to their aspects.
-.. plot:: mpl_toolkits/axes_grid/figures/demo_axes_grid.py
Documentation
@@ -20,4 +19,4 @@
:maxdepth: 2
users/index.rst
-
+ api/index.rst
Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axes_divider.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axes_divider.rst 2009-04-19 14:29:07 UTC (rev 7055)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axes_divider.rst 2009-04-21 03:12:53 UTC (rev 7056)
@@ -4,15 +4,17 @@
The axes_divider module provide helper classes to adjust the axes
positions of set of images in the drawing time.
-* *Size* This provides a classese of units that the size of each axes
- will be determined. For example, you can specify a fixed size
+* :mod:`~mpl_toolkits.axes_grid.axes_size` provides a classese of
+ units that the size of each axes will be determined. For example,
+ you can specify a fixed size
-* *Divider* this is the class that is used calculates the axes
- position. It divides the given renctangular area into several
- areas. You intialize the divider by setting the horizontal and
- vertical list of sizes that the division will be based on. You then
- use the new_locator method, whose return value is a callable object
- that can be used to set the axes_locator of the axes.
+* :class:`~mpl_toolkits.axes_grid.axes_size.Divider` this is the class
+ that is used calculates the axes position. It divides the given
+ renctangular area into several areas. You intialize the divider by
+ setting the horizontal and vertical list of sizes that the division
+ will be based on. You then use the new_locator method, whose return
+ value is a callable object that can be used to set the axes_locator
+ of the axes.
You first initialize the divider by specifying its grids, i.e., horiz and vert.
@@ -25,10 +27,11 @@
divider = Divider(fig, rect, horiz, vert)
where, rect is a bounds of the box that will be divided and h0,..h3,
-v0,..v2 need to be an callable object that returns a tuple of two
-floats. The first float is the relative size, and the second float is
-the absolute size. Use of the subclasses contained in the Size class
-is recommanded. Lets' consider a following grid.
+v0,..v2 need to be an instance of classes in the
+:mod:`~mpl_toolkits.axes_grid.axes_size`. They have *get_size* method
+that returns a tuple of two floats. The first float is the relative
+size, and the second float is the absolute size. Consider a following
+grid.
+-----+-----+-----+-----+
| v0 | | | |
@@ -39,34 +42,34 @@
+-----+-----+-----+-----+
-* h0 => 2, 0
-* h1 => 0, 2
-* h2 => 0, 3
+* v0 => 0, 2
+* v1 => 2, 0
+* v2 => 3, 0
The height of the bottom row is always 2 (axes_divider internally
assumes that the unit is inch). The first and the second rows with
-height ration of 2:3. For example, if the total height of the grid 6,
-the the first and second row will each occupy 2/(2+3) and 3/(2+3) of
+height ratio of 2:3. For example, if the total height of the grid 6,
+then the first and second row will each occupy 2/(2+3) and 3/(2+3) of
(6-1) inches. The widths of columns (horiz) will be similarly
determined. When aspect ratio is set, the total height (or width) will
be adjusted accordingly.
-The Size class is a container class that contains several sub-class
+The :mod:`mpl_toolkits.axes_grid.axes_size` contains several classes
that can be used to set the horiz and vert. For example, for the
vertical configuration above will be::
- from Size import Fixed, Scaled
+ from mpl_toolkits.axes_grid.axes_size import Fixed, Scaled
vert = [Fixed(2), Scaled(2), Scaled(3)]
-After you set up the divider object, you
-Then you create a locator instance which will be given to the axes.::
+After you set up the divider object, then you create a locator
+instance which will be given to the axes.::
locator = divider.new_locator(nx=0, ny=1)
ax.set_axes_locator(locator)
The return value of the new_locator method is a instance of the
-AxesLocator class. It is a callable object that will return the
+AxesLocator class. It is a callable object that returns the
location and size of the cell at the first column and the second row.
You may create a locator that spans over multiple cells.::
Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst 2009-04-19 14:29:07 UTC (rev 7055)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst 2009-04-21 03:12:53 UTC (rev 7056)
@@ -10,3 +10,4 @@
.. toctree::
overview.rst
+ axes_divider.rst
Modified: trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst 2009-04-19 14:29:07 UTC (rev 7055)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst 2009-04-21 03:12:53 UTC (rev 7056)
@@ -1,6 +1,6 @@
-=================
-AxesGrid Overview
-=================
+========
+Overview
+========
The matplotlib AxesGrid toolkit is a collection of helper classes,
mainly to ease displaying (multiple) images in matplotlib.
@@ -347,3 +347,44 @@
:include-source:
+InsetLocator
+============
+
+:mod:`mpl_toolkits.axes_grid.inset_locator` provides helper classes
+and functions to place your (inset) axes at the anchored position of
+the parent axes, similarly to AnchoredArtis.
+
+Using :func:`mpl_toolkits.axes_grid.inset_locator.inset_axes`, you
+can have inset axes whose size is either fixed, or a fixed proportion
+of the parent axes. For example,::
+
+ inset_axes = inset_axes(parent_axes,
+ width="30%", # width = 30% of parent_bbox
+ height=1., # height : 1 inch
+ loc=3)
+
+creates an inset axes whose width is 30% of the parent axes and whose
+height is fixed at 1 inch.
+
+You may creates your inset whose size is determined so that the data
+scale of the inset axes to be that of the parent axes multiplied by
+some factor. For example, ::
+
+ inset_axes = zoomed_inset_axes(ax,
+ 0.5, # zoom = 0.5
+ loc=1)
+
+creates an inset axes whose data scale is half of the parent axes.
+Here is complete examples.
+
+.. plot:: mpl_toolkits/axes_grid/figures/inset_locator_demo.py
+
+For example, :func:`zoomed_inset_axes` can be used when you want the
+inset represents the zoom-up of the small portion in the parent axes.
+And :mod:`~mpl_toolkits/axes_grid/inset_locator` provides a helper
+function :func:`mark_inset` to mark the location of the area
+represented by the inset axes.
+
+.. plot:: mpl_toolkits/axes_grid/figures/inset_locator_demo2.py
+ :include-source:
+
Added: trunk/matplotlib/examples/axes_grid/inset_locator_demo.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/inset_locator_demo.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/inset_locator_demo.py 2009-04-21 03:12:53 UTC (rev 7056)
@@ -0,0 +1,45 @@
+import matplotlib.pyplot as plt
+
+from mpl_toolkits.axes_grid.inset_locator import inset_axes, zoomed_inset_axes
+from mpl_toolkits.axes_grid.anchored_artists import AnchoredSizeBar
+
+
+def add_sizebar(ax, size):
+ as = AnchoredSizeBar(ax.transData,
+ size,
+ str(size),
+ loc=8,
+ pad=0.1, borderpad=0.5, sep=5,
+ frameon=False)
+ ax.add_artist(as)
+
+
+fig = plt.figure(1, [5.5, 3])
+
+# first subplot
+ax = fig.add_subplot(1,2,1)
+ax.set_aspect(1.)
+
+axins = inset_axes(ax,
+ width="30%", # width = 30% of parent_bbox
+ height=1., # height : 1 inch
+ loc=3)
+
+plt.xticks(visible=False)
+plt.yticks(visible=False)
+
+
+# second subplot
+ax = fig.add_subplot(1,2,2)
+ax.set_aspect(1.)
+
+axins = zoomed_inset_axes(ax, 0.5, loc=1) # zoom = 0.5
+
+plt.xticks(visible=False)
+plt.yticks(visible=False)
+
+add_sizebar(ax, 0.5)
+add_sizebar(axins, 0.5)
+
+plt.draw()
+plt.show()
Added: trunk/matplotlib/examples/axes_grid/inset_locator_demo2.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/inset_locator_demo2.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/inset_locator_demo2.py 2009-04-21 03:12:53 UTC (rev 7056)
@@ -0,0 +1,42 @@
+import matplotlib.pyplot as plt
+
+from mpl_toolkits.axes_grid.inset_locator import zoomed_inset_axes
+from mpl_toolkits.axes_grid.inset_locator import mark_inset
+
+import numpy as np
+
+from demo_image import get_demo_image
+
+
+fig = plt.figure(1, [5,4])
+ax = fig.add_subplot(111)
+
+# prepare the demo image
+Z, extent = get_demo_image()
+Z2 = np.zeros([150, 150], dtype="d")
+ny, nx = Z.shape
+Z2[30:30+ny, 30:30+nx] = Z
+
+# extent = [-3, 4, -4, 3]
+ax.imshow(Z2, extent=extent, interpolation="nearest",
+ origin="lower")
+
+axins = zoomed_inset_axes(ax, 6, loc=1) # zoom = 6
+axins.imshow(Z2, extent=extent, interpolation="nearest",
+ origin="lower")
+
+# sub region of the original image
+x1, x2, y1, y2 = -1.5, -0.9, -2.5, -1.9
+axins.set_xlim(x1, x2)
+axins.set_ylim(y1, y2)
+
+plt.xticks(visible=False)
+plt.yticks(visible=False)
+
+# draw a bbox of the region of the inset axes in the parent axes and
+# connecting lines between the bbox and the inset axes area
+mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5")
+
+plt.draw()
+plt.show()
+
Modified: trunk/matplotlib/examples/axes_grid/simple_axes_divider2.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axes_divider2.py 2009-04-19 14:29:07 UTC (rev 7055)
+++ trunk/matplotlib/examples/axes_grid/simple_axes_divider2.py 2009-04-21 03:12:53 UTC (rev 7056)
@@ -1,4 +1,5 @@
-from mpl_toolkits.axes_grid import Size, Divider
+import mpl_toolkits.axes_grid.axes_size as Size
+from mpl_toolkits.axes_grid import Divider
import matplotlib.pyplot as plt
fig1 = plt.figure(1, (5.5, 4.))
Modified: trunk/matplotlib/examples/axes_grid/simple_axes_divider3.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axes_divider3.py 2009-04-19 14:29:07 UTC (rev 7055)
+++ trunk/matplotlib/examples/axes_grid/simple_axes_divider3.py 2009-04-21 03:12:53 UTC (rev 7056)
@@ -1,4 +1,5 @@
-from mpl_toolkits.axes_grid import Size, Divider
+import mpl_toolkits.axes_grid.axes_size as Size
+from mpl_toolkits.axes_grid import Divider
import matplotlib.pyplot as plt
Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py 2009-04-19 14:29:07 UTC (rev 7055)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py 2009-04-21 03:12:53 UTC (rev 7056)
@@ -3,7 +3,8 @@
"""
-from axes_divider import Divider, SubplotDivider, LocatableAxes, Size, \
+from axes_divider import Divider, SubplotDivider, LocatableAxes, \
make_axes_locatable
from axes_grid import AxesGrid
+#from axes_divider import make_axes_locatable
Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py 2009-04-19 14:29:07 UTC (rev 7055)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py 2009-04-21 03:12:53 UTC (rev 7056)
@@ -1,189 +1,56 @@
"""
-The axes_divider module provide helper classes to adjust the axes
-positions of set of images in the drawing time.
+The axes_divider module provide helper classes to adjust the positions of
+multiple axes at the drawing time.
- Size: This provides a classese of units that the size of each axes
- will be determined. For example, you can specify a fixed size
-
- Divider: this is the class that uis used calculates the axes
- position. It divides the given renctangular area into several
- areas. You intialize the divider by setting the horizontal and
- vertical list of sizes that the division will be based on. You
+ Divider: this is the class that is used calculates the axes
+ position. It divides the given renctangular area into several sub
+ rectangles. You intialize the divider by setting the horizontal
+ and vertical list of sizes that the division will be based on. You
then use the new_locator method, whose return value is a callable
object that can be used to set the axes_locator of the axes.
"""
-import matplotlib.axes as maxes
import matplotlib.transforms as mtransforms
-import matplotlib.cbook as cbook
from matplotlib.axes import SubplotBase
import new
+import axes_size as Size
-class Size(object):
- """
- provides a classese of units that will be used with AxesDivider
- class (or others) to determine the size of each axes. The unit
- classes define __call__ that returns a tuple of two floats,
- meaning relative and absolute sizes, respectively.
- Note that this class is nothing more than a simple tuple of two
- floats. Take a look at the Divider class to see how these two
- values are used.
-
+class Divider(object):
"""
+ This is the class that is used calculates the axes position. It
+ divides the given renctangular area into several
+ sub-rectangles. You intialize the divider by setting the
+ horizontal and vertical lists of sizes
+ (:mod:`mpl_toolkits.axes_grid.axes_size`) that the division will
+ be based on. You then use the new_locator method to create a
+ callable object that can be used to as the axes_locator of the
+ axes.
+ """
- class _Base(object):
- "Base class"
- pass
-
- class Fixed(_Base):
- "Simple fixed size with relative part = 0"
- def __init__(self, fixed_size):
- self._fixed_size = fixed_size
-
- def get_size(self, renderer):
- rel_size = 0.
- abs_size = self._fixed_size
- return rel_size, abs_size
-
- class Scaled(_Base):
- "Simple scaled(?) size with absolute part = 0"
- def __init__(self, scalable_size):
- self._scalable_size = scalable_size
-
- def get_size(self, renderer):
- rel_size = self._scalable_size
- abs_size = 0.
- return rel_size, abs_size
-
- Scalable=Scaled
-
- class AxesX(_Base):
+
+ def __init__(self, fig, pos, horizontal, vertical, aspect=None, anchor="C"):
"""
- Scaled size whose relative part corresponds to the data width
- of the given axes
+ :param fig: matplotlib figure
+ :param pos: position (tuple of 4 floats) of the rectangle that
+ will be divided.
+ :param horizontal: list of sizes
+ (:mod:`~mpl_toolkits.axes_grid.axes_size`)
+ for horizontal division
+ :param vertical: list of sizes
+ (:mod:`~mpl_toolkits.axes_grid.axes_size`)
+ for vertical division
+ :param aspect: if True, the overall rectalngular area is reduced
+ so that the relative part of the horizontal and
+ vertical scales have same scale.
+ :param anchor: Detrmine how the reduced rectangle is placed
+ when aspect is True,
"""
- def __init__(self, axes, aspect=1.):
- self._axes = axes
- self._aspect = aspect
-
- def get_size(self, renderer):
- l1, l2 = self._axes.get_xlim()
- rel_size = abs(l2-l1)*self._aspect
- abs_size = 0.
- return rel_size, abs_size
-
- class AxesY(_Base):
- """
- Scaled size whose relative part corresponds to the data height
- of the given axes
- """
- def __init__(self, axes, aspect=1.):
- self._axes = axes
- self._aspect = aspect
-
- def get_size(self, renderer):
- l1, l2 = self._axes.get_ylim()
- rel_size = abs(l2-l1)*self._aspect
- abs_size = 0.
- return rel_size, abs_size
-
-
- class MaxExtent(_Base):
- """
- Size whose absolute part is the largest width (or height) of
- the given list of artists.
- """
- def __init__(self, artist_list, w_or_h):
- self._artist_list = artist_list
-
- if w_or_h not in ["width", "height"]:
- raise ValueError()
-
- self._w_or_h = w_or_h
-
- def add_artist(self, a):
- self._artist_list.append(a)
-
- def get_size(self, renderer):
- rel_size = 0.
- w_list, h_list = [], []
- for a in self._artist_list:
- bb = a.get_window_extent(renderer)
- w_list.append(bb.width)
- h_list.append(bb.height)
- dpi = a.get_figure().get_dpi()
- if self._w_or_h == "width":
- abs_size = max(w_list)/dpi
- elif self._w_or_h == "height":
- abs_size = max(h_list)/dpi
-
- return rel_size, abs_size
-
- class Fraction(_Base):
- """
- An instance whose size is a fraction of the reference size.
- ex) s = Fraction(0.3, AxesX(ax))
- """
- def __init__(self, fraction, fraction_ref):
- self._fraction_ref = fraction_ref
- self._fraction = fraction
-
- def get_size(self, renderer):
- if self._fraction_ref is None:
- return self._fraction, 0.
- else:
- r, a = self._fraction_ref.get_size(renderer)
- rel_size = r*self._fraction
- abs_size = a*self._fraction
- return rel_size, abs_size
-
- @classmethod
- def from_any(self, size, fraction_ref=None):
- """
- Creates Fixed unit when the first argument is a float, or a
- Fraction unit if that is a string that ends with %. The second
- argument is only meaningful when Fraction unit is created.
-
- >>> a = Size.from_any(1.2) # => Size.Fixed(1.2)
- >>> Size.from_any("50%", a) # => Size.Fraction(0.5, a)
-
- """
- if cbook.is_numlike(size):
- return Size.Fixed(size)
- elif cbook.is_string_like(size):
- if size[-1] == "%":
- return Size.Fraction(float(size[:-1])/100., fraction_ref)
-
- raise ValueError("Unknown format")
-
-
-
- class Padded(_Base):
- """
- Return a instance where the absolute part of *size* is
- increase by the amount of *pad*.
- """
- def __init__(self, size, pad):
- self._size = size
- self._pad = pad
-
- def get_size(self, renderer):
- r, a = self._size.get_size(renderer)
- rel_size = r
- abs_size = a + self._pad
- return rel_size, abs_size
-
-
-
-
-class Divider(object):
-
- def __init__(self, fig, pos, horizontal, vertical, aspect=None, anchor="C"):
+
self._fig = fig
self._pos = pos
self._horizontal = horizontal
@@ -224,14 +91,21 @@
def set_position(self, pos):
+ """
+ set the position of the rectangle.
+
+ :param pos: position (tuple of 4 floats) of the rectangle that
+ will be divided.
+ """
self._pos = pos
def get_position(self):
+ "return the position of the rectangle."
return self._pos
def set_anchor(self, anchor):
"""
- *anchor*
+ :param anchor: anchor position
===== ============
value description
@@ -254,43 +128,56 @@
raise ValueError('argument must be among %s' %
', '.join(mtransforms.BBox.coefs.keys()))
+ def get_anchor(self):
+ "return the anchor"
+ return self._anchor
def set_horizontal(self, h):
+ """
+ :param horizontal: list of sizes
+ (:mod:`~mpl_toolkits.axes_grid.axes_size`)
+ for horizontal division
+ """
self._horizontal = h
+
def get_horizontal(self):
+ "return horizontal sizes"
return self._horizontal
def set_vertical(self, v):
+ """
+ :param horizontal: list of sizes
+ (:mod:`~mpl_toolkits.axes_grid.axes_size`)
+ for horizontal division
+ """
self._vertical = v
def get_vertical(self):
+ "return vertical sizes"
return self._vertical
- def get_anchor(self):
- return self._anchor
-
-
def set_aspect(self, aspect=False):
"""
- *aspect* : True or False
+ :param anchor: True or False
"""
self._aspect = aspect
def get_aspect(self):
+ "return aspect"
return self._aspect
def locate(self, nx, ny, nx1=None, ny1=None, renderer=None):
"""
- nx, nx1 : Integers specifying the column-position of the
- cell. When nx1 is None, a single nx-th column is
- specified. Otherwise location of columns spanning between nx
- to nx1 (but excluding nx1-th column) is is specified.
+ :param nx, nx1: Integers specifying the column-position of the
+ cell. When nx1 is None, a single nx-th column is
+ specified. Otherwise location of columns spanning between nx
+ to nx1 (but excluding nx1-th column) is specified.
- ny, ny1 : same as nx and nx1, but for row positions.
+ :param ny, ny1: same as nx and nx1, but for row positions.
"""
@@ -330,6 +217,18 @@
def new_locator(self, nx, ny, nx1=None, ny1=None):
+ """
+ returns a new locator
+ (:class:`mpl_toolkits.axes_grid.axes_divider.AxesLocator`) for
+ specified cell.
+
+ :param nx, nx1: Integers specifying the column-position of the
+ cell. When nx1 is None, a single nx-th column is
+ specified. Otherwise location of columns spanning between nx
+ to nx1 (but excluding nx1-th column) is specified.
+
+ :param ny, ny1: same as nx and nx1, but for row positions.
+ """
return AxesLocator(self, nx, ny, nx1, ny1)
@@ -341,14 +240,14 @@
"""
def __init__(self, axes_divider, nx, ny, nx1=None, ny1=None):
"""
- 'axes_divider' : An instance of AxesDivider class.
+ :param axes_divider: An instance of AxesDivider class.
- nx, nx1 : Integers specifying the column-position of the
- cell. When nx1 is None, a single nx-th column is
- specified. Otherwise location of columns spanning between nx
- to nx1 (but excluding nx1-th column) is is specified.
+ :param nx, nx1: Integers specifying the column-position of the
+ cell. When nx1 is None, a single nx-th column is
+ specified. Otherwise location of columns spanning between nx
+ to nx1 (but excluding nx1-th column) is is specified.
- ny, ny1 : same as nx and nx1, but for row positions.
+ :param ny, ny1: same as nx and nx1, but for row positions.
"""
self._axes_divider = axes_divider
@@ -371,14 +270,20 @@
_xrefindex = self._axes_divider._xrefindex
_yrefindex = self._axes_divider._yrefindex
- return self._axes_divider.locate(self._nx + _xrefindex, self._ny + _yrefindex,
- self._nx1 + _xrefindex, self._ny1 + _yrefindex,
+ return self._axes_divider.locate(self._nx + _xrefindex,
+ self._ny + _yrefindex,
+ self._nx1 + _xrefindex,
+ self._ny1 + _yrefindex,
renderer)
class SubplotDivider(Divider):
+ """
+ The Divider class whose rectangle area is specified as a subplot grometry.
+ """
+
def __init__(self, fig, *args, **kwargs):
"""
*fig* is a :class:`matplotlib.figure.Figure` instance.
@@ -431,6 +336,7 @@
def get_position(self):
+ "return the bounds of the subplot box"
self.update_params()
return self.figbox.bounds
@@ -468,9 +374,14 @@
class AxesDivider(Divider):
+ """
+ Divider based on the pre-existing axes.
+ """
-
def __init__(self, axes):
+ """
+ :param axes: axes
+ """
self._axes = axes
self._xref = Size.AxesX(axes)
self._yref = Size.AxesY(axes)
@@ -494,8 +405,27 @@
return ax
+
def new_horizontal(self, size, pad=None, pack_start=False, **kwargs):
+ """
+ Add a new axes on the right (or left) side of the main axes.
+ :param size: A width of the axes. A :mod:`~mpl_toolkits.axes_grid.axes_size`
+ instance or if float or string is given, *from_any*
+ fucntion is used to create one, with *ref_size* set to AxesX instance
+ of the current axes.
+ :param pad: pad between the axes. It takes same argument as *size*.
+ :param pack_start: If False, the new axes is appended at the end
+ of the list, i.e., it became the right-most axes. If True, it is
+ inseted at the start of the list, and becomes the left-most axes.
+
+ All extra keywords argument is passed to when creating a axes.
+ if *axes_class* is given, the new axes will be created as an
+ instance of the given class. Otherwise, the same class of the
+ main axes will be used. if Not provided
+
+ """
+
if pad:
if not isinstance(pad, Size._Base):
pad = Size.from_any(pad,
@@ -518,18 +448,32 @@
self._horizontal.append(size)
locator = self.new_locator(nx=len(self._horizontal)-1, ny=0)
- #axes_class = type(self._axes)
ax = self._get_new_axes(**kwargs)
- #ax = axes_class(self._axes.get_figure(),
- # self._axes.get_position(original=True),
- # **kwargs)
locator = self.new_locator(nx=len(self._horizontal)-1, ny=0)
ax.set_axes_locator(locator)
return ax
def new_vertical(self, size, pad=None, pack_start=False, **kwargs):
+ """
+ Add a new axes on the top (or bottom) side of the main axes.
+ :param size: A height of the axes. A :mod:`~mpl_toolkits.axes_grid.axes_size`
+ instance or if float or string is given, *from_any*
+ fucntion is used to create one, with *ref_size* set to AxesX instance
+ of the current axes.
+ :param pad: pad between the axes. It takes same argument as *size*.
+ :param pack_start: If False, the new axes is appended at the end
+ of the list, i.e., it became the top-most axes. If True, it is
+ inseted at the start of the list, and becomes the bottom-most axes.
+
+ All extra keywords argument is passed to when creating a axes.
+ if *axes_class* is given, the new axes will be created as an
+ instance of the given class. Otherwise, the same class of the
+ main axes will be used. if Not provided
+
+ """
+
if pad:
if not isinstance(pad, Size._Base):
pad = Size.from_any(pad,
@@ -553,10 +497,6 @@
locator = self.new_locator(nx=0, ny=len(self._vertical)-1)
ax = self._get_new_axes(**kwargs)
- #axes_class = type(self._axes)
- #ax = axes_class(self._axes.get_figure(),
- # self._axes.get_position(original=True),
- # **kwargs)
ax.set_axes_locator(locator)
return ax
@@ -650,3 +590,138 @@
return divider
+def get_demo_image():
+ # prepare image
+ delta = 0.5
+
+ extent = (-3,4,-4,3)
+ import numpy as np
+ x = np.arange(-3.0, 4.001, delta)
+ y = np.arange(-4.0, 3.001, delta)
+ X, Y = np.meshgrid(x, y)
+ import matplotlib.mlab as mlab
+ Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
+ Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
+ Z = (Z1 - Z2) * 10
+
+ return Z, extent
+
+def demo_locatable_axes():
+ import matplotlib.pyplot as plt
+
+ fig1 = plt.figure(1, (6, 6))
+ fig1.clf()
+
+ ## PLOT 1
+ # simple image & colorbar
+ ax = fig1.add_subplot(2, 2, 1)
+
+ Z, extent = get_demo_image()
+
+ im = ax.imshow(Z, extent=extent, interpolation="nearest")
+ cb = plt.colorbar(im)
+ plt.setp(cb.ax.get_yticklabels(), visible=False)
+
+
+ ## PLOT 2
+ # image and colorbar whose location is adjusted in the drawing time.
+ # a hard way
+
+ divider = SubplotDivider(fig1, 2, 2, 2, aspect=True)
+
+ # axes for image
+ ax = LocatableAxes(fig1, divider.get_position())
+
+ # axes for coloarbar
+ ax_cb = LocatableAxes(fig1, divider.get_position())
+
+ h = [Size.AxesX(ax), # main axes
+ Size.Fixed(0.05), # padding, 0.1 inch
+ Size.Fixed(0.2), # colorbar, 0.3 inch
+ ]
+
+ v = [Size.AxesY(ax)]
+
+ divider.set_horizontal(h)
+ divider.set_vertical(v)
+
+ ax.set_axes_locator(divider.new_locator(nx=0, ny=0))
+ ax_cb.set_axes_locator(divider.new_locator(nx=2, ny=0))
+
+ fig1.add_axes(ax)
+ fig1.add_axes(ax_cb)
+
+ ax_cb.yaxis.set_ticks_position("right")
+
+ Z, extent = get_demo_image()
+
+ im = ax.imshow(Z, extent=extent, interpolation="nearest")
+ plt.colorbar(im, cax=ax_cb)
+ plt.setp(ax_cb.get_yticklabels(), visible=False)
+
+ plt.draw()
+ #plt.colorbar(im, cax=ax_cb)
+
+
+ ## PLOT 3
+ # image and colorbar whose location is adjusted in the drawing time.
+ # a easy way
+
+ ax = fig1.add_subplot(2, 2, 3)
+ divider = make_axes_locatable(ax)
+
+ ax_cb = divider.new_horizontal(size="5%", pad=0.05)
+ fig1.add_axes(ax_cb)
+
+ im = ax.imshow(Z, extent=extent, interpolation="nearest")
+ plt.colorbar(im, cax=ax_cb)
+ plt.setp(ax_cb.get_yticklabels(), visible=False)
+
+
+ ## PLOT 4
+ # two images side by sied with fixed padding.
+
+ ax = fig1.add_subplot(2, 2, 4)
+ divider = make_axes_locatable(ax)
+
+ ax2 = divider.new_horizontal(size="100%", pad=0.05)
+ fig1.add_axes(ax2)
+
+ ax.imshow(Z, extent=extent, interpolation="nearest")
+ ax2.imshow(Z, extent=extent, interpolation="nearest")
+ plt.setp(ax2.get_yticklabels(), visible=False)
+ plt.draw()
+ plt.show()
+
+
+def demo_fixed_size_axes():
+ import matplotlib.pyplot as plt
+
+ fig2 = plt.figure(2, (6, 6))
+
+ # The first items are for padding and the second items are for the axes.
+ # sizes are in inch.
+ h = [Size.Fixed(1.0), Size.Fixed(4.5)]
+ v = [Size.Fixed(0.7), Size.Fixed(5.)]
+
+ divider = Divider(fig2, (0.0, 0.0, 1., 1.), h, v, aspect=False)
+ # the width and height of the rectangle is ignored.
+
+ ax = LocatableAxes(fig2, divider.get_position())
+ ax.set_axes_locator(divider.new_locator(nx=1, ny=1))
+
+ fig2.add_axes(ax)
+
+ ax.plot([1,2,3])
+
+ plt.draw()
+ plt.show()
+ #plt.colorbar(im, cax=ax_cb)
+
+
+
+
+
+if __name__ == "__main__":
+ demo_locatable_axes()
+ demo_fixed_size_axes()
Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_grid.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_grid.py 2009-04-19 14:29:07 UTC (rev 7055)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_grid.py 2009-04-21 03:12:53 UTC (rev 7056)
@@ -53,16 +53,11 @@
ticks, ticklabels, offset_string = self._ticker()
if self.orientation == 'vertical':
- #ax.set_xticks([])
- #ax.yaxis.set_label_position('right')
- #ax.yaxis.set_ticks_position('right')
ax.set_yticks(ticks)
ax.set_yticklabels(ticklabels)
ax.yaxis.get_major_formatter().set_offset_string(offset_string)
else:
- #ax.set_yticks([])
- #ax.xaxis.set_label_position('bottom')
ax.set_xticks(ticks)
ax.set_xticklabels(ticklabels)
ax.xaxis.get_major_formatter().set_offset_string(offset_string)
@@ -150,17 +145,12 @@
class AxesGrid(object):
"""
- The :class:`Axes` contains most of the figure elements:
- :class:`~matplotlib.axis.Axis`, :class:`~matplotlib.axis.Tick`,
- :class:`~matplotlib.lines.Line2D`, :class:`~matplotlib.text.Text`,
- :class:`~matplotlib.patches.Polygon`, etc., and sets the
- coordinate system.
-
- The :class:`Axes` instance supports callbacks through a callbacks
- attribute which is a :class:`~matplotlib.cbook.CallbackRegistry`
- instance. The events you can connect to are 'xlim_changed' and
- 'ylim_changed' and the callback will be called with func(*ax*)
- where *ax* is the :class:`Axes` instance.
+ A class that creates a grid of Axes. In matplotlib, the axes
+ location (and size) is specified in the normalized figure
+ coordinates. This may not be ideal for images that needs to be
+ displayed with a given aspect ratio. For example, displaying
+ images of a same size with some fixed padding between them cannot
+ be easily done in matplotlib. AxesGrid is used in such case.
"""
def __init__(self, fig,
@@ -275,7 +265,7 @@
for i in range(self.ngrids):
- col, row = self.get_col_row(i)
+ col, row = self._get_col_row(i)
if share_all:
sharex = self._refax
@@ -359,7 +349,7 @@
for i in range(self.ngrids):
- col, row = self.get_col_row(i)
+ col, row = self._get_col_row(i)
#locator = self._divider.new_locator(nx=4*col, ny=2*(self._nrows - row - 1))
locator = self._divider.new_locator(nx=h_ax_pos[col],
ny=v_ax_pos[self._nrows -1 - row])
@@ -406,7 +396,7 @@
- def get_col_row(self, n):
+ def _get_col_row(self, n):
if self._direction == "column":
col, row = divmod(n, self._nrows)
else:
@@ -420,80 +410,57 @@
def get_geometry(self):
+ """
+ get geometry of the grid. Returns a tuple of two integer,
+ representing number of rows and number of columns.
+ """
return self._nrows, self._ncols
def set_axes_pad(self, axes_pad):
+ "set axes_pad"
self._axes_pad = axes_pad
def get_axes_pad(self):
+ "get axes_pad"
return self._axes_pad
def set_aspect(self, aspect):
+ "set aspect"
self._divider.set_aspect(aspect)
def get_aspect(self):
+ "get aspect"
return self._divider.get_aspect()
def set_label_mode(self, mode):
+ "set label_mode"
if mode == "all":
for ax in self.axes_all:
_tick_only(ax, False, False)
- #[l.set_visible(True) for l in ax.get_xticklabels()]
- #[l.set_visible(True) for l in ax.get_yticklabels()]
elif mode == "L":
# left-most axes
for ax in self.axes_column[0][:-1]:
_tick_only(ax, bottom_on=True, left_on=False)
- #[l.set_visible(False) for l in ax.get_xticklabels()]
- #[l.set_visible(True) for l in ax.get_yticklabels()]
- #if hasattr(ax, "_axislines"):
- # ax._axislines["left"].major_ticklabels.set_visible(True)
- # ax._axislines["bottom"].major_ticklabels.set_visible(False)
# lower-left axes
ax = self.axes_column[0][-1]
_tick_only(ax, bottom_on=False, left_on=False)
- #[l.set_visible(True) for l in ax.get_xticklabels()]
- #[l.set_visible(True) for l in ax.get_yticklabels()]
- #if hasattr(ax, "_axislines"):
- # ax._axislines["left"].major_ticklabels.set_visible(True)
- # ax._axislines["bottom"].major_ticklabels.set_visible(True)
for col in self.axes_column[1:]:
# axes with no labels
for ax in col[:-1]:
_tick_only(ax, bottom_on=True, left_on=True)
- #[l.set_visible(False) for l in ax.get_xticklabels()]
- #[l.set_visible(False) for l in ax.get_yticklabels()]
- #if hasattr(ax, "_axislines"):
- # ax._axislines["left"].major_ticklabels.set_visible(False)
- # ax._axislines["bottom"].major_ticklabels.set_visible(False)
# bottom
ax = col[-1]
_tick_only(ax, bottom_on=False, left_on=True)
- #[l.set_visible(True) for l in ax.get_xticklabels()]
- #[l.set_visible(False) for l in ax.get_yticklabels()]
- #if hasattr(ax, "_axislines"):
- # ax._axislines["left"].major_ticklabels.set_visible(False)
- # ax._axislines["bottom"].major_ticklabels.set_visible(True)
elif mode == "1":
for ax in self.axes_all:
_tick_only(ax, bottom_on=True, left_on=True)
- #[l.set_visible(False) for l in ax.get_xticklabels()]
- #[l.set_visible(False) for l in ax.get_yticklabels()]
- #if hasattr(ax, "_axislines"):
- # for axisline in ax._axislines.values():
- # axisline.major_ticklabels.set_visible(False)
ax = self.axes_llc
_tick_only(ax, bottom_on=False, left_on=False)
- #[l.set_visible(True) for l in ax.get_xticklabels()]
- #[l.set_visible(True) for l in ax.get_yticklabels()]
- #if hasattr(ax, "_axislines"):
- # ax._axislines["left"].major_ticklabels.set_visible(True)
- # ax._axislines["bottom"].major_ticklabels.set_visible(True)
Added: trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_size.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_size.py (rev 0)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_size.py 2009-04-21 03:12:53 UTC (rev 7056)
@@ -0,0 +1,207 @@
+
+"""
+provides a classese of simlpe units that will be used with AxesDivider
+class (or others) to determine the size of each axes. The unit
+classes define `get_size` method that returns a tuple of two floats,
+meaning relative and absolute sizes, respectively.
+
+Note that this class is nothing more than a simple tuple of two
+floats. Take a look at the Divider class to see how these two
+values are used.
+
+"""
+
+import matplotlib.cbook as cbook
+
+
+class _Base(object):
+ "Base class"
+ pass
+
+class Fixed(_Base):
+ "Simple fixed size with absolute part = *fixed_size* and relative part = 0"
+ def __init__(self, fixed_size):
+ self._fixed_size = fixed_size
+
+ def get_size(self, renderer):
+ rel_size = 0.
+ abs_size = self._fixed_size
+ return rel_size, abs_size
+
+class Scaled(_Base):
+ "Simple scaled(?) size with absolute part = 0 and relative part = *scalable_size*"
+ def __init__(self, scalable_size):
+ self._scalable_size = scalable_size
+
+ def get_size(self, renderer):
+ rel_size = self._scalable_size
+ abs_size = 0.
+ return rel_size, abs_size
+
+Scalable=Scaled
+
+
+class AxesX(_Base):
+ """
+ Scaled size whose relative part corresponds to the data width
+ of the *axes* multiplied by the *aspect*.
+ """
+ def __init__(self, axes, aspect=1.):
+ self._axes = axes
+ self._aspect = aspect
+
+ def get_size(self, renderer):
+ l1, l2 = self._axes.get_xlim()
+ rel_size = abs(l2-l1)*self._aspect
+ abs_size = 0.
+ return rel_size, abs_size
+
+class AxesY(_Base):
+ """
+ Scaled size whose relative part corresponds to the data height
+ of the *axes* multiplied by the *aspect*.
+ """
+ def __init__(self, axes, aspect=1.):
+ self._axes = axes
+ self._aspect = aspect
+
+ def get_size(self, renderer):
+ l1, l2 = self._axes.get_ylim()
+ rel_size = abs(l2-l1)*self._aspect
+ abs_size = 0.
+ return rel_size, abs_size
+
+
+class MaxExtent(_Base):
+ """
+ Size whose absolute part is the largest width (or height) of
+ the given *artist_list*.
+ """
+ def __init__(self, artist_list, w_or_h):
+ self._artist_list = artist_list
+
+ if w_or_h not in ["width", "height"]:
+ raise ValueError()
+
+ self._w_or_h = w_or_h
+
+ def add_artist(self, a):
+ self._artist_list.append(a)
+
+ def get_size(self, renderer):
+ rel_size = 0.
+ w_list, h_list = [], []
+ for a in self._artist_list:
+ bb = a.get_window_extent(renderer)
+ w_list.append(bb.width)
+ h_list.append(bb.height)
+ dpi = a.get_figure().get_dpi()
+ if self._w_or_h == "width":
+ abs_size = max(w_list)/dpi
+ elif self._w_or_h == "height":
+ abs_size = max(h_list)/dpi
+
+ return rel_size, abs_size
+
+
+class MaxWidth(_Base):
+ """
+ Size whose absolute part is the largest width of
+ the given *artist_list*.
+ """
+ def __init__(self, artist_list):
+ self._artist_list = artist_list
+
+ def add_artist(self, a):
+ self._artist_list.append(a)
+
+ def get_size(self, renderer):
+ rel_size = 0.
+ w_list = []
+ for a in self._artist_list:
+ bb = a.get_window_extent(renderer)
+ w_list.append(bb.width)
+ dpi = a.get_figure().get_dpi()
+ abs_size = max(w_list)/dpi
+
+ return rel_size, abs_size
+
+
+
+class MaxHeight(_Base):
+ """
+ Size whose absolute part is the largest height of
+ the given *artist_list*.
+ """
+ def __init__(self, artist_list):
+ self._artist_list = artist_list
+
+ def add_artist(self, a):
+ self._artist_list.append(a)
+
+ def get_size(self, renderer):
+ rel_size = 0.
+ h_list = []
+ for a in self._artist_list:
+ bb = a.get_window_extent(renderer)
+ h_list.append(bb.height)
+ dpi = a.get_figure().get_dpi()
+ abs_size = max(h_list)/dpi
+
+ return rel_size, abs_size
+
+
+class Fraction(_Base):
+ """
+ An instance whose size is a *fraction* of the *ref_size*.
+
+ >>> s = Fraction(0.3, AxesX(ax))
+
+ """
+ def __init__(self, fraction, ref_size):
+ self._fraction_ref = ref_size
+ self._fraction = fraction
+
+ def get_size(self, renderer):
+ if self._fraction_ref is None:
+ return self._fraction, 0.
+ else:
+ r, a = self._fraction_ref.get_size(renderer)
+ rel_size = r*self._fraction
+ abs_size = a*self._fraction
+ return rel_size, abs_size
+
+class Padded(_Base):
+ """
+ Return a instance where the absolute part of *size* is
+ increase by the amount of *pad*.
+ """
+ def __init__(self, size, pad):
+ self._size = size
+ self._pad = pad
+
+ def get_size(self, renderer):
+ r, a = self._size.get_size(renderer)
+ rel_size = r
+ abs_size = a + self._pad
+ return rel_size, abs_size
+
+def from_any(size, fraction_ref=None):
+ """
+ Creates Fixed unit when the first argument is a float, or a
+ Fraction unit if that is a string that ends with %. The second
+ argument is only meaningful when Fraction unit is created.
+
+ >>> a = Size.from_any(1.2) # => Size.Fixed(1.2)
+ >>> Size.from_any("50%", a) # => Size.Fraction(0.5, a)
+
+ """
+ if cbook.is_numlike(size):
+ return Fixed(size)
+ elif cbook.is_string_like(size):
+ if size[-1] == "%":
+ return Fraction(float(size[:-1])/100., fraction_ref)
+
+ raise ValueError("Unknown format")
+
+
Added: trunk/matplotlib/lib/mpl_toolkits/axes_grid/inset_locator.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/inset_locator.py (rev 0)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/inset_locator.py 2009-04-21 03:12:53 UTC (rev 7056)
@@ -0,0 +1,308 @@
+from matplotlib.offsetbox import AnchoredOffsetbox
+#from matplotlib.transforms import IdentityTransform
+
+import matplotlib.transforms as mtrans
+from matplotlib.axes import Axes
+
+from matplotlib.transforms import Bbox, TransformedBbox, IdentityTransform
+
+from matplotlib.patches import Patch
+from matplotlib.path import Path
+
+from matplotlib.patches import Rectangle
+
+
+class InsetPosition(object):
+ def __init__(self, parent, lbwh):
+ self.parent = parent
+ self.lbwh = lbwh # position of the inset axes in the normalized coordinate of the parent axes
+
+ def __call__(self, ax, renderer):
+ bbox_parent = self.parent.get_position(original=False)
+ trans = mtrans.BboxTransformTo(bbox_parent)
+ bbox_inset = mtrans.Bbox.from_bounds(*self.lbwh)
+ bb = mtrans.TransformedBbox(bbox_inset, trans)
+ return bb
+
+
+class AnchoredLocatorBase(AnchoredOffsetbox):
+ def __init__(self, bbox_to_anchor, offsetbox, loc,
+ borderpad=0.5, bbox_transform=None):
+
+ super(AnchoredLocatorBase, self).__init__(loc,
+ pad=0., child=None,
+ borderpad=borderpad,
+ bbox_to_anchor=bbox_to_anchor,
+ bbox_transform=bbox_transform)
+
+
+ def draw(self, renderer):
+ raise RuntimeError("No draw method should be called")
+
+
+ def __call__(self, ax, renderer):
+
+ fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
+ self._update_offset_func(renderer, fontsize)
+
+ width, height, xdescent, ydescent = self.get_extent(renderer)
+
+ px, py = self.get_offset(width, height, 0, 0)
+ bbox_canvas = mtrans.Bbox.from_bounds(px, py, width, height)
+ tr = ax.figure.transFigure.inverted()
+ bb = mtrans.TransformedBbox(bbox_canvas, tr)
+
+ return bb
+
+
+
+
+from mpl_toolkits.axes_grid.axes_divider import Size
+
+class AnchoredSizeLocator(AnchoredLocatorBase):
+ def __init__(self, bbox_to_anchor, x_size, y_size, loc,
+ borderpad=0.5, bbox_transform=None):
+
+ self.axes = None
+ self.x_size = Size.from_any(x_size)
+ self.y_size = Size.from_any(y_size)
+
+ super(AnchoredSizeLocator, self).__init__(bbox_to_anchor, None, loc,
+ borderpad=borderpad,
+ bbox_transform=bbox_transform)
+
+ def get_extent(self, renderer):
+
+ x, y, w, h = self.get_bbox_to_anchor().bounds
+
+ dpi = renderer.points_to_pixels(72.)
+
+ r, a = self.x_size.get_size(renderer)
+ width = w*r + a*dpi
+
+ r, a = self.y_size.get_size(renderer)
+ height = h*r + a*dpi
+ xd, yd = 0, 0
+
+ fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
+ pad = self.pad * fontsize
+
+ return width+2*pad, height+2*pad, xd+pad, yd+pad
+
+
+ def __call__(self, ax, renderer):
+
+ self.axes = ax
+ return super(AnchoredSizeLocator, self).__call__(ax, renderer)
+
+
+class AnchoredZoomLocator(AnchoredLocatorBase):
+ def __init__(self, parent_axes, zoom, loc,
+ borderpad=0.5,
+ bbox_to_anchor=None,
+ bbox_transform=None):
+
+ self.parent_axes = parent_axes
+ self.zoom = zoom
+
+ if bbox_to_anchor is None:
+ bbox_to_anchor = parent_axes.bbox
+
+ super(AnchoredZoomLocator, self).__init__(bbox_to_anchor, None, loc,
+ borderpad=borderpad,
+ bbox_transform=bbox_transform)
+
+ self.axes = None
+
+
+ def get_extent(self, renderer):
+
+ bb = mtrans.TransformedBbox(self.axes.viewLim, self.parent_axes.transData)
+
+ x, y, w, h = bb.bounds
+
+ xd, yd = 0, 0
+
+ fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
+ pad = self.pad * fontsize
+
+ return w*self.zoom+2*pad, h*self.zoom+2*pad, xd+pad, yd+pad
+
+
+ def __call__(self, ax, renderer):
+
+ self.axes = ax
+ return super(AnchoredZoomLocator, self).__call__(ax, renderer)
+
+
+
+
+
+
+class BboxPatch(Patch):
+ def __init__(self, bbox, **kwargs):
+ if "transform" in kwargs:
+ raise ValueError("trnasform should nt be set")
+
+ kwargs["transform"] = IdentityTransform()
+ Patch.__init__(self, **kwargs)
+ self.bbox = bbox
+
+ def get_path(self):
+ x0, y0, x1, y1 = self.bbox.extents
+
+ verts = [(x0, y0),
+ (x1, y0),
+ (x1, y1),
+ (x0, y1),
+ (x0, y0),
+ (0,0)]
+
+ codes = [Path.MOVETO,
+ Path.LINETO,
+ Path.LINETO,
+ Path.LINETO,
+ Path.LINETO,
+ Path.CLOSEPOLY]
+
+ return Path(verts, codes)
+
+
+
+
+class BboxConnector(Patch):
+
+ @staticmethod
+ def get_bbox_edge_pos(bbox, loc):
+ x0, y0, x1, y1 = bbox.extents
+ if loc==1:
+ return x1, y1
+ elif loc==2:
+ return x0, y1
+ elif loc==3:
+ return x0, y0
+ elif loc==4:
+ return x1, y0
+
+ @staticmethod
+ def connect_bbox(bbox1, bbox2, loc1, loc2=None):
+ if isinstance(bbox1, Rectangle):
+ transform = bbox1.get_transfrom()
+ bbox1 = Bbox.from_bounds(0, 0, 1, 1)
+ bbox1 = TransformedBbox(bbox1, transform)
+
+ if isinstance(bbox2, Rectangle):
+ transform = bbox2.get_transform()
+ bbox2 = Bbox.from_bounds(0, 0, 1, 1)
+ bbox2 = TransformedBbox(bbox2, transform)
+
+ if loc2 is None:
+ loc2 = loc1
+
+ x1, y1 = BboxConnector.get_bbox_edge_pos(bbox1, loc1)
+ x2, y2 = BboxConnector.get_bbox_edge_pos(bbox2, loc2)
+
+ verts = [[x1, y1], [x2,y2]]
+ #Path()
+
+ codes = [Path.MOVETO, Path.LINETO]
+
+ return Path(verts, codes)
+
+
+ def __init__(self, bbox1, bbox2, loc1, loc2=None, **kwargs):
+ """
+ *path* is a :class:`matplotlib.path.Path` object.
+
+ Valid kwargs are:
+ %(Patch)s
+
+ .. seealso::
+
+ :class:`Patch`
+ For additional kwargs
+
+ """
+ if "transform" in kwargs:
+ raise ValueError("trnasform should nt be set")
+
+ kwargs["transform"] = IdentityTransform()
+ Patch.__init__(self, **kwargs)
+ self.bbox1 = bbox1
+ self.bbox2 = bbox2
+ self.loc1 = loc1
+ self.loc2 = loc2
+
+
+ def get_path(self):
+ return self.connect_bbox(self.bbox1, self.bbox2,
+ self.loc1, self.loc2)
+
+
+def _add_inset_axes(parent_axes, inset_axes):
+ parent_axes.figure.add_axes(inset_axes)
+ inset_axes.set_navigate(False)
+
+
+def inset_axes(parent_axes, width, height, loc=1,
+ bbox_to_anchor=None, bbox_transform=None,
+ axes_kwargs=None,
+ **kwargs):
+
+ if axes_kwargs is None:
+ inset_axes = Axes(parent_axes.figure, parent_axes.get_position())
+ else:
+ inset_axes = Axes(parent_axes.figure, parent_axes.get_position(),
+ **axes_kwargs)
+
+ axes_locator = AnchoredSizeLocator(parent_axes.bbox,
+ width, height,
+ loc=loc)
+
+ inset_axes.set_axes_locator(axes_locator)
+
+ _add_inset_axes(parent_axes, inset_axes)
+
+ return inset_axes
+
+
+def zoomed_inset_axes(parent_axes, zoom, loc=1,
+ bbox_to_anchor=None, bbox_transform=None,
+ axes_kwargs=None,
+ connects=None,
+ **kwargs):
+
+ if axes_kwargs is None:
+ inset_axes = Axes(parent_axes.figure, parent_axes.get_position())
+ else:
+ inset_axes = Axes(parent_axes.figure, parent_axes.get_position(),
+ **axes_kwargs)
+
+ axes_locator = AnchoredZoomLocator(parent_axes, zoom=zoom, loc=loc)
+ inset_axes.set_axes_locator(axes_locator)
+
+ _add_inset_axes(parent_axes, inset_axes)
+
+ if connects is not None:
+ pass
+
+ return inset_axes
+
+
+def mark_inset(parent_axes, inset_axes, loc1, loc2, **kwargs):
+ rect = TransformedBbox(inset_axes.viewLim, parent_axes.transData)
+
+ pp = BboxPatch(rect, **kwargs)
+ parent_axes.add_patch(pp)
+
+ p1 = BboxConnector(inset_axes.bbox, rect, loc1=loc1, **kwargs)
+ inset_axes.add_patch(p1)
+ p1.set_clip_on(False)
+ p2 = BboxConnector(inset_axes.bbox, rect, loc1=loc2, **kwargs)
+ inset_axes.add_patch(p2)
+ p2.set_clip_on(False)
+
+ return pp, p1, p2
+
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-04-19 14:29:17
|
Revision: 7055
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7055&view=rev
Author: jdh2358
Date: 2009-04-19 14:29:07 +0000 (Sun, 19 Apr 2009)
Log Message:
-----------
Merged revisions 7054 via svnmerge from
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/v0_98_5_maint
........
r7054 | jdh2358 | 2009-04-19 09:26:12 -0500 (Sun, 19 Apr 2009) | 1 line
force a copy of the colormap input data
........
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/colors.py
Property Changed:
----------------
trunk/matplotlib/
Property changes on: trunk/matplotlib
___________________________________________________________________
Modified: svnmerge-integrated
- /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-7042
+ /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-7054
Modified: trunk/matplotlib/lib/matplotlib/colors.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/colors.py 2009-04-19 14:26:12 UTC (rev 7054)
+++ trunk/matplotlib/lib/matplotlib/colors.py 2009-04-19 14:29:07 UTC (rev 7055)
@@ -483,7 +483,9 @@
xa = np.array([X])
else:
vtype = 'array'
- xma = ma.asarray(X)
+ # force a copy here -- the ma.array and filled functions
+ # do force a cop of the data by default - JDH
+ xma = ma.array(X, copy=True)
xa = xma.filled(0)
mask_bad = ma.getmask(xma)
if xa.dtype.char in np.typecodes['Float']:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-04-19 14:26:16
|
Revision: 7054
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7054&view=rev
Author: jdh2358
Date: 2009-04-19 14:26:12 +0000 (Sun, 19 Apr 2009)
Log Message:
-----------
force a copy of the colormap input data
Modified Paths:
--------------
branches/v0_98_5_maint/lib/matplotlib/colors.py
Modified: branches/v0_98_5_maint/lib/matplotlib/colors.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/colors.py 2009-04-19 14:25:41 UTC (rev 7053)
+++ branches/v0_98_5_maint/lib/matplotlib/colors.py 2009-04-19 14:26:12 UTC (rev 7054)
@@ -483,7 +483,9 @@
xa = np.array([X])
else:
vtype = 'array'
- xma = ma.asarray(X)
+ # force a copy here -- the ma.array and filled functions
+ # do force a cop of the data by default - JDH
+ xma = ma.array(X, copy=True)
xa = xma.filled(0)
mask_bad = ma.getmask(xma)
if xa.dtype.char in np.typecodes['Float']:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-04-19 14:25:46
|
Revision: 7053
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7053&view=rev
Author: jdh2358
Date: 2009-04-19 14:25:41 +0000 (Sun, 19 Apr 2009)
Log Message:
-----------
updated osx release notes
Modified Paths:
--------------
trunk/matplotlib/release/osx/README.txt
Modified: trunk/matplotlib/release/osx/README.txt
===================================================================
--- trunk/matplotlib/release/osx/README.txt 2009-04-18 16:02:56 UTC (rev 7052)
+++ trunk/matplotlib/release/osx/README.txt 2009-04-19 14:25:41 UTC (rev 7053)
@@ -55,3 +55,30 @@
make installers
The mpkg and egg binaries will reside in :file:`matplotlib-VERSION/dist`
+
+Crib sheet
+-------------
+
+Build the dependencies::
+
+ cd release/osx/
+ unset PKG_CONFIG_PATH
+ make fetch_deps
+ cd bdist_mpkg-0.4.3
+ sudo python setup.py install
+ cd ..
+ make dependencies
+
+Build the mpl sdist::
+
+ cd ../..
+ python setup.py sdist
+ mv dist/matplotlib-0.98.6svn.tar.gz release/osx/
+
+Set the version number in the Makefile to 0.98.6svn and build the
+installers ::
+
+ cd release/osx
+ make installers
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2009-04-18 16:02:57
|
Revision: 7052
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7052&view=rev
Author: leejjoon
Date: 2009-04-18 16:02:56 +0000 (Sat, 18 Apr 2009)
Log Message:
-----------
offsetbox minor update
Modified Paths:
--------------
trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py
trunk/matplotlib/lib/matplotlib/offsetbox.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py
Removed Paths:
-------------
trunk/matplotlib/examples/pylab_examples/axes_divider.py
trunk/matplotlib/examples/pylab_examples/axes_grid.py
Modified: trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py 2009-04-17 20:40:58 UTC (rev 7051)
+++ trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py 2009-04-18 16:02:56 UTC (rev 7052)
@@ -11,7 +11,8 @@
at2 = AnchoredText("Figure 1(b)",
loc=3, prop=dict(size=8), frameon=True,
- bbox_to_anchor=(0., 1.)
+ bbox_to_anchor=(0., 1.),
+ bbox_transform=ax.transAxes
)
at2.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at2)
Deleted: trunk/matplotlib/examples/pylab_examples/axes_divider.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/axes_divider.py 2009-04-17 20:40:58 UTC (rev 7051)
+++ trunk/matplotlib/examples/pylab_examples/axes_divider.py 2009-04-18 16:02:56 UTC (rev 7052)
@@ -1,674 +0,0 @@
-
-import matplotlib.axes as maxes
-import matplotlib.transforms as mtransforms
-
-import matplotlib.cbook as cbook
-
-import new
-
-
-class Size(object):
-
- @classmethod
- def from_any(self, size, fraction_ref=None):
- if cbook.is_numlike(size):
- return Size.Fixed(size)
- elif cbook.is_string_like(size):
- if size[-1] == "%":
- return Size.Fraction(fraction_ref, float(size[:-1])/100.)
-
- raise ValueError("")
-
-
-
- class _Base(object):
- pass
-
- class Fixed(_Base):
- def __init__(self, fixed_size):
- self._fixed_size = fixed_size
-
- def get_size(self, renderer):
- rel_size = 0.
- abs_size = self._fixed_size
- return rel_size, abs_size
-
- class Scalable(_Base):
- def __init__(self, scalable_size):
- self._scalable_size = scalable_size
-
- def get_size(self, renderer):
- rel_size = self._scalable_size
- abs_size = 0.
- return rel_size, abs_size
-
-
- class AxesX(_Base):
- def __init__(self, axes, aspect=1.):
- self._axes = axes
- self._aspect = aspect
-
- def get_size(self, renderer):
- l1, l2 = self._axes.get_xlim()
- rel_size = abs(l2-l1)*self._aspect
- abs_size = 0.
- return rel_size, abs_size
-
- class AxesY(_Base):
- def __init__(self, axes, aspect=1.):
- self._axes = axes
- self._aspect = aspect
-
- def get_size(self, renderer):
- l1, l2 = self._axes.get_ylim()
- rel_size = abs(l2-l1)*self._aspect
- abs_size = 0.
- return rel_size, abs_size
-
-
- class MaxExtent(_Base):
- def __init__(self, artist_list, w_or_h):
- self._artist_list = artist_list
-
- if w_or_h not in ["width", "height"]:
- raise ValueError()
-
- self._w_or_h = w_or_h
-
- def add_artist(self, a):
- self._artist_list.append(a)
-
- def get_size(self, renderer):
- rel_size = 0.
- w_list, h_list = [], []
- for a in self._artist_list:
- bb = a.get_window_extent(renderer)
- w_list.append(bb.width)
- h_list.append(bb.height)
- dpi = a.get_figure().get_dpi()
- if self._w_or_h == "width":
- abs_size = max(w_list)/dpi
- elif self._w_or_h == "height":
- abs_size = max(h_list)/dpi
-
- return rel_size, abs_size
-
- class Fraction(_Base):
- def __init__(self, size, fraction):
- self._size = size
- self._fraction = fraction
-
- def get_size(self, renderer):
- r, a = self._size.get_size(renderer)
- rel_size = r*self._fraction
- abs_size = a*self._fraction
- return rel_size, abs_size
-
- class Padded(_Base):
- def __init__(self, size, pad):
- self._size = size
- self._pad = pad
-
- def get_size(self, renderer):
- r, a = self._size.get_size(renderer)
- rel_size = r
- abs_size = a + self._pad
- return rel_size, abs_size
-
-
-
-class AxesLocator(object):
- def __init__(self, axes_divider, nx, ny, nx1=None, ny1=None):
-
- self._axes_divider = axes_divider
-
- _xrefindex = axes_divider._xrefindex
- _yrefindex = axes_divider._yrefindex
-
- self._nx, self._ny = nx - _xrefindex, ny - _yrefindex
-
- if nx1 is None:
- nx1 = nx+1
- if ny1 is None:
- ny1 = ny+1
-
- self._nx1 = nx1 - _xrefindex
- self._ny1 = ny1 - _yrefindex
-
-
- def __call__(self, axes, renderer):
-
- _xrefindex = self._axes_divider._xrefindex
- _yrefindex = self._axes_divider._yrefindex
-
- return self._axes_divider.locate(self._nx + _xrefindex, self._ny + _yrefindex,
- self._nx1 + _xrefindex, self._ny1 + _yrefindex,
- renderer)
-
-
-class Divider(object):
-
- def __init__(self, fig, pos, horizontal, vertical, aspect=None, anchor="C"):
- self._fig = fig
- self._pos = pos
- self._horizontal = horizontal
- self._vertical = vertical
- self._anchor = anchor
- self._aspect = aspect
- self._xrefindex = 0
- self._yrefindex = 0
-
-
- @staticmethod
- def _calc_k(l, total_size, renderer):
-
- rs_sum, as_sum = 0., 0.
-
- for s in l:
- rs, as = s.get_size(renderer)
- rs_sum += rs
- as_sum += as
-
- if rs_sum != 0.:
- k = (total_size - as_sum) / rs_sum
- return k
- else:
- return 0.
-
-
- @staticmethod
- def _calc_offsets(l, k, renderer):
-
- offsets = [0.]
-
- for s in l:
- rs, as = s.get_size(renderer)
- offsets.append(offsets[-1] + rs*k + as)
-
- return offsets
-
-
- def set_position(self, pos):
- self._pos = pos
-
- def get_position(self):
- return self._pos
-
- def set_anchor(self, anchor):
- """
- *anchor*
-
- ===== ============
- value description
- ===== ============
- 'C' Center
- 'SW' bottom left
- 'S' bottom
- 'SE' bottom right
- 'E' right
- 'NE' top right
- 'N' top
- 'NW' top left
- 'W' left
- ===== ============
-
- """
- if anchor in mtransforms.Bbox.coefs.keys() or len(anchor) == 2:
- self._anchor = anchor
- else:
- raise ValueError('argument must be among %s' %
- ', '.join(mtransforms.BBox.coefs.keys()))
-
-
- def set_horizontal(self, h):
- self._horizontal = h
-
- def get_horizontal(self):
- return self._horizontal
-
- def set_vertical(self, v):
- self._vertical = v
-
- def get_vertical(self):
- return self._vertical
-
-
- def get_anchor(self):
- return self._anchor
-
-
- def set_aspect(self, aspect=False):
- """
- *aspect* : True or False
- """
- self._aspect = aspect
-
- def get_aspect(self):
- return self._aspect
-
-
- def locate(self, nx, ny, nx1=None, ny1=None, renderer=None):
-
-
- figW,figH = self._fig.get_size_inches()
- x, y, w, h = self.get_position()
-
- k_h = self._calc_k(self._horizontal, figW*w, renderer)
- k_v = self._calc_k(self._vertical, figH*h, renderer)
-
- if self.get_aspect():
- k = min(k_h, k_v)
- ox = self._calc_offsets(self._horizontal, k, renderer)
- oy = self._calc_offsets(self._vertical, k, renderer)
-
- ww = (ox[-1] - ox[0])/figW
- hh = (oy[-1] - oy[0])/figH
- pb = mtransforms.Bbox.from_bounds(x, y, w, h)
- pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh)
- pb1_anchored = pb1.anchored(self.get_anchor(), pb)
- x0, y0 = pb1_anchored.x0, pb1_anchored.y0
-
- else:
- ox = self._calc_offsets(self._horizontal, k_h, renderer)
- oy = self._calc_offsets(self._vertical, k_v, renderer)
- x0, y0 = x, y
-
-
- if nx1 is None:
- nx1=nx+1
- if ny1 is None:
- ny1=ny+1
-
- x1, w1 = x0 + ox[nx]/figW, (ox[nx1] - ox[nx])/figW
- y1, h1 = y0 + oy[ny]/figH, (oy[ny1] - oy[ny])/figH
-
- return mtransforms.Bbox.from_bounds(x1, y1, w1, h1)
-
-
- def new_locator(self, nx, ny, nx1=None, ny1=None):
- return AxesLocator(self, nx, ny, nx1, ny1)
-
-
-class SubplotDivider(Divider):
-
- def __init__(self, fig, *args, **kwargs):
- """
- *fig* is a :class:`matplotlib.figure.Figure` instance.
-
- *args* is the tuple (*numRows*, *numCols*, *plotNum*), where
- the array of subplots in the figure has dimensions *numRows*,
- *numCols*, and where *plotNum* is the number of the subplot
- being created. *plotNum* starts at 1 in the upper left
- corner and increases to the right.
-
- If *numRows* <= *numCols* <= *plotNum* < 10, *args* can be the
- decimal integer *numRows* * 100 + *numCols* * 10 + *plotNum*.
- """
-
- self.figure = fig
-
- if len(args)==1:
- s = str(args[0])
- if len(s) != 3:
- raise ValueError('Argument to subplot must be a 3 digits long')
- rows, cols, num = map(int, s)
- elif len(args)==3:
- rows, cols, num = args
- else:
- raise ValueError( 'Illegal argument to subplot')
-
-
- total = rows*cols
- num -= 1 # convert from matlab to python indexing
- # ie num in range(0,total)
- if num >= total:
- raise ValueError( 'Subplot number exceeds total subplots')
- self._rows = rows
- self._cols = cols
- self._num = num
-
- self.update_params()
-
- pos = self.figbox.bounds
- horizontal = kwargs.pop("horizontal", [])
- vertical = kwargs.pop("vertical", [])
- aspect = kwargs.pop("aspect", None)
- anchor = kwargs.pop("anchor", "C")
-
- if kwargs:
- raise Exception("")
-
- Divider.__init__(self, fig, pos, horizontal, vertical,
- aspect=aspect, anchor=anchor)
-
-
- def get_position(self):
- self.update_params()
- return self.figbox.bounds
-
-
- def update_params(self):
- 'update the subplot position from fig.subplotpars'
-
- rows = self._rows
- cols = self._cols
- num = self._num
-
- pars = self.figure.subplotpars
- left = pars.left
- right = pars.right
- bottom = pars.bottom
- top = pars.top
- wspace = pars.wspace
- hspace = pars.hspace
- totWidth = right-left
- totHeight = top-bottom
-
- figH = totHeight/(rows + hspace*(rows-1))
- sepH = hspace*figH
-
- figW = totWidth/(cols + wspace*(cols-1))
- sepW = wspace*figW
-
- rowNum, colNum = divmod(num, cols)
-
- figBottom = top - (rowNum+1)*figH - rowNum*sepH
- figLeft = left + colNum*(figW + sepW)
-
- self.figbox = mtransforms.Bbox.from_bounds(figLeft, figBottom,
- figW, figH)
-
-class AxesDivider(Divider):
-
-
- def __init__(self, axes):
- self._axes = axes
- self._xref = Size.AxesX(axes)
- self._yref = Size.AxesY(axes)
- Divider.__init__(self, fig=axes.get_figure(), pos=None,
- horizontal=[self._xref], vertical=[self._yref],
- aspect=None, anchor="C")
-
- def new_horizontal(self, size, pad=None, pack_start=False):
-
- if pad:
- if not isinstance(pad, Size._Base):
- pad = Size.from_any(pad,
- fraction_ref=self._xref)
- if pack_start:
- self._horizontal.insert(0, pad)
- self._xrefindex += 1
- else:
- self._horizontal.append(pad)
-
- if not isinstance(size, Size._Base):
- size = Size.from_any(size,
- fraction_ref=self._xref)
-
- if pack_start:
- self._horizontal.insert(0, pad)
- self._xrefindex += 1
- locator = self.new_locator(nx=0, ny=0)
- else:
- self._horizontal.append(size)
- locator = self.new_locator(nx=len(self._horizontal)-1, ny=0)
-
- ax = LocatableAxes(self._axes.get_figure(),
- self._axes.get_position(original=True))
- locator = self.new_locator(nx=len(self._horizontal)-1, ny=0)
- ax.set_axes_locator(locator)
-
- return ax
-
- def new_vertical(self, size, pad=None, pack_start=False):
-
- if pad:
- if not isinstance(pad, Size._Base):
- pad = Size.from_any(pad,
- fraction_ref=self._yref)
- if pack_start:
- self._vertical.insert(0, pad)
- self._yrefindex += 1
- else:
- self._vertical.append(pad)
-
- if not isinstance(size, Size._Base):
- size = Size.from_any(size,
- fraction_ref=self._yref)
-
- if pack_start:
- self._vertical.insert(0, pad)
- self._yrefindex += 1
- locator = self.new_locator(nx=0, ny=0)
- else:
- self._vertical.append(size)
- locator = self.new_locator(nx=0, ny=len(self._vertical)-1)
-
- ax = LocatableAxes(self._axes.get_figure(),
- self._axes.get_position(original=True))
- ax.set_axes_locator(locator)
-
- return ax
-
-
- def get_aspect(self):
- if self._aspect is None:
- aspect = self._axes.get_aspect()
- if aspect == "auto":
- return False
- else:
- return True
- else:
- return self._aspect
-
- def get_position(self):
- if self._pos is None:
- bbox = self._axes.get_position(original=True)
- return bbox.bounds
- else:
- return self._pos
-
- def get_anchor(self):
- if self._anchor is None:
- return self._axes.get_anchor()
- else:
- return self._anchor
-
-
-
-class LocatableAxesBase:
- def __init__(self, *kl, **kw):
-
- self._axes_class.__init__(self, *kl, **kw)
-
- self._locator = None
- self._locator_renderer = None
-
- def set_axes_locator(self, locator):
- self._locator = locator
-
- def get_axes_locator(self):
- return self._locator
-
- def apply_aspect(self, position=None):
-
- if self.get_axes_locator() is None:
- self._axes_class.apply_apsect(self, position)
- else:
- pos = self.get_axes_locator()(self, self._locator_renderer)
- self._axes_class.apply_aspect(self, position=pos)
-
-
- def draw(self, renderer=None, inframe=False):
-
- self._locator_renderer = renderer
-
- self._axes_class.draw(self, renderer, inframe)
-
-
-
-_locatableaxes_classes = {}
-def locatable_axes_factory(axes_class):
-
- new_class = _locatableaxes_classes.get(axes_class)
- if new_class is None:
- new_class = new.classobj("Locatable%s" % (axes_class.__name__),
- (LocatableAxesBase, axes_class),
- {'_axes_class': axes_class})
- _locatableaxes_classes[axes_class] = new_class
-
- return new_class
-
-if hasattr(maxes.Axes, "get_axes_locator"):
- LocatableAxes = maxes.Axes
-else:
- LocatableAxes = locatable_axes_factory(maxes.Axes)
-
-
-def make_axes_locatable(axes):
- if not hasattr(axes, "set_axes_locator"):
- new_class = locatable_axes_factory(type(axes))
- axes.__class__ = new_class
-
- divider = AxesDivider(axes)
- locator = divider.new_locator(nx=0, ny=0)
- axes.set_axes_locator(locator)
-
- return divider
-
-
-def get_demo_image():
- # prepare image
- delta = 0.5
-
- extent = (-3,4,-4,3)
- import numpy as np
- x = np.arange(-3.0, 4.001, delta)
- y = np.arange(-4.0, 3.001, delta)
- X, Y = np.meshgrid(x, y)
- import matplotlib.mlab as mlab
- Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
- Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
- Z = (Z1 - Z2) * 10
-
- return Z, extent
-
-def demo_locatable_axes():
- import matplotlib.pyplot as plt
-
- fig1 = plt.figure(1, (6, 6))
- fig1.clf()
-
- ## PLOT 1
- # simple image & colorbar
- ax = fig1.add_subplot(2, 2, 1)
-
- Z, extent = get_demo_image()
-
- im = ax.imshow(Z, extent=extent, interpolation="nearest")
- cb = plt.colorbar(im)
- plt.setp(cb.ax.get_yticklabels(), visible=False)
-
-
- ## PLOT 2
- # image and colorbar whose location is adjusted in the drawing time.
- # a hard way
-
- divider = SubplotDivider(fig1, 2, 2, 2, aspect=True)
-
- # axes for image
- ax = LocatableAxes(fig1, divider.get_position())
-
- # axes for coloarbar
- ax_cb = LocatableAxes(fig1, divider.get_position())
-
- h = [Size.AxesX(ax), # main axes
- Size.Fixed(0.05), # padding, 0.1 inch
- Size.Fixed(0.2), # colorbar, 0.3 inch
- ]
-
- v = [Size.AxesY(ax)]
-
- divider.set_horizontal(h)
- divider.set_vertical(v)
-
- ax.set_axes_locator(divider.new_locator(nx=0, ny=0))
- ax_cb.set_axes_locator(divider.new_locator(nx=2, ny=0))
-
- fig1.add_axes(ax)
- fig1.add_axes(ax_cb)
-
- ax_cb.yaxis.set_ticks_position("right")
-
- Z, extent = get_demo_image()
-
- im = ax.imshow(Z, extent=extent, interpolation="nearest")
- plt.colorbar(im, cax=ax_cb)
- plt.setp(ax_cb.get_yticklabels(), visible=False)
-
- plt.draw()
- #plt.colorbar(im, cax=ax_cb)
-
-
- ## PLOT 3
- # image and colorbar whose location is adjusted in the drawing time.
- # a easy way
-
- ax = fig1.add_subplot(2, 2, 3)
- divider = make_axes_locatable(ax)
-
- ax_cb = divider.new_horizontal(size="5%", pad=0.05)
- fig1.add_axes(ax_cb)
-
- im = ax.imshow(Z, extent=extent, interpolation="nearest")
- plt.colorbar(im, cax=ax_cb)
- plt.setp(ax_cb.get_yticklabels(), visible=False)
-
-
- ## PLOT 4
- # two images side by sied with fixed padding.
-
- ax = fig1.add_subplot(2, 2, 4)
- divider = make_axes_locatable(ax)
-
- ax2 = divider.new_horizontal(size="100%", pad=0.05)
- fig1.add_axes(ax2)
-
- ax.imshow(Z, extent=extent, interpolation="nearest")
- ax2.imshow(Z, extent=extent, interpolation="nearest")
- plt.setp(ax2.get_yticklabels(), visible=False)
- plt.draw()
- plt.show()
-
-
-def demo_fixed_size_axes():
- import matplotlib.pyplot as plt
-
- fig2 = plt.figure(2, (6, 6))
-
- # The first items are for padding and the second items are for the axes.
- # sizes are in inch.
- h = [Size.Fixed(1.0), Size.Fixed(4.5)]
- v = [Size.Fixed(0.7), Size.Fixed(5.)]
-
- divider = Divider(fig2, (0.0, 0.0, 1., 1.), h, v, aspect=False)
- # the width and height of the rectangle is ignored.
-
- ax = LocatableAxes(fig2, divider.get_position())
- ax.set_axes_locator(divider.new_locator(nx=1, ny=1))
-
- fig2.add_axes(ax)
-
- ax.plot([1,2,3])
-
- plt.draw()
- plt.show()
- #plt.colorbar(im, cax=ax_cb)
-
-
-
-
-
-if __name__ == "__main__":
- demo_locatable_axes()
- demo_fixed_size_axes()
Deleted: trunk/matplotlib/examples/pylab_examples/axes_grid.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/axes_grid.py 2009-04-17 20:40:58 UTC (rev 7051)
+++ trunk/matplotlib/examples/pylab_examples/axes_grid.py 2009-04-18 16:02:56 UTC (rev 7052)
@@ -1,343 +0,0 @@
-import matplotlib.cbook as cbook
-
-import matplotlib.pyplot as plt
-
-from axes_divider import Size, SubplotDivider, LocatableAxes, Divider, get_demo_image
-
-class AxesGrid(object):
-
- def __init__(self, fig, rect,
- nrows_ncols,
- ngrids = None,
- direction="row",
- axes_pad = 0.02,
- axes_class=None,
- add_all=True,
- share_all=False,
- aspect=True,
- label_mode="L",
- colorbar_mode=None,
- colorbar_location="right",
- colorbar_pad=None,
- colorbar_size="5%",
- ):
-
- self._nrows, self._ncols = nrows_ncols
-
- if ngrids is None:
- ngrids = self._nrows * self._ncols
- else:
- if (ngrids > self._nrows * self._ncols) or (ngrids <= 0):
- raise Exception("")
-
- self.ngrids = ngrids
-
- self._axes_pad = axes_pad
-
- self._colorbar_mode = colorbar_mode
- self._colorbar_location = colorbar_location
- if colorbar_pad is None:
- self._colorbar_pad = axes_pad
- else:
- self._colorbar_pad = colorbar_pad
-
- self._colorbar_size = colorbar_size
-
- if direction not in ["column", "row"]:
- raise Exception("")
-
- self._direction = direction
-
-
- if axes_class is None:
- axes_class = LocatableAxes
-
-
- self.axes_all = []
- self.axes_column = [[] for i in range(self._ncols)]
- self.axes_row = [[] for i in range(self._nrows)]
-
- self.cbar_axes = []
-
- h = []
- v = []
- if cbook.is_string_like(rect) or cbook.is_numlike(rect):
- self._divider = SubplotDivider(fig, rect, horizontal=h, vertical=v,
- aspect=aspect)
- elif len(rect) == 3:
- kw = dict(horizontal=h, vertical=v, aspect=aspect)
- self._divider = SubplotDivider(fig, *rect, **kw)
- elif len(rect) == 4:
- self._divider = Divider(fig, rect, horizontal=h, vertical=v,
- aspect=aspect)
- else:
- raise Exception("")
-
-
- rect = self._divider.get_position()
-
- # reference axes
- self._column_refax = [None for i in range(self._ncols)]
- self._row_refax = [None for i in range(self._nrows)]
- self._refax = None
-
- for i in range(self.ngrids):
-
- col, row = self.get_col_row(i)
-
- if share_all:
- sharex = self._refax
- sharey = self._refax
- else:
- sharex = self._column_refax[col]
- sharey = self._row_refax[row]
-
- ax = axes_class(fig, rect, sharex=sharex, sharey=sharey)
-
- if share_all:
- if self._refax is None:
- self._refax = ax
- else:
- if sharex is None:
- self._column_refax[col] = ax
- if sharey is None:
- self._row_refax[row] = ax
-
- self.axes_all.append(ax)
- self.axes_column[col].append(ax)
- self.axes_row[row].append(ax)
-
- cax = axes_class(fig, rect)
- self.cbar_axes.append(cax)
-
- self.axes_llc = self.axes_column[0][-1]
-
- self._update_locators()
-
- if add_all:
- for ax in self.axes_all+self.cbar_axes:
- fig.add_axes(ax)
-
- self.set_label_mode(label_mode)
-
-
- def _update_locators(self):
-
- h = []
-
- h_ax_pos = []
- h_cb_pos = []
- for ax in self._column_refax:
- if h: h.append(Size.Fixed(self._axes_pad))
-
- h_ax_pos.append(len(h))
-
- if ax:
- sz = Size.AxesX(ax)
- else:
- sz = Size.AxesX(self.axes_llc)
- h.append(sz)
-
- if self._colorbar_mode == "each" and self._colorbar_location == "right":
- h.append(Size.from_any(self._colorbar_pad, sz))
- h_cb_pos.append(len(h))
- h.append(Size.from_any(self._colorbar_size, sz))
-
-
- v = []
-
- v_ax_pos = []
- v_cb_pos = []
- for ax in self._row_refax[::-1]:
- if v: v.append(Size.Fixed(self._axes_pad))
- v_ax_pos.append(len(v))
- if ax:
- sz = Size.AxesY(ax)
- else:
- sz = Size.AxesY(self.axes_llc)
- v.append(sz)
-
-
- if self._colorbar_mode == "each" and self._colorbar_location == "top":
- v.append(Size.from_any(self._colorbar_pad, sz))
- v_cb_pos.append(len(v))
- v.append(Size.from_any(self._colorbar_size, sz))
-
-
- for i in range(self.ngrids):
- col, row = self.get_col_row(i)
- #locator = self._divider.new_locator(nx=4*col, ny=2*(self._nrows - row - 1))
- locator = self._divider.new_locator(nx=h_ax_pos[col],
- ny=v_ax_pos[self._nrows -1 - row])
- self.axes_all[i].set_axes_locator(locator)
-
- if self._colorbar_mode == "each":
- if self._colorbar_location == "right":
- locator = self._divider.new_locator(nx=h_cb_pos[col],
- ny=v_ax_pos[self._nrows -1 - row])
- elif self._colorbar_location == "top":
- locator = self._divider.new_locator(nx=h_ax_pos[col],
- ny=v_cb_pos[self._nrows -1 - row])
- self.cbar_axes[i].set_axes_locator(locator)
-
-
- if self._colorbar_mode == "single":
- if self._colorbar_location == "right":
- sz = Size.Fraction(Size.AxesX(self.axes_llc), self._nrows)
- h.append(Size.from_any(self._colorbar_pad, sz))
- h.append(Size.from_any(self._colorbar_size, sz))
- locator = self._divider.new_locator(nx=-2, ny=0, ny1=-1)
- elif self._colorbar_location == "top":
- sz = Size.Fraction(Size.AxesY(self.axes_llc), self._ncols)
- v.append(Size.from_any(self._colorbar_pad, sz))
- v.append(Size.from_any(self._colorbar_size, sz))
- locator = self._divider.new_locator(nx=0, nx1=-1, ny=-2)
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
- self.cbar_axes[0].set_axes_locator(locator)
- self.cbar_axes[0].set_visible(True)
- elif self._colorbar_mode == "each":
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(True)
- else:
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
-
- self._divider.set_horizontal(h)
- self._divider.set_vertical(v)
-
-
-
- def get_col_row(self, n):
- if self._direction == "column":
- col, row = divmod(n, self._nrows)
- else:
- row, col = divmod(n, self._ncols)
-
- return col, row
-
-
- def __getitem__(self, i):
- return self.axes_all[i]
-
-
- def get_geometry(self):
- return self._nrows, self._ncols
-
- def set_axes_pad(self, axes_pad):
- self._axes_pad = axes_pad
-
- def get_axes_pad(self):
- return self._axes_pad
-
- def set_aspect(self, aspect):
- self._divider.set_aspect(aspect)
-
- def get_aspect(self):
- return self._divider.get_aspect()
-
- def set_label_mode(self, mode):
- if mode == "all":
- for ax in self.axes_all:
- [l.set_visible(True) for l in ax.get_xticklabels()]
- [l.set_visible(True) for l in ax.get_yticklabels()]
- elif mode == "L":
- for ax in self.axes_column[0][:-1]:
- [l.set_visible(False) for l in ax.get_xticklabels()]
- [l.set_visible(True) for l in ax.get_yticklabels()]
- ax = self.axes_column[0][-1]
- [l.set_visible(True) for l in ax.get_xticklabels()]
- [l.set_visible(True) for l in ax.get_yticklabels()]
- for col in self.axes_column[1:]:
- for ax in col[:-1]:
- [l.set_visible(False) for l in ax.get_xticklabels()]
- [l.set_visible(False) for l in ax.get_yticklabels()]
- ax = col[-1]
- [l.set_visible(True) for l in ax.get_xticklabels()]
- [l.set_visible(False) for l in ax.get_yticklabels()]
- elif mode == "1":
- for ax in self.axes_all:
- [l.set_visible(False) for l in ax.get_xticklabels()]
- [l.set_visible(False) for l in ax.get_yticklabels()]
- ax = self.axes_llc
- [l.set_visible(True) for l in ax.get_xticklabels()]
- [l.set_visible(True) for l in ax.get_yticklabels()]
-
-
-
-if __name__ == "__main__":
- F = plt.figure(1, (9, 3.5))
- F.clf()
-
- F.subplots_adjust(left=0.05, right=0.98)
-
- grid = AxesGrid(F, 131, # similar to subplot(111)
- nrows_ncols = (2, 2),
- direction="row",
- axes_pad = 0.05,
- add_all=True,
- label_mode = "1",
- )
-
- Z, extent = get_demo_image()
- plt.ioff()
- for i in range(4):
- im = grid[i].imshow(Z, extent=extent, interpolation="nearest")
-
- # This only affects axes in first column and second row as share_all = False.
- grid.axes_llc.set_xticks([-2, 0, 2])
- grid.axes_llc.set_yticks([-2, 0, 2])
- plt.ion()
-
-
- grid = AxesGrid(F, 132, # similar to subplot(111)
- nrows_ncols = (2, 2),
- direction="row",
- axes_pad = 0.0,
- add_all=True,
- share_all=True,
- label_mode = "1",
- colorbar_mode="single",
- )
-
- Z, extent = get_demo_image()
- plt.ioff()
- for i in range(4):
- im = grid[i].imshow(Z, extent=extent, interpolation="nearest")
- plt.colorbar(im, cax = grid.cbar_axes[0])
- plt.setp(grid.cbar_axes[0].get_yticklabels(), visible=False)
-
- # This affects all axes as share_all = True.
- grid.axes_llc.set_xticks([-2, 0, 2])
- grid.axes_llc.set_yticks([-2, 0, 2])
-
- plt.ion()
-
-
-
- grid = AxesGrid(F, 133, # similar to subplot(122)
- nrows_ncols = (2, 2),
- direction="row",
- axes_pad = 0.1,
- add_all=True,
- label_mode = "1",
- share_all = True,
- colorbar_location="top",
- colorbar_mode="each",
- colorbar_size="7%",
- colorbar_pad="2%",
- )
- plt.ioff()
- for i in range(4):
- im = grid[i].imshow(Z, extent=extent, interpolation="nearest")
- plt.colorbar(im, cax = grid.cbar_axes[i],
- orientation="horizontal")
- grid.cbar_axes[i].xaxis.set_ticks_position("top")
- plt.setp(grid.cbar_axes[i].get_xticklabels(), visible=False)
-
- # This affects all axes as share_all = True.
- grid.axes_llc.set_xticks([-2, 0, 2])
- grid.axes_llc.set_yticks([-2, 0, 2])
-
- plt.ion()
- plt.draw()
Modified: trunk/matplotlib/lib/matplotlib/offsetbox.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/offsetbox.py 2009-04-17 20:40:58 UTC (rev 7051)
+++ trunk/matplotlib/lib/matplotlib/offsetbox.py 2009-04-18 16:02:56 UTC (rev 7052)
@@ -782,7 +782,8 @@
explicitly specify the bbox_to_anchor.
"""
- def __init__(self, loc, pad=0.4, borderpad=0.5,
+ def __init__(self, loc,
+ pad=0.4, borderpad=0.5,
child=None, prop=None, frameon=True,
bbox_to_anchor=None,
bbox_transform=None):
@@ -801,7 +802,6 @@
'upper center' : 9,
'center' : 10,
-
pad : pad around the child for drawing a frame. given in
fraction of fontsize.
@@ -813,12 +813,15 @@
frameon : draw a frame box if True.
- bbox_to_anchor : bbox to anchor. If None, use axes.bbox.
+ bbox_to_anchor : bbox to anchor. Use self.axes.bbox if None.
+ bbox_transform : with which the bbox_to_anchor will be transformed.
+
"""
super(AnchoredOffsetbox, self).__init__()
+ self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)
self.set_child(child)
self.loc = loc
@@ -838,8 +841,6 @@
)
self.patch.set_boxstyle("square",pad=0)
self._drawFrame = frameon
- #self._parent_bbox = bbox_to_anchor
- self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)
@@ -878,13 +879,14 @@
else:
transform = self._bbox_to_anchor_transform
if transform is None:
- transform = BboxTransformTo(self.axes.bbox)
+ return self._bbox_to_anchor
+ else:
+ return TransformedBbox(self._bbox_to_anchor,
+ transform)
+
- return TransformedBbox(self._bbox_to_anchor,
- transform)
-
def set_bbox_to_anchor(self, bbox, transform=None):
"""
set the bbox that the child will be anchored.
@@ -892,12 +894,9 @@
*bbox* can be a Bbox instance, a list of [left, bottom, width,
height], or a list of [left, bottom] where the width and
height will be assumed to be zero. The bbox will be
- transformed to display coordinate by the given transform. If
- transform is None, axes.transAxes will be use.
+ transformed to display coordinate by the given transform.
"""
- if bbox is None:
- self._bbox_to_anchor = None
- elif isinstance(bbox, BboxBase):
+ if bbox is None or isinstance(bbox, BboxBase):
self._bbox_to_anchor = bbox
else:
try:
Modified: trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py 2009-04-17 20:40:58 UTC (rev 7051)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py 2009-04-18 16:02:56 UTC (rev 7052)
@@ -78,45 +78,3 @@
-if __name__ == "__main__":
- import matplotlib.pyplot as plt
- from matplotlib.patches import Circle
-
- #import matplotlib.offsetbox
- #matplotlib.offsetbox.DEBUG=False
-
- #ax = plt.subplot(1,1,1)
- plt.clf()
- plt.cla()
- plt.draw()
- ax = plt.gca()
- ax.set_aspect(1.)
-
- at = AnchoredText("Figure 1a",
- loc=2, frameon=True)
- at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
- ax.add_artist(at)
-
- ada = AnchoredDrawingArea(20, 20, 0, 0,
- loc=1, pad=0., frameon=False)
- p = Circle((10, 10), 10)
- ada.da.add_artist(p)
- ax.add_artist(ada)
-
-
- as = AnchoredSizeBar(ax, 0.1, r"1$^{\prime}$",
- loc=8,
- pad=0.1, borderpad=0.5, sep=5,
- frameon=False)
- ax.add_artist(as)
-
-
- ae = AnchoredEllipse(ax, width=0.1, height=0.15, angle=0.,
- loc=3, pad=0.5, borderpad=0.4, frameon=True)
-
- ax.add_artist(ae)
-
- plt.draw()
- plt.show()
-
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-04-17 20:41:11
|
Revision: 7051
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7051&view=rev
Author: jdh2358
Date: 2009-04-17 20:40:58 +0000 (Fri, 17 Apr 2009)
Log Message:
-----------
use 0 for default in rec join outer join if no default given
Modified Paths:
--------------
trunk/matplotlib/examples/misc/rec_join_demo.py
Modified: trunk/matplotlib/examples/misc/rec_join_demo.py
===================================================================
--- trunk/matplotlib/examples/misc/rec_join_demo.py 2009-04-17 20:40:29 UTC (rev 7050)
+++ trunk/matplotlib/examples/misc/rec_join_demo.py 2009-04-17 20:40:58 UTC (rev 7051)
@@ -19,7 +19,7 @@
print "r2:"
print mlab.rec2txt(r2)
-defaults = {'marker':-1, '_close':np.NaN, 'low':-4444.}
+defaults = {'marker':-1, 'close':np.NaN, 'low':-4444.}
for s in ('inner', 'outer', 'leftouter'):
rec = mlab.rec_join(['date', 'high'], r1, r2,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-04-17 20:40:42
|
Revision: 7050
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7050&view=rev
Author: jdh2358
Date: 2009-04-17 20:40:29 +0000 (Fri, 17 Apr 2009)
Log Message:
-----------
use 0 for default in rec join outer join if no default given
Modified Paths:
--------------
trunk/matplotlib/doc/sphinxext/gen_gallery.py
trunk/matplotlib/examples/misc/rec_join_demo.py
trunk/matplotlib/lib/matplotlib/backend_bases.py
trunk/matplotlib/lib/matplotlib/mlab.py
Modified: trunk/matplotlib/doc/sphinxext/gen_gallery.py
===================================================================
--- trunk/matplotlib/doc/sphinxext/gen_gallery.py 2009-04-17 20:20:07 UTC (rev 7049)
+++ trunk/matplotlib/doc/sphinxext/gen_gallery.py 2009-04-17 20:40:29 UTC (rev 7050)
@@ -38,7 +38,7 @@
print
print "generating gallery: ",
data = []
- for subdir in ('api', 'pylab_examples', 'widgets'):
+ for subdir in ('api', 'pylab_examples', 'widgets', 'mplot3d'):
origdir = os.path.join('build', rootdir, subdir)
thumbdir = os.path.join(outdir, rootdir, subdir, 'thumbnails')
if not os.path.exists(thumbdir):
Modified: trunk/matplotlib/examples/misc/rec_join_demo.py
===================================================================
--- trunk/matplotlib/examples/misc/rec_join_demo.py 2009-04-17 20:20:07 UTC (rev 7049)
+++ trunk/matplotlib/examples/misc/rec_join_demo.py 2009-04-17 20:40:29 UTC (rev 7050)
@@ -6,8 +6,8 @@
r.sort()
r1 = r[-10:]
-# Create a new array
-r2 = np.empty(12, dtype=[('date', '|O4'), ('high', np.float),
+# Create a new array
+r2 = np.empty(12, dtype=[('date', '|O4'), ('high', np.float),
('marker', np.float)])
r2 = r2.view(np.recarray)
r2.date = r.date[-17:-5]
@@ -19,9 +19,9 @@
print "r2:"
print mlab.rec2txt(r2)
-defaults = {'marker':-1, 'close':np.NaN, 'low':-4444.}
+defaults = {'marker':-1, '_close':np.NaN, 'low':-4444.}
for s in ('inner', 'outer', 'leftouter'):
- rec = mlab.rec_join(['date', 'high'], r1, r2,
- jointype=s, defaults=defaults)
+ rec = mlab.rec_join(['date', 'high'], r1, r2,
+ jointype=s, defaults=defaults)
print "\n%sjoin :\n%s" % (s, mlab.rec2txt(rec))
Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backend_bases.py 2009-04-17 20:20:07 UTC (rev 7049)
+++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2009-04-17 20:40:29 UTC (rev 7050)
@@ -1058,7 +1058,7 @@
under = self.figure.hitlist(ev)
enter = [a for a in under if a not in self._active]
leave = [a for a in self._active if a not in under]
- print "within:"," ".join([str(x) for x in under])
+ #print "within:"," ".join([str(x) for x in under])
#print "entering:",[str(a) for a in enter]
#print "leaving:",[str(a) for a in leave]
# On leave restore the captured colour
@@ -1520,6 +1520,10 @@
- 'pick_event'
- 'resize_event'
- 'scroll_event'
+ - 'figure_enter_event',
+ - 'figure_leave_event',
+ - 'axes_enter_event',
+ - 'axes_leave_event'
For the location events (button and key press/release), if the
mouse is over the axes, the variable ``event.inaxes`` will be
Modified: trunk/matplotlib/lib/matplotlib/mlab.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/mlab.py 2009-04-17 20:20:07 UTC (rev 7049)
+++ trunk/matplotlib/lib/matplotlib/mlab.py 2009-04-17 20:40:29 UTC (rev 7050)
@@ -2303,6 +2303,17 @@
newrec = np.empty(common_len + left_len + right_len, dtype=newdtype)
+ if defaults is not None:
+ for thiskey in defaults:
+ if thiskey not in newdtype.names:
+ warnings.warn('rec_join defaults key="%s" not in new dtype names "%s"'%(
+ thiskey, newdtype.names))
+
+ for name in newdtype.names:
+ dt = newdtype[name]
+ if dt.kind in ('f', 'i'):
+ newrec[name] = 0
+
if jointype != 'inner' and defaults is not None: # fill in the defaults enmasse
newrec_fields = newrec.dtype.fields.keys()
for k, v in defaults.items():
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2009-04-17 20:20:18
|
Revision: 7049
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7049&view=rev
Author: leejjoon
Date: 2009-04-17 20:20:07 +0000 (Fri, 17 Apr 2009)
Log Message:
-----------
removing axes_grid.inset_locator.
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/offsetbox.py
Removed Paths:
-------------
trunk/matplotlib/lib/mpl_toolkits/axes_grid/inset_locator.py
Modified: trunk/matplotlib/lib/matplotlib/offsetbox.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/offsetbox.py 2009-04-17 19:35:59 UTC (rev 7048)
+++ trunk/matplotlib/lib/matplotlib/offsetbox.py 2009-04-17 20:20:07 UTC (rev 7049)
@@ -19,7 +19,7 @@
import matplotlib.artist as martist
import matplotlib.text as mtext
import numpy as np
-from matplotlib.transforms import Bbox, TransformedBbox, BboxTransformTo
+from matplotlib.transforms import Bbox, BboxBase, TransformedBbox, BboxTransformTo
from matplotlib.font_manager import FontProperties
from matplotlib.patches import FancyBboxPatch
@@ -897,7 +897,7 @@
"""
if bbox is None:
self._bbox_to_anchor = None
- elif isinstance(bbox, Bbox):
+ elif isinstance(bbox, BboxBase):
self._bbox_to_anchor = bbox
else:
try:
Deleted: trunk/matplotlib/lib/mpl_toolkits/axes_grid/inset_locator.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/inset_locator.py 2009-04-17 19:35:59 UTC (rev 7048)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/inset_locator.py 2009-04-17 20:20:07 UTC (rev 7049)
@@ -1,191 +0,0 @@
-from matplotlib.offsetbox import AnchoredOffsetbox
-
-
-import matplotlib.transforms as mtrans
-
-class InsetPosition(object):
- def __init__(self, parent, lbwh):
- self.parent = parent
- self.lbwh = lbwh # position of the inset axes in the normalized coordinate of the parent axes
-
- def __call__(self, ax, renderer):
- bbox_parent = self.parent.get_position(original=False)
- trans = mtrans.BboxTransformTo(bbox_parent)
- bbox_inset = mtrans.Bbox.from_bounds(*self.lbwh)
- bb = mtrans.TransformedBbox(bbox_inset, trans)
- return bb
-
-
-class AnchoredLocatorBase(AnchoredOffsetbox):
- def __init__(self, parent_bbox, offsetbox, loc, **kwargs):
-
- for k in ["parent_bbox", "child", "pad"]:
- if kwargs.has_key(k):
- raise ValueError("%s paramter should not be provided" % (k,))
-
- kwargs["pad"] = 0.
- kwargs["child"] = None
- kwargs["parent_bbox"] = parent_bbox
-
- super(AnchoredLocatorBase, self).__init__(loc, **kwargs)
-
-
- def draw(self, renderer):
- raise RuntimeError("No draw method should be called")
-
-
- def __call__(self, ax, renderer):
-
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- self._update_offset_func(renderer, fontsize)
-
- width, height, xdescent, ydescent = self.get_extent(renderer)
-
- px, py = self.get_offset(width, height, 0, 0)
- bbox_canvas = mtrans.Bbox.from_bounds(px, py, width, height)
- tr = ax.figure.transFigure.inverted()
- bb = mtrans.TransformedBbox(bbox_canvas, tr)
-
- return bb
-
-
-class AnchoredOffsetBoxLocator(AnchoredLocatorBase):
- def __init__(self, parent_bbox, offsetbox, loc, **kwargs):
-
- for k in ["parent_bbox", "child", "pad"]:
- if kwargs.has_key(k):
- raise ValueError("%s paramter should not be provided" % (k,))
-
- kwargs["pad"] = 0.
- kwargs["child"] = offsetbox
- kwargs["parent_bbox"] = parent_bbox
-
- super(AnchoredOffsetBoxLocator, self).__init__(loc, **kwargs)
-
-
-
-from mpl_toolkits.axes_grid.axes_divider import Size
-
-class AnchoredSizeLocator(AnchoredLocatorBase):
- def __init__(self, parent_bbox, x_size, y_size,
- loc, **kwargs):
-
- self.axes = None
- self.x_size = Size.from_any(x_size)
- self.y_size = Size.from_any(y_size)
-
- super(AnchoredSizeLocator, self).__init__(parent_bbox, None, loc, **kwargs)
-
- def get_extent(self, renderer):
-
- x, y, w, h = self._parent_bbox.bounds
-
- dpi = renderer.points_to_pixels(72.)
-
- r, a = self.x_size.get_size(renderer)
- width = w*r + a*dpi
-
- r, a = self.y_size.get_size(renderer)
- height = h*r + a*dpi
- xd, yd = 0, 0
-
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- pad = self.pad * fontsize
-
- return width+2*pad, height+2*pad, xd+pad, yd+pad
-
-
- def __call__(self, ax, renderer):
-
- self.axes = ax
- return super(AnchoredSizeLocator, self).__call__(ax, renderer)
-
-
-class AnchoredZoomLocator(AnchoredLocatorBase):
- def __init__(self, parent_axes, zoom,
- loc, **kwargs):
-
- self.parent_axes = parent_axes
- self.zoom = zoom
-
- super(AnchoredZoomLocator, self).__init__(parent_axes.bbox, None, loc, **kwargs)
-
- self.axes = None
-
-
- def get_extent(self, renderer):
-
- bb = mtrans.TransformedBbox(self.axes.viewLim, self.parent_axes.transData)
-
- x, y, w, h = bb.bounds
-
- xd, yd = 0, 0
-
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- pad = self.pad * fontsize
-
- return w*self.zoom+2*pad, h*self.zoom+2*pad, xd+pad, yd+pad
-
-
- def __call__(self, ax, renderer):
-
- self.axes = ax
- return super(AnchoredZoomLocator, self).__call__(ax, renderer)
-
-
-# class AnchoredAxesBoxLocator(AnchoredOffsetBoxLocator):
-# def __init__(self, ax, x0, x1, y0, y1, zoom, zoomy=None,
-# parent_bbox, width_inch, height_inch,
-# loc, **kwargs):
-
-# self.width_inch = width_inch
-# self.height_inch = height_inch
-
-# super(AnchoredFixedBoxLocator, self).__init__(parent_bbox, None, loc, **kwargs)
-
-# def get_extent(self, renderer):
-
-# w =self.width_inch * renderer.points_to_pixels(72.)
-# h =self.height_inch * renderer.points_to_pixels(72.)
-# xd, yd = 0, 0
-
-# fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
-# pad = self.pad * fontsize
-
-# return w+2*pad, h+2*pad, xd+pad, yd+pad
-
-
-if __name__ == "__main__":
-
- import matplotlib.pyplot as plt
-
- fig = plt.figure(1)
- ax = fig.add_subplot(1,2,1)
- ax.set_aspect(1.)
-
- # width : 30% of parent_bbox (ax.bbox)
- # height : 1 inch
- axes_locator = AnchoredSizeLocator(ax.bbox, "30%", 1, loc=1)
-
- axins = fig.add_axes([0, 0, 1, 1], label="inset1")
- axins.set_axes_locator(axes_locator)
-
-
-
-
- ax = fig.add_subplot(1,2,2)
- ax.set_aspect(1.)
-
- # inset axes has a data scale of the parent axes multiplied by a zoom factor
- axes_locator = AnchoredZoomLocator(ax, zoom=0.5, loc=1)
-
- axins = fig.add_axes([0, 0, 0.5, 1], label="inset2")
- #axins = plt.axes([0, 0, 1, 1])
- axins.set_axes_locator(axes_locator)
-
-
-
-
-
-
- #locator = AnchoredBoxLocator(parent_bbox, Fixed(1.), Scaled(0.2), loc=1)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2009-04-17 19:36:09
|
Revision: 7048
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7048&view=rev
Author: leejjoon
Date: 2009-04-17 19:35:59 +0000 (Fri, 17 Apr 2009)
Log Message:
-----------
axes_grid toolkit initial check in
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/doc/users/toolkits.rst
trunk/matplotlib/setup.py
Added Paths:
-----------
trunk/matplotlib/doc/_static/demo_axes_grid.png
trunk/matplotlib/doc/mpl_toolkits/
trunk/matplotlib/doc/mpl_toolkits/axes_grid/
trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures
trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst
trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/
trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axes_divider.rst
trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst
trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst
trunk/matplotlib/examples/axes_grid/
trunk/matplotlib/examples/axes_grid/demo_axes_divider.py
trunk/matplotlib/examples/axes_grid/demo_axes_grid.py
trunk/matplotlib/examples/axes_grid/demo_axes_rgb.py
trunk/matplotlib/examples/axes_grid/demo_fixed_size_axes.py
trunk/matplotlib/examples/axes_grid/demo_image.py
trunk/matplotlib/examples/axes_grid/demo_parasite_axes.py
trunk/matplotlib/examples/axes_grid/demo_parasite_axes2.py
trunk/matplotlib/examples/axes_grid/parasite_simple.py
trunk/matplotlib/examples/axes_grid/parasite_simple2.py
trunk/matplotlib/examples/axes_grid/scatter_hist.py
trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py
trunk/matplotlib/examples/axes_grid/simple_axes_divider1.py
trunk/matplotlib/examples/axes_grid/simple_axes_divider2.py
trunk/matplotlib/examples/axes_grid/simple_axes_divider3.py
trunk/matplotlib/examples/axes_grid/simple_axesgrid.py
trunk/matplotlib/examples/axes_grid/simple_axesgrid2.py
trunk/matplotlib/examples/axes_grid/simple_axisline.py
trunk/matplotlib/examples/axes_grid/simple_axisline2.py
trunk/matplotlib/examples/axes_grid/simple_axisline3.py
trunk/matplotlib/examples/axes_grid/simple_axisline4.py
trunk/matplotlib/examples/axes_grid/simple_rgb.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/
trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_grid.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_rgb.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/axislines.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/inset_locator.py
trunk/matplotlib/lib/mpl_toolkits/axes_grid/parasite_axes.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-04-17 16:34:09 UTC (rev 7047)
+++ trunk/matplotlib/CHANGELOG 2009-04-17 19:35:59 UTC (rev 7048)
@@ -1,5 +1,7 @@
======================================================================
+2009-04-17 Initial check-in of the axes_grid toolkit. - JJL
+
2009-04-17 Added a support for bbox_to_anchor in
offsetbox.AnchoredOffsetbox. Improved a documentation.
- JJL
Added: trunk/matplotlib/doc/_static/demo_axes_grid.png
===================================================================
(Binary files differ)
Property changes on: trunk/matplotlib/doc/_static/demo_axes_grid.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures (rev 0)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1 @@
+link ../../../examples/axes_grid/
\ No newline at end of file
Property changes on: trunk/matplotlib/doc/mpl_toolkits/axes_grid/figures
___________________________________________________________________
Added: svn:special
+ *
Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst (rev 0)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/index.rst 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,23 @@
+
+.. _toolkit_axesgrid-index:
+
+Matplotlib AxesGrid Toolkit
+===========================
+
+The matplotlib AxesGrid toolkit is a collection of helper classes to
+ease displaying multiple images in matplotlib. While the aspect
+parameter in matplotlib adjust the position of the single axes,
+AxesGrid toolkit provides a framework to adjust the position of
+multiple axes according to their aspects.
+
+.. plot:: mpl_toolkits/axes_grid/figures/demo_axes_grid.py
+
+
+Documentation
+=============
+
+.. toctree::
+ :maxdepth: 2
+
+ users/index.rst
+
Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axes_divider.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axes_divider.rst (rev 0)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/axes_divider.rst 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,89 @@
+AxesDivider
+===========
+
+The axes_divider module provide helper classes to adjust the axes
+positions of set of images in the drawing time.
+
+* *Size* This provides a classese of units that the size of each axes
+ will be determined. For example, you can specify a fixed size
+
+* *Divider* this is the class that is used calculates the axes
+ position. It divides the given renctangular area into several
+ areas. You intialize the divider by setting the horizontal and
+ vertical list of sizes that the division will be based on. You then
+ use the new_locator method, whose return value is a callable object
+ that can be used to set the axes_locator of the axes.
+
+
+You first initialize the divider by specifying its grids, i.e., horiz and vert.
+
+for example,::
+
+ rect = [0.2, 0.2, 0.6, 0.6]
+ horiz=[h0, h1, h2, h3]
+ vert=[v0, v1, v2]
+ divider = Divider(fig, rect, horiz, vert)
+
+where, rect is a bounds of the box that will be divided and h0,..h3,
+v0,..v2 need to be an callable object that returns a tuple of two
+floats. The first float is the relative size, and the second float is
+the absolute size. Use of the subclasses contained in the Size class
+is recommanded. Lets' consider a following grid.
+
++-----+-----+-----+-----+
+| v0 | | | |
++-----+-----+-----+-----+
+| v1 | | | |
++-----+-----+-----+-----+
+|h0,v2| h1 | h2 | h3 |
++-----+-----+-----+-----+
+
+
+* h0 => 2, 0
+* h1 => 0, 2
+* h2 => 0, 3
+
+The height of the bottom row is always 2 (axes_divider internally
+assumes that the unit is inch). The first and the second rows with
+height ration of 2:3. For example, if the total height of the grid 6,
+the the first and second row will each occupy 2/(2+3) and 3/(2+3) of
+(6-1) inches. The widths of columns (horiz) will be similarly
+determined. When aspect ratio is set, the total height (or width) will
+be adjusted accordingly.
+
+
+The Size class is a container class that contains several sub-class
+that can be used to set the horiz and vert. For example, for the
+vertical configuration above will be::
+
+ from Size import Fixed, Scaled
+ vert = [Fixed(2), Scaled(2), Scaled(3)]
+
+After you set up the divider object, you
+Then you create a locator instance which will be given to the axes.::
+
+ locator = divider.new_locator(nx=0, ny=1)
+ ax.set_axes_locator(locator)
+
+The return value of the new_locator method is a instance of the
+AxesLocator class. It is a callable object that will return the
+location and size of the cell at the first column and the second row.
+You may create a locator that spans over multiple cells.::
+
+ locator = divider.new_locator(nx=0, nx=2, ny=1)
+
+The above locator, when called, will return the position and size of
+the cells spanning the first and second column and the first row. You
+may consider it as [0:2, 1].
+
+See the example,
+
+.. plot:: mpl_toolkits/axes_grid/figures/simple_axes_divider2.py
+ :include-source:
+
+You can adjust the size of the each axes accroding to their x or y
+data limits (AxesX and AxesY), similar to the axes aspect parameter.
+
+.. plot:: mpl_toolkits/axes_grid/figures/simple_axes_divider3.py
+ :include-source:
+
Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst (rev 0)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/index.rst 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,12 @@
+.. _axes_grid_users-guide-index:
+
+################################################
+ The Matplotlib AxesGrid Toolkit User's Guide
+################################################
+
+:Release: |version|
+:Date: |today|
+
+.. toctree::
+
+ overview.rst
Added: trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst
===================================================================
--- trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst (rev 0)
+++ trunk/matplotlib/doc/mpl_toolkits/axes_grid/users/overview.rst 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,349 @@
+=================
+AxesGrid Overview
+=================
+
+The matplotlib AxesGrid toolkit is a collection of helper classes,
+mainly to ease displaying (multiple) images in matplotlib.
+
+.. contents::
+ :depth: 1
+ :local:
+
+`AxesGrid`_, `RGB Axes`_ and `AxesDivider`_ are helper classes that
+deals with adjusting the location of (multiple) Axes, mainly for
+displaying images. It provides a framework to adjust the position of
+multiple axes at the drawing time. `ParasiteAxes`_ provides twinx(or
+twiny)-like features so that you can plot different data (e.g.,
+different y-scale) in a same Axes. `AxisLine`_ is a custom Axes
+class. Unlike default Axes in matpotlib, each axis (left, right, top
+and bottom) is associated with a separate artist (which is resposible
+to draw axis-line, ticks, ticklabels, label). `AnchoredArtists`_
+includes custom artists which are placed at some anchored position,
+like the legend.
+
+
+
+
+AxesGrid
+========
+
+
+A class that creates a grid of Axes. In matplotlib, the axes location
+(and size) is specified in the normalized figure coordinates. This may
+not be ideal for images that needs to be displayed with a given aspect
+ratio. For example, displaying images of a same size with some fixed
+padding between them cannot be easily done in matplotlib. AxesGrid is
+used in such case.
+
+.. plot:: mpl_toolkits/axes_grid/figures/simple_axesgrid.py
+ :include-source:
+
+* The postion of each axes is determined at the drawing time (see
+ `AxesDivider`_), so that the size of the entire grid fits in the
+ given rectangle (like the aspec of axes). Note that in this example,
+ the paddings between axes are fixed even if you changes the figure
+ size.
+
+* axes in the same column has a same axes width (in figure
+ coordinate), and similarly, axes in the same row has a same
+ height. The widths (height) of the axes in the same row (column) are
+ scaled according to their view limits (xlim or ylim).
+
+ .. plot:: mpl_toolkits/axes_grid/figures/simple_axesgrid2.py
+ :include-source:
+
+* xaxis are shared among axes in a same column. Similarly, yaxis are
+ shared among axes in a same row. Therefore, changing axis properties
+ (view limits, tick location, etc. either by plot commands or using
+ your mouse in interactive backends) of one axes will affect all
+ other shared axes.
+
+
+
+When initialized, AxesGrid creates given number (*ngrids* or *ncols* *
+*nrows* if *ngrids* is None) of Axes instances. A sequence-like
+interface is provided to access the individual Axes instances (e.g.,
+grid[0] is the first Axes in the grid. See below for the order of
+axes).
+
+
+
+AxesGrid takes following arguments,
+
+
+ ============= ======== ================================================
+ Name Default Description
+ ============= ======== ================================================
+ fig
+ rect
+ nrows_ncols number of rows and cols. e.g. (2,2)
+ ngrids None number of grids. nrows x ncols if None
+ direction "row" increasing direction of axes number. [row|column]
+ axes_pad 0.02 pad between axes in inches
+ add_all True Add axes to figures if True
+ share_all False xaxis & yaxis of all axes are shared if True
+ aspect True aspect of axes
+ label_mode "L" location of tick labels thaw will be displayed.
+ "1" (only the lower left axes),
+ "L" (left most and bottom most axes),
+ or "all".
+ cbar_mode None [None|single|each]
+ cbar_location "right" [right|top]
+ cbar_pad None pad between image axes and colorbar axes
+ cbar_size "5%" size of the colorbar
+ axes_class None
+ ============= ======== ================================================
+
+ *rect*
+ specifies the location of the grid. You can either specify
+ coordinates of the rectangle to be used (e.g., (0.1, 0.1, 0.8, 0.8)
+ as in the Axes), or the subplot-like position (e.g., "121").
+
+ *direction*
+ means the increasing direction of the axes number.
+
+ *aspect*
+ By default (False), widths and heigths of axes in the grid are
+ scaled independently. If True, they are scaled according to their
+ data limits (similar to aspect parameter in mpl).
+
+ *share_all*
+ if True, xaxis and yaxis of all axes are shared.
+
+ *direction*
+ direction of increasing axes number. For "row",
+
+ +---------+---------+
+ | grid[0] | grid[1] |
+ +---------+---------+
+ | grid[2] | grid[3] |
+ +---------+---------+
+
+ For "column",
+
+ +---------+---------+
+ | grid[0] | grid[2] |
+ +---------+---------+
+ | grid[1] | grid[3] |
+ +---------+---------+
+
+You can also create a colorbar (or colobars). You can have colorbar
+for each axes (cbar_mode="each"), or you can have a single colorbar
+for the grid (cbar_mode="single"). The colorbar can be placed on your
+right, or top. The axes for each colorbar is stored as a *cbar_axes*
+attribute.
+
+
+
+The examples below show what you can do with AxesGrid.
+
+.. plot:: mpl_toolkits/axes_grid/figures/demo_axes_grid.py
+
+
+RGB Axes
+========
+
+RGBAxes is a helper clase to conveniently show RGB composite
+images. Like AxesGrid, the location of axes are adjusted so that the
+area occupied by them fits in a given rectangle. Also, the xaxis and
+yaxis of each axes are shared. ::
+
+ from mpl_toolkits.axes_grid.axes_rgb import RGBAxes
+
+ fig = plt.figure(1)
+ ax = RGBAxes(fig, [0.1, 0.1, 0.8, 0.8])
+
+ r, g, b = get_rgb() # r,g,b are 2-d images
+ ax.imshow_rgb(r, g, b,
+ origin="lower", interpolation="nearest")
+
+
+.. plot:: mpl_toolkits/axes_grid/figures/simple_rgb.py
+
+
+
+AxesDivider
+===========
+
+Behind the scene, the AxesGrid class and the RGBAxes class utilize the
+AxesDivider class, whose role is to calculate the location of the axes
+at drawing time. While a more about the AxesDivider is (will be)
+explained in (yet to be written) AxesDividerGuide, direct use of the
+AxesDivider class will not be necessary for most users. The
+axes_divider module provides a helper function make_axes_locatable,
+which can be useful. It takes a exisitng axes instance and create a
+divider for it. ::
+
+ ax = subplot(1,1,1)
+ divider = make_axes_locatable(ax)
+
+
+
+
+*make_axes_locatable* returns an isntance of the AxesLocator class,
+derived from the Locator. It has *new_vertical*, and *new_horizontal*
+methods. The *new_vertical* (*new_horizontal*) creates a new axes on
+the upper (right) side of the original axes.
+
+
+scatter_hist.py with AxesDivider
+--------------------------------
+
+The "scatter_hist.py" example in mpl can be rewritten using
+*make_axes_locatable*. ::
+
+ from mpl_toolkits.axes_grid import make_axes_locatable
+
+ axScatter = subplot(111)
+ divider = make_axes_locatable(axScatter)
+
+ # create new axes on the right and on the top of the current axes
+ # The first argument of the new_vertical(new_horizontal) method is
+ # the height (width) of the axes to be created in inches.
+ axHistx = divider.new_vertical(1.2, pad=0.1, sharex=axScatter)
+ axHisty = divider.new_horizontal(1.2, pad=0.1, sharey=axScatter)
+
+ fig.add_axes(axHistx)
+ fig.add_axes(axHisty)
+
+
+ # the scatter plot:
+ axScatter.scatter(x, y)
+ axScatter.set_aspect(1.)
+
+ # histograms
+ bins = np.arange(-lim, lim + binwidth, binwidth)
+ axHistx.hist(x, bins=bins)
+ axHisty.hist(y, bins=bins, orientation='horizontal')
+
+See the full source code below.
+
+
+.. plot:: mpl_toolkits/axes_grid/figures/scatter_hist.py
+
+
+The scatter_hist using the AxesDivider has some advantage over the
+original scatter_hist.py in mpl. For example, you can set the aspect
+ratio of the scatter plot, even with the x-axis or y-axis is shared
+accordingly.
+
+
+ParasiteAxes
+============
+
+The ParasiteAxes is a axes whose location is identical to its host
+axes. The location is adjusted in the drawing time, thus it works even
+if the host change its location (e.g., images). It provides *twinx*,
+*twiny* (similar to twinx and twiny in the matplotlib). Also it
+provides *twin*, which takes an arbitraty tranfromation that maps
+between the data coordinates of the host and the parasite axes.
+Artists in each axes are mergred and drawn acrroding to their zorder.
+It also modifies some behavior of the axes. For example, color cycle
+for plot lines are shared between host and parasites. Also, the legend
+command in host, creates a legend that includes lines in the parasite
+axes.
+
+Example 1. twinx
+----------------
+
+.. plot:: mpl_toolkits/axes_grid/figures/parasite_simple.py
+ :include-source:
+
+Example 2. twin
+---------------
+
+A more sophiscated example using twin. Note that if you change the
+x-limit in the host axes, the x-limit of the parasite axes will change
+accordingly.
+
+
+.. plot:: mpl_toolkits/axes_grid/figures/parasite_simple2.py
+
+
+
+AxisLine
+========
+
+AxisLine is a custom (and very experimenta) Axes class, where each
+axis (left, right, top and bottom) have a separate artist associated
+(which is resposible to draw axis-line, ticks, ticklabels, label).
+Also, you can create your own axis, which can pass through a fixed
+position in the axes coordinate, or a fixed position in the data
+coordinate (i.e., the axis floats around when viewlimit changes).
+
+Most of the class in this toolkit is based on this class. And it has
+not been tested extensibly. You may go back to the original mpl
+behanvior, by ::
+
+ ax.toggle_axisline(False)
+
+The axes class, by default, provides 4 artists which are responsible
+to draw axis in "left","right","bottom" and "top". They are accessed
+as ax.axis["left"], ax.axis["right"], and so on, i.e., ax.axis is a
+dictionary that contains artists (note that ax.axis is still a
+callable methods and it behaves as an original Axes.axis method in
+mpl).
+
+For example, you can hide right, and top axis by ::
+
+ ax.axis["right"].set_visible(False)
+ ax.axis["top"].set_visible(False)
+
+
+.. plot:: mpl_toolkits/axes_grid/figures/simple_axisline3.py
+
+
+SubplotZero gives you two more additional (floating?) axis of x=0 and
+y=0 (in data coordinate)
+
+.. plot:: mpl_toolkits/axes_grid/figures/simple_axisline2.py
+ :include-source:
+
+
+Axisline with ParasiteAxes
+--------------------------
+
+Most of axes class in the axes_grid toolkit, including ParasiteAxes,
+is based on the Axisline axes. The combination of the two can be
+useful in some case. For example, you can have different tick-location,
+tick-label, or tick-formatter for bottom and top (or left and right)
+axis. ::
+
+ ax2 = ax.twin() # now, ax2 is responsible for "top" axis and "right" axis
+ ax2.set_xticks([0., .5*np.pi, np.pi, 1.5*np.pi, 2*np.pi])
+ ax2.set_xticklabels(["0", r"$\frac{1}{2}\pi$",
+ r"$\pi$", r"$\frac{3}{2}\pi$", r"$2\pi$"])
+
+
+.. plot:: mpl_toolkits/axes_grid/figures/simple_axisline4.py
+
+
+AxisLine Axes lets you create a custom axis, ::
+
+ # make new (right-side) yaxis, but wth some offset
+ offset = (20, 0)
+ new_axisline = ax.get_grid_helper().new_fixed_axis
+ ax.axis["right2"] = new_axisline(loc="right",
+ offset=offset)
+
+
+And, you can use it with parasiteAxes.
+
+
+.. plot:: mpl_toolkits/axes_grid/figures/demo_parasite_axes2.py
+
+
+AnchoredArtists
+===============
+
+It's a collection of artists whose location is anchored to the (axes)
+bbox, like the legend. It is derived from *OffsetBox* in mpl, and
+artist need to be drawn in the canvas coordinate. But, there is a
+limited support for an arbitrary transform. For example, the ellipse
+in the example below will have width and height in the data
+coordinate.
+
+.. plot:: mpl_toolkits/axes_grid/figures/simple_anchored_artists.py
+ :include-source:
+
+
Modified: trunk/matplotlib/doc/users/toolkits.rst
===================================================================
--- trunk/matplotlib/doc/users/toolkits.rst 2009-04-17 16:34:09 UTC (rev 7047)
+++ trunk/matplotlib/doc/users/toolkits.rst 2009-04-17 19:35:59 UTC (rev 7048)
@@ -53,3 +53,17 @@
line, mesh) tools. Not the fastest or feature complete 3D library out
there, but ships with matplotlib and thus may be a lighter weight
solution for some use cases.
+
+
+.. _toolkit_axes_grid:
+
+AxesGrid
+========
+
+The matplotlib AxesGrid toolkit is a collection of helper classes to
+ease displaying multiple images in matplotlib. The AxesGrid toolkit is
+distributed with matplotlib source.
+
+.. image:: ../_static/demo_axes_grid.png
+
+See :ref:`toolkit_axesgrid-index` for documentations.
Added: trunk/matplotlib/examples/axes_grid/demo_axes_divider.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/demo_axes_divider.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/demo_axes_divider.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,124 @@
+import matplotlib.pyplot as plt
+from demo_image import get_demo_image
+#import mpl_toolkits.imaging.axes_grid as imaging
+
+def demo_simple_image(ax):
+ Z, extent = get_demo_image()
+
+ im = ax.imshow(Z, extent=extent, interpolation="nearest")
+ cb = plt.colorbar(im)
+ plt.setp(cb.ax.get_yticklabels(), visible=False)
+
+
+def demo_locatable_axes_hard(fig1):
+
+ from mpl_toolkits.axes_grid \
+ import SubplotDivider, LocatableAxes, Size
+
+ divider = SubplotDivider(fig1, 2, 2, 2, aspect=True)
+
+ # axes for image
+ ax = LocatableAxes(fig1, divider.get_position())
+
+ # axes for coloarbar
+ ax_cb = LocatableAxes(fig1, divider.get_position())
+
+ h = [Size.AxesX(ax), # main axes
+ Size.Fixed(0.05), # padding, 0.1 inch
+ Size.Fixed(0.2), # colorbar, 0.3 inch
+ ]
+
+ v = [Size.AxesY(ax)]
+
+ divider.set_horizontal(h)
+ divider.set_vertical(v)
+
+ ax.set_axes_locator(divider.new_locator(nx=0, ny=0))
+ ax_cb.set_axes_locator(divider.new_locator(nx=2, ny=0))
+
+ fig1.add_axes(ax)
+ fig1.add_axes(ax_cb)
+
+ ax_cb.axis["left"].toggle(all=False)
+ ax_cb.axis["right"].toggle(ticks=True)
+
+ Z, extent = get_demo_image()
+
+ im = ax.imshow(Z, extent=extent, interpolation="nearest")
+ plt.colorbar(im, cax=ax_cb)
+ plt.setp(ax_cb.get_yticklabels(), visible=False)
+
+
+def demo_locatable_axes_easy(ax):
+ from mpl_toolkits.axes_grid import make_axes_locatable
+
+ divider = make_axes_locatable(ax)
+
+ ax_cb = divider.new_horizontal(size="5%", pad=0.05)
+ fig1 = ax.get_figure()
+ fig1.add_axes(ax_cb)
+
+ Z, extent = get_demo_image()
+ im = ax.imshow(Z, extent=extent, interpolation="nearest")
+
+ plt.colorbar(im, cax=ax_cb)
+ ax_cb.yaxis.tick_right()
+ for tl in ax_cb.get_yticklabels():
+ tl.set_visible(False)
+ ax_cb.yaxis.tick_right()
+
+
+def demo_images_side_by_sied(ax):
+ from mpl_toolkits.axes_grid import make_axes_locatable
+
+ divider = make_axes_locatable(ax)
+
+ Z, extent = get_demo_image()
+ ax2 = divider.new_horizontal(size="100%", pad=0.05)
+ fig1 = ax.get_figure()
+ fig1.add_axes(ax2)
+
+ ax.imshow(Z, extent=extent, interpolation="nearest")
+ ax2.imshow(Z, extent=extent, interpolation="nearest")
+ for tl in ax2.get_yticklabels():
+ tl.set_visible(False)
+
+
+def demo():
+
+ fig1 = plt.figure(1, (6, 6))
+ fig1.clf()
+
+ ## PLOT 1
+ # simple image & colorbar
+ ax = fig1.add_subplot(2, 2, 1)
+ demo_simple_image(ax)
+
+ ## PLOT 2
+ # image and colorbar whose location is adjusted in the drawing time.
+ # a hard way
+
+ demo_locatable_axes_hard(fig1)
+
+
+ ## PLOT 3
+ # image and colorbar whose location is adjusted in the drawing time.
+ # a easy way
+
+ ax = fig1.add_subplot(2, 2, 3)
+ demo_locatable_axes_easy(ax)
+
+
+ ## PLOT 4
+ # two images side by sied with fixed padding.
+
+ ax = fig1.add_subplot(2, 2, 4)
+ demo_images_side_by_sied(ax)
+
+ plt.draw()
+ plt.show()
+
+
+
+if __name__ == "__main__":
+ demo()
Added: trunk/matplotlib/examples/axes_grid/demo_axes_grid.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/demo_axes_grid.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/demo_axes_grid.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,87 @@
+import matplotlib.pyplot as plt
+from demo_image import get_demo_image
+from mpl_toolkits.axes_grid import AxesGrid
+
+
+def demo_simple_grid(fig):
+ """
+ A grid of 2x2 images with 0.05 inch pad between images and only
+ the lower-left axes is labeld.
+ """
+ grid = AxesGrid(fig, 131, # similar to subplot(131)
+ nrows_ncols = (2, 2),
+ axes_pad = 0.05,
+ label_mode = "1",
+ )
+
+ Z, extent = get_demo_image()
+ for i in range(4):
+ im = grid[i].imshow(Z, extent=extent, interpolation="nearest")
+
+ # This only affects axes in first column and second row as share_all = False.
+ grid.axes_llc.set_xticks([-2, 0, 2])
+ grid.axes_llc.set_yticks([-2, 0, 2])
+
+
+def demo_grid_with_single_cbar(fig):
+ """
+ A grid of 2x2 images with a single colobar
+ """
+ grid = AxesGrid(fig, 132, # similar to subplot(132)
+ nrows_ncols = (2, 2),
+ axes_pad = 0.0,
+ share_all=True,
+ label_mode = "L",
+ cbar_mode="single",
+ )
+
+ Z, extent = get_demo_image()
+ for i in range(4):
+ im = grid[i].imshow(Z, extent=extent, interpolation="nearest")
+ plt.colorbar(im, cax = grid.cbar_axes[0])
+ grid.cbar_axes[0].colorbar(im)
+
+ # This affects all axes as share_all = True.
+ grid.axes_llc.set_xticks([-2, 0, 2])
+ grid.axes_llc.set_yticks([-2, 0, 2])
+
+
+def demo_grid_with_each_cbar(fig):
+ """
+ A grid of 2x2 images. Each image has its own colobar.
+ """
+
+ grid = AxesGrid(F, 133, # similar to subplot(122)
+ nrows_ncols = (2, 2),
+ axes_pad = 0.1,
+ label_mode = "1",
+ share_all = True,
+ cbar_location="top",
+ cbar_mode="each",
+ cbar_size="7%",
+ cbar_pad="2%",
+ )
+ Z, extent = get_demo_image()
+ for i in range(4):
+ im = grid[i].imshow(Z, extent=extent, interpolation="nearest")
+ grid.cbar_axes[i].colorbar(im)
+
+ # This affects all axes because we set share_all = True.
+ grid.axes_llc.set_xticks([-2, 0, 2])
+ grid.axes_llc.set_yticks([-2, 0, 2])
+
+
+
+if __name__ == "__main__":
+
+ F = plt.figure(1, (5.5, 2.5))
+
+ F.subplots_adjust(left=0.05, right=0.98)
+
+ demo_simple_grid(F)
+ demo_grid_with_single_cbar(F)
+ demo_grid_with_each_cbar(F)
+
+ plt.draw()
+ plt.show()
+
Added: trunk/matplotlib/examples/axes_grid/demo_axes_rgb.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/demo_axes_rgb.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/demo_axes_rgb.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,82 @@
+import numpy as np
+import matplotlib.pyplot as plt
+
+from demo_axes_divider import get_demo_image
+from mpl_toolkits.axes_grid.axes_rgb import make_rgb_axes, RGBAxes
+
+def get_rgb():
+ Z, extent = get_demo_image()
+
+ Z[Z<0] = 0.
+ Z = Z/Z.max()
+
+ R = Z[:13,:13]
+ G = Z[2:,2:]
+ B = Z[:13,2:]
+
+ return R, G, B
+
+
+def make_cube(r, g, b):
+ ny, nx = r.shape
+ R = np.zeros([ny, nx, 3], dtype="d")
+ R[:,:,0] = r
+ G = np.zeros_like(R)
+ G[:,:,1] = g
+ B = np.zeros_like(R)
+ B[:,:,2] = b
+
+ RGB = R + G + B
+
+ return R, G, B, RGB
+
+
+
+def demo_rgb():
+ fig = plt.figure(1)
+ fig.clf()
+
+ ax = fig.add_subplot(111)
+ ax_r, ax_g, ax_b = make_rgb_axes(ax, pad=0.02)
+ #fig.add_axes(ax_r)
+ #fig.add_axes(ax_g)
+ #fig.add_axes(ax_b)
+
+ r, g, b = get_rgb()
+ im_r, im_g, im_b, im_rgb = make_cube(r, g, b)
+ kwargs = dict(origin="lower", interpolation="nearest")
+ ax.imshow(im_rgb, **kwargs)
+ ax_r.imshow(im_r, **kwargs)
+ ax_g.imshow(im_g, **kwargs)
+ ax_b.imshow(im_b, **kwargs)
+
+
+
+
+def demo_rgb2():
+ fig = plt.figure(2)
+ ax = RGBAxes(fig, [0.1, 0.1, 0.8, 0.8], pad=0.0)
+ #fig.add_axes(ax)
+ #ax.add_RGB_to_figure()
+
+ r, g, b = get_rgb()
+ kwargs = dict(origin="lower", interpolation="nearest")
+ ax.imshow_rgb(r, g, b, **kwargs)
+
+ ax.RGB.set_xlim(0., 9.5)
+ ax.RGB.set_ylim(0.9, 10.6)
+
+ for ax1 in [ax.RGB, ax.R, ax.G, ax.B]:
+ for axisline in ax1._axislines.values():
+ axisline.line.set_color("w")
+ axisline.major_ticks.set_mec("w")
+
+ return ax
+
+
+if __name__ == "__main__":
+ demo_rgb()
+ ax = demo_rgb2()
+
+ plt.draw()
+ plt.show()
Added: trunk/matplotlib/examples/axes_grid/demo_fixed_size_axes.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/demo_fixed_size_axes.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/demo_fixed_size_axes.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,57 @@
+import matplotlib.pyplot as plt
+
+from mpl_toolkits.axes_grid \
+ import Divider, LocatableAxes, Size
+
+def demo_fixed_size_axes():
+
+ fig1 = plt.figure(1, (6, 6))
+
+ # The first items are for padding and the second items are for the axes.
+ # sizes are in inch.
+ h = [Size.Fixed(1.0), Size.Fixed(4.5)]
+ v = [Size.Fixed(0.7), Size.Fixed(5.)]
+
+ divider = Divider(fig1, (0.0, 0.0, 1., 1.), h, v, aspect=False)
+ # the width and height of the rectangle is ignored.
+
+ ax = LocatableAxes(fig1, divider.get_position())
+ ax.set_axes_locator(divider.new_locator(nx=1, ny=1))
+
+ fig1.add_axes(ax)
+
+ ax.plot([1,2,3])
+
+
+
+
+def demo_fixed_pad_axes():
+
+ fig = plt.figure(2, (6, 6))
+
+ # The first & third items are for padding and the second items are for the axes.
+ # sizes are in inch.
+ h = [Size.Fixed(1.0), Size.Scaled(1.), Size.Fixed(.2),]
+ v = [Size.Fixed(0.7), Size.Scaled(1.), Size.Fixed(.5),]
+
+ divider = Divider(fig, (0.0, 0.0, 1., 1.), h, v, aspect=False)
+ # the width and height of the rectangle is ignored.
+
+ ax = LocatableAxes(fig, divider.get_position())
+ ax.set_axes_locator(divider.new_locator(nx=1, ny=1))
+
+ fig.add_axes(ax)
+
+ ax.plot([1,2,3])
+
+
+
+
+
+
+if __name__ == "__main__":
+ demo_fixed_size_axes()
+ demo_fixed_pad_axes()
+
+ plt.draw()
+ plt.show()
Added: trunk/matplotlib/examples/axes_grid/demo_image.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/demo_image.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/demo_image.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,17 @@
+import numpy as np
+
+def get_demo_image():
+ # prepare image
+ delta = 0.5
+
+ extent = (-3,4,-4,3)
+ x = np.arange(-3.0, 4.001, delta)
+ y = np.arange(-4.0, 3.001, delta)
+ X, Y = np.meshgrid(x, y)
+ import matplotlib.mlab as mlab
+ Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
+ Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
+ Z = (Z1 - Z2) * 10
+
+ return Z, extent
+
Added: trunk/matplotlib/examples/axes_grid/demo_parasite_axes.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/demo_parasite_axes.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/demo_parasite_axes.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,53 @@
+from mpl_toolkits.axes_grid.parasite_axes import HostAxes, ParasiteAxes
+import matplotlib.pyplot as plt
+
+if __name__ == "__main__":
+ fig = plt.figure(1)
+
+ host = HostAxes(fig, [0.15, 0.1, 0.65, 0.8])
+ par1 = ParasiteAxes(host, sharex=host)
+ par2 = ParasiteAxes(host, sharex=host)
+ host.parasites.append(par1)
+ host.parasites.append(par2)
+
+ host.set_ylabel("Density")
+ host.set_xlabel("Distance")
+
+ host.axis["right"].set_visible(False)
+ par1.axis["right"].set_visible(True)
+ par1.set_ylabel("Temperature")
+
+ par1.axis["right"].major_ticklabels.set_visible(True)
+ par1.axis["right"].label.set_visible(True)
+
+ par2.set_ylabel("Velocity")
+ offset = (60, 0)
+ new_axisline = par2._grid_helper.new_axisline
+ par2.axis["right2"] = new_axisline(loc="right",
+ offset=offset)
+
+
+ fig.add_axes(host)
+
+ host.set_xlim(0, 2)
+ host.set_ylim(0, 2)
+
+ host.set_xlabel("Distance")
+ host.set_ylabel("Density")
+ par1.set_ylabel("Temperature")
+
+ p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density")
+ p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature")
+ p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity")
+
+ par1.set_ylim(0, 4)
+ par2.set_ylim(1, 65)
+
+ host.legend()
+
+ host.axis["left"].label.set_color(p1.get_color())
+ par1.axis["right"].label.set_color(p2.get_color())
+ par2.axis["right2"].label.set_color(p3.get_color())
+
+ plt.draw()
+ plt.show()
Added: trunk/matplotlib/examples/axes_grid/demo_parasite_axes2.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/demo_parasite_axes2.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/demo_parasite_axes2.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,54 @@
+from mpl_toolkits.axes_grid.parasite_axes import SubplotHost
+import matplotlib.transforms as mtransforms
+import matplotlib.pyplot as plt
+
+if 1:
+ fig = plt.figure(1)
+
+ host = SubplotHost(fig, 111)
+
+ host.set_ylabel("Density")
+ host.set_xlabel("Distance")
+
+ par1 = host.twinx()
+ par2 = host.twinx()
+
+ par1.set_ylabel("Temperature")
+
+ par2.axis["right"].set_visible(False)
+
+ offset = 60, 0
+ new_axisline = par2.get_grid_helper().new_fixed_axis
+ par2.axis["right2"] = new_axisline(loc="right",
+ offset=offset)
+
+ par2.axis["right2"].label.set_visible(True)
+ par2.axis["right2"].set_label("Velocity")
+
+ fig.add_axes(host)
+ plt.subplots_adjust(right=0.75)
+
+ host.set_xlim(0, 2)
+ host.set_ylim(0, 2)
+
+ host.set_xlabel("Distance")
+ host.set_ylabel("Density")
+ par1.set_ylabel("Temperature")
+
+ p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density")
+ p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature")
+ p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity")
+
+ par1.set_ylim(0, 4)
+ par2.set_ylim(1, 65)
+
+ host.legend()
+
+ host.axis["left"].label.set_color(p1.get_color())
+ par1.axis["right"].label.set_color(p2.get_color())
+ par2.axis["right2"].label.set_color(p3.get_color())
+
+ plt.draw()
+ plt.show()
+
+ #plt.savefig("Test")
Added: trunk/matplotlib/examples/axes_grid/parasite_simple.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/parasite_simple.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/parasite_simple.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,24 @@
+from mpl_toolkits.axes_grid.parasite_axes import SubplotHost
+import matplotlib.pyplot as plt
+
+fig = plt.figure(1)
+
+host = SubplotHost(fig, 111)
+fig.add_subplot(host)
+
+par = host.twinx()
+
+host.set_xlabel("Distance")
+host.set_ylabel("Density")
+par.set_ylabel("Temperature")
+
+p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density")
+p2, = par.plot([0, 1, 2], [0, 3, 2], label="Temperature")
+
+host.axis["left"].label.set_color(p1.get_color())
+par.axis["right"].label.set_color(p2.get_color())
+
+host.legend()
+
+plt.show()
+
Added: trunk/matplotlib/examples/axes_grid/parasite_simple2.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/parasite_simple2.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/parasite_simple2.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,42 @@
+import matplotlib.transforms as mtransforms
+import matplotlib.pyplot as plt
+from mpl_toolkits.axes_grid.parasite_axes import SubplotHost
+
+obs = [["01_S1", 3.88, 0.14, 1970, 63],
+ ["01_S4", 5.6, 0.82, 1622, 150],
+ ["02_S1", 2.4, 0.54, 1570, 40],
+ ["03_S1", 4.1, 0.62, 2380, 170]]
+
+
+fig = plt.figure()
+
+ax_kms = SubplotHost(fig, 1,1,1, aspect=1.)
+
+# angular proper motion("/yr) to linear velocity(km/s) at distance=2.3kpc
+pm_to_kms = 1./206265.*2300*3.085e18/3.15e7/1.e5
+
+aux_trans = mtransforms.Affine2D().scale(pm_to_kms, 1.)
+ax_pm = ax_kms.twin(aux_trans)
+ax_pm.set_viewlim_mode("transform")
+
+fig.add_subplot(ax_kms)
+
+for n, ds, dse, w, we in obs:
+ time = ((2007+(10. + 4/30.)/12)-1988.5)
+ v = ds / time * pm_to_kms
+ ve = dse / time * pm_to_kms
+ ax_kms.errorbar([v], [w], xerr=[ve], yerr=[we], color="k")
+
+
+ax_kms.axis["bottom"].set_label("Linear velocity at 2.3 kpc [km/s]")
+ax_kms.axis["left"].set_label("FWHM [km/s]")
+ax_pm.axis["top"].set_label("Proper Motion [$^{''}$/yr]")
+ax_pm.axis["top"].label.set_visible(True)
+ax_pm.axis["right"].major_ticklabels.set_visible(False)
+
+ax_kms.set_xlim(950, 3700)
+ax_kms.set_ylim(950, 3100)
+# xlim and ylim of ax_pms will be automatically adjusted.
+
+plt.draw()
+plt.show()
Added: trunk/matplotlib/examples/axes_grid/scatter_hist.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/scatter_hist.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/scatter_hist.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,60 @@
+import numpy as np
+import matplotlib.pyplot as plt
+
+# the random data
+x = np.random.randn(1000)
+y = np.random.randn(1000)
+
+
+fig = plt.figure(1, figsize=(5.5,5.5))
+
+from mpl_toolkits.axes_grid import make_axes_locatable
+
+axScatter = plt.subplot(111)
+divider = make_axes_locatable(axScatter)
+
+# create a new axes with a height of 1.2 inch above the axScatter
+axHistx = divider.new_vertical(1.2, pad=0.1, sharex=axScatter)
+
+# create a new axes with a width of 1.2 inch on the right side of the
+# axScatter
+axHisty = divider.new_horizontal(1.2, pad=0.1, sharey=axScatter)
+
+fig.add_axes(axHistx)
+fig.add_axes(axHisty)
+
+
+# make some labels invisible
+plt.setp(axHistx.get_xticklabels() + axHisty.get_yticklabels(),
+ visible=False)
+
+# the scatter plot:
+axScatter.scatter(x, y)
+axScatter.set_aspect(1.)
+
+# now determine nice limits by hand:
+binwidth = 0.25
+xymax = np.max( [np.max(np.fabs(x)), np.max(np.fabs(y))] )
+lim = ( int(xymax/binwidth) + 1) * binwidth
+
+bins = np.arange(-lim, lim + binwidth, binwidth)
+axHistx.hist(x, bins=bins)
+axHisty.hist(y, bins=bins, orientation='horizontal')
+
+# the xaxis of axHistx and yaxis of axHisty are shared with axScatter,
+# thus there is no need to manually adjust the xlim and ylim of these
+# axis.
+
+#axHistx.axis["bottom"].major_ticklabels.set_visible(False)
+for tl in axHistx.get_xticklabels():
+ tl.set_visible(False)
+axHistx.set_yticks([0, 50, 100])
+
+#axHisty.axis["left"].major_ticklabels.set_visible(False)
+for tl in axHisty.get_yticklabels():
+ tl.set_visible(False)
+axHisty.set_xticks([0, 50, 100])
+
+plt.draw()
+#plt.show()
+plt.savefig("a.pdf")
Added: trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_anchored_artists.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,60 @@
+import matplotlib.pyplot as plt
+
+
+def draw_text(ax):
+ from mpl_toolkits.axes_grid.anchored_artists import AnchoredText
+ at = AnchoredText("Figure 1a",
+ loc=2, prop=dict(size=8), frameon=True,
+ )
+ at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
+ ax.add_artist(at)
+
+ at2 = AnchoredText("Figure 1(b)",
+ loc=3, prop=dict(size=8), frameon=True,
+ bbox_to_anchor=(0., 1.)
+ )
+ at2.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
+ ax.add_artist(at2)
+
+def draw_circle(ax): # circle in the canvas coordinate
+ from mpl_toolkits.axes_grid.anchored_artists import AnchoredDrawingArea
+ from matplotlib.patches import Circle
+ ada = AnchoredDrawingArea(20, 20, 0, 0,
+ loc=1, pad=0., frameon=False)
+ p = Circle((10, 10), 10)
+ ada.da.add_artist(p)
+ ax.add_artist(ada)
+
+def draw_ellipse(ax):
+ from mpl_toolkits.axes_grid.anchored_artists import AnchoredEllipse
+ # draw an ellipse of width=0.1, height=0.15 in the data coordinate
+ ae = AnchoredEllipse(ax.transData, width=0.1, height=0.15, angle=0.,
+ loc=3, pad=0.5, borderpad=0.4, frameon=True)
+
+ ax.add_artist(ae)
+
+def draw_sizebar(ax):
+ from mpl_toolkits.axes_grid.anchored_artists import AnchoredSizeBar
+ # draw a horizontal bar with length of 0.1 in Data coordinate
+ # (ax.transData) with a label underneath.
+ as = AnchoredSizeBar(ax.transData,
+ 0.1,
+ r"1$^{\prime}$",
+ loc=8,
+ pad=0.1, borderpad=0.5, sep=5,
+ frameon=False)
+ ax.add_artist(as)
+
+
+if 1:
+ ax = plt.gca()
+ ax.set_aspect(1.)
+
+ draw_text(ax)
+ draw_circle(ax)
+ draw_ellipse(ax)
+ draw_sizebar(ax)
+
+ plt.show()
+
+
Added: trunk/matplotlib/examples/axes_grid/simple_axes_divider1.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axes_divider1.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_axes_divider1.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,30 @@
+from mpl_toolkits.axes_grid import Size, Divider
+import matplotlib.pyplot as plt
+
+
+fig1 = plt.figure(1, (6, 6))
+
+# fixed size in inch
+horiz = [Size.Fixed(1.), Size.Fixed(.5), Size.Fixed(1.5),
+ Size.Fixed(.5)]
+vert = [Size.Fixed(1.5), Size.Fixed(.5), Size.Fixed(1.)]
+
+rect = (0.1, 0.1, 0.8, 0.8)
+# divide the axes rectangle into grid whose size is specified by horiz * vert
+divider = Divider(fig1, rect, horiz, vert, aspect=False)
+
+# the rect parameter will be ignore as we will set axes_locator
+ax1 = fig1.add_axes(rect, label="1")
+ax2 = fig1.add_axes(rect, label="2")
+ax3 = fig1.add_axes(rect, label="3")
+ax4 = fig1.add_axes(rect, label="4")
+
+ax1.set_axes_locator(divider.new_locator(nx=0, ny=0))
+ax2.set_axes_locator(divider.new_locator(nx=0, ny=2))
+ax3.set_axes_locator(divider.new_locator(nx=2, ny=2))
+ax4.set_axes_locator(divider.new_locator(nx=2, nx1=4, ny=0))
+
+
+
+plt.draw()
+plt.show()
Added: trunk/matplotlib/examples/axes_grid/simple_axes_divider2.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axes_divider2.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_axes_divider2.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,28 @@
+from mpl_toolkits.axes_grid import Size, Divider
+import matplotlib.pyplot as plt
+
+fig1 = plt.figure(1, (5.5, 4.))
+
+# the rect parameter will be ignore as we will set axes_locator
+rect = (0.1, 0.1, 0.8, 0.8)
+ax = [fig1.add_axes(rect, label="%d"%i) for i in range(4)]
+
+horiz = [Size.Scaled(1.5), Size.Fixed(.5), Size.Scaled(1.),
+ Size.Scaled(.5)]
+
+vert = [Size.Scaled(1.), Size.Fixed(.5), Size.Scaled(1.5)]
+
+# divide the axes rectangle into grid whose size is specified by horiz * vert
+divider = Divider(fig1, rect, horiz, vert, aspect=False)
+
+ax[0].set_axes_locator(divider.new_locator(nx=0, ny=0))
+ax[1].set_axes_locator(divider.new_locator(nx=0, ny=2))
+ax[2].set_axes_locator(divider.new_locator(nx=2, ny=2))
+ax[3].set_axes_locator(divider.new_locator(nx=2, nx1=4, ny=0))
+
+for ax1 in ax:
+ plt.setp(ax1.get_xticklabels()+ax1.get_yticklabels(),
+ visible=False)
+
+plt.draw()
+plt.show()
Added: trunk/matplotlib/examples/axes_grid/simple_axes_divider3.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axes_divider3.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_axes_divider3.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,37 @@
+from mpl_toolkits.axes_grid import Size, Divider
+import matplotlib.pyplot as plt
+
+
+fig1 = plt.figure(1, (5.5, 4))
+
+# the rect parameter will be ignore as we will set axes_locator
+rect = (0.1, 0.1, 0.8, 0.8)
+ax = [fig1.add_axes(rect, label="%d"%i) for i in range(4)]
+
+
+horiz = [Size.AxesX(ax[0]), Size.Fixed(.5), Size.AxesX(ax[1])]
+vert = [Size.AxesY(ax[0]), Size.Fixed(.5), Size.AxesY(ax[2])]
+
+# divide the axes rectangle into grid whose size is specified by horiz * vert
+divider = Divider(fig1, rect, horiz, vert, aspect=False)
+
+
+ax[0].set_axes_locator(divider.new_locator(nx=0, ny=0))
+ax[1].set_axes_locator(divider.new_locator(nx=2, ny=0))
+ax[2].set_axes_locator(divider.new_locator(nx=0, ny=2))
+ax[3].set_axes_locator(divider.new_locator(nx=2, ny=2))
+
+ax[0].set_xlim(0, 2)
+ax[1].set_xlim(0, 1)
+
+ax[0].set_ylim(0, 1)
+ax[2].set_ylim(0, 2)
+
+divider.set_aspect(1.)
+
+for ax1 in ax:
+ plt.setp(ax1.get_xticklabels()+ax1.get_yticklabels(),
+ visible=False)
+
+plt.draw()
+plt.show()
Added: trunk/matplotlib/examples/axes_grid/simple_axesgrid.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axesgrid.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_axesgrid.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,17 @@
+import matplotlib.pyplot as plt
+from mpl_toolkits.axes_grid import AxesGrid
+import numpy as np
+
+im = np.arange(100)
+im.shape = 10, 10
+
+fig = plt.figure(1, (4., 4.))
+grid = AxesGrid(fig, 111, # similar to subplot(111)
+ nrows_ncols = (2, 2), # creates 2x2 grid of axes
+ axes_pad=0.1, # pad between axes in inch.
+ )
+
+for i in range(4):
+ grid[i].imshow(im) # The AxesGrid object work as a list of axes.
+
+plt.show()
Added: trunk/matplotlib/examples/axes_grid/simple_axesgrid2.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axesgrid2.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_axesgrid2.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,24 @@
+import matplotlib.pyplot as plt
+from mpl_toolkits.axes_grid import AxesGrid
+from demo_image import get_demo_image
+
+F = plt.figure(1, (5.5, 3.5))
+grid = AxesGrid(F, 111, # similar to subplot(111)
+ nrows_ncols = (1, 3),
+ axes_pad = 0.1,
+ add_all=True,
+ label_mode = "L",
+ )
+
+Z, extent = get_demo_image() # demo image
+
+im1=Z
+im2=Z[:,:10]
+im3=Z[:,10:]
+vmin, vmax = Z.min(), Z.max()
+for i, im in enumerate([im1, im2, im3]):
+ ax = grid[i]
+ ax.imshow(im, origin="lower", vmin=vmin, vmax=vmax, interpolation="nearest")
+
+plt.draw()
+plt.show()
Added: trunk/matplotlib/examples/axes_grid/simple_axisline.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axisline.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_axisline.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,37 @@
+import matplotlib.pyplot as plt
+
+from mpl_toolkits.axes_grid.axislines import SubplotZero
+
+if 1:
+
+ fig = plt.figure(1)
+ fig.subplots_adjust(right=0.85)
+ ax = SubplotZero(fig, 1, 1, 1)
+ fig.add_subplot(ax)
+
+ # make right and top axis invisible
+ ax.axis["right"].set_visible(False)
+ ax.axis["top"].set_visible(False)
+
+ # make xzero axis (horizontal axis line through y=0) visible.
+ ax.axis["xzero"].set_visible(True)
+ ax.axis["xzero"].label.set_text("Axis Zero")
+
+ ax.set_ylim(-2, 4)
+ ax.set_xlabel("Label X")
+ ax.set_ylabel("Label Y")
+ # or
+ #ax.axis["bottom"].label.set_text("Label X")
+ #ax.axis["left"].label.set_text("Label Y")
+
+ # make new (right-side) yaxis, but wth some offset
+ offset = (20, 0)
+ new_axisline = ax.get_grid_helper().new_axisline
+ ax.axis["right2"] = new_axisline(loc="right",
+ offset=offset)
+ ax.axis["right2"].label.set_text("Label Y2")
+
+ ax.plot([-2,3,2])
+ plt.draw()
+ plt.show()
+
Added: trunk/matplotlib/examples/axes_grid/simple_axisline2.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axisline2.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_axisline2.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,24 @@
+import matplotlib.pyplot as plt
+from mpl_toolkits.axes_grid.axislines import SubplotZero
+import numpy as np
+
+fig = plt.figure(1, (4,3))
+
+# a subplot with two additiona axis, "xzero" and "yzero". "xzero" is
+# y=0 line, and "yzero" is x=0 line.
+ax = SubplotZero(fig, 1, 1, 1)
+fig.add_subplot(ax)
+
+# make xzero axis (horizontal axis line through y=0) visible.
+ax.axis["xzero"].set_visible(True)
+ax.axis["xzero"].label.set_text("Axis Zero")
+
+# make other axis (bottom, top, right) invisible.
+for n in ["bottom", "top", "right"]:
+ ax.axis[n].set_visible(False)
+
+xx = np.arange(0, 2*np.pi, 0.01)
+ax.plot(xx, np.sin(xx))
+
+plt.show()
+
Added: trunk/matplotlib/examples/axes_grid/simple_axisline3.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axisline3.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_axisline3.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,13 @@
+import matplotlib.pyplot as plt
+from mpl_toolkits.axes_grid.axislines import Subplot
+
+fig = plt.figure(1, (3,3))
+
+ax = Subplot(fig, 111)
+fig.add_subplot(ax)
+
+ax.axis["right"].set_visible(False)
+ax.axis["top"].set_visible(False)
+
+plt.show()
+
Added: trunk/matplotlib/examples/axes_grid/simple_axisline4.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_axisline4.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_axisline4.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,22 @@
+import matplotlib.pyplot as plt
+from mpl_toolkits.axes_grid.parasite_axes import SubplotHost
+import numpy as np
+
+fig = plt.figure(1, (4,3))
+
+ax = SubplotHost(fig, 111)
+fig.add_subplot(ax)
+
+xx = np.arange(0, 2*np.pi, 0.01)
+ax.plot(xx, np.sin(xx))
+
+ax2 = ax.twin() # ax2 is responsible for "top" axis and "right" axis
+ax2.set_xticks([0., .5*np.pi, np.pi, 1.5*np.pi, 2*np.pi])
+ax2.set_xticklabels(["0", r"$\frac{1}{2}\pi$",
+ r"$\pi$", r"$\frac{3}{2}\pi$", r"$2\pi$"])
+
+ax2.axis["right"].major_ticklabels.set_visible(False)
+
+plt.draw()
+plt.show()
+
Added: trunk/matplotlib/examples/axes_grid/simple_rgb.py
===================================================================
--- trunk/matplotlib/examples/axes_grid/simple_rgb.py (rev 0)
+++ trunk/matplotlib/examples/axes_grid/simple_rgb.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,31 @@
+import matplotlib.pyplot as plt
+
+from demo_image import get_demo_image
+from mpl_toolkits.axes_grid.axes_rgb import RGBAxes
+
+def get_rgb():
+ Z, extent = get_demo_image()
+
+ Z[Z<0] = 0.
+ Z = Z/Z.max()
+
+ R = Z[:13,:13]
+ G = Z[2:,2:]
+ B = Z[:13,2:]
+
+ return R, G, B
+
+
+fig = plt.figure(1)
+ax = RGBAxes(fig, [0.1, 0.1, 0.8, 0.8])
+
+r, g, b = get_rgb()
+kwargs = dict(origin="lower", interpolation="nearest")
+ax.imshow_rgb(r, g, b, **kwargs)
+
+ax.RGB.set_xlim(0., 9.5)
+ax.RGB.set_ylim(0.9, 10.6)
+
+
+plt.draw()
+plt.show()
Added: trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py (rev 0)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/__init__.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,9 @@
+"""
+AxesGrid
+"""
+
+
+from axes_divider import Divider, SubplotDivider, LocatableAxes, Size, \
+ make_axes_locatable
+from axes_grid import AxesGrid
+
Added: trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py (rev 0)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/anchored_artists.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,122 @@
+
+
+from matplotlib.font_manager import FontProperties
+from matplotlib import rcParams
+from matplotlib.patches import Rectangle, Ellipse
+
+from matplotlib.offsetbox import AnchoredOffsetbox, AuxTransformBox, VPacker,\
+ TextArea, DrawingArea
+
+
+class AnchoredText(AnchoredOffsetbox):
+ def __init__(self, s, loc, pad=0.4, borderpad=0.5, prop=None, **kwargs):
+
+ self.txt = TextArea(s, textprops=prop,
+ minimumdescent=False)
+ fp = self.txt._text.get_fontproperties()
+
+ super(AnchoredText, self).__init__(loc, pad=pad, borderpad=borderpad,
+ child=self.txt,
+ prop=fp,
+ **kwargs)
+
+
+class AnchoredSizeBar(AnchoredOffsetbox):
+ def __init__(self, transform, size, label, loc,
+ pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True):
+ """
+ Draw a horizontal bar with the size in data coordinate of the give axes.
+ A label will be drawn underneath (center-alinged).
+
+ pad, borderpad in fraction of the legend font size (or prop)
+ sep in points.
+ """
+ self.size_bar = AuxTransformBox(transform)
+ self.size_bar.add_artist(Rectangle((0,0), size, 0, fc="none"))
+
+ self.txt_label = TextArea(label, minimumdescent=False)
+
+ self._box = VPacker(children=[self.size_bar, self.txt_label],
+ align="center",
+ pad=0, sep=sep)
+
+ AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad,
+ child=self._box,
+ prop=prop,
+ frameon=frameon)
+
+
+class AnchoredEllipse(AnchoredOffsetbox):
+ def __init__(self, transform, width, height, angle, loc,
+ pad=0.1, borderpad=0.1, prop=None, frameon=True):
+ """
+ Draw an ellipse the size in data coordinate of the give axes.
+
+ pad, borderpad in fraction of the legend font size (or prop)
+ """
+ self._box = AuxTransformBox(transform)
+ self.ellipse = Ellipse((0,0), width, height, angle)
+ self._box.add_artist(self.ellipse)
+
+ AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad,
+ child=self._box,
+ prop=prop,
+ frameon=frameon)
+
+
+
+class AnchoredDrawingArea(AnchoredOffsetbox):
+ def __init__(self, width, height, xdescent, ydescent,
+ loc, pad=0.4, borderpad=0.5, prop=None, frameon=True):
+
+ self.da = DrawingArea(width, height, xdescent, ydescent, clip=True)
+
+ super(AnchoredDrawingArea, self).__init__(loc, pad=pad, borderpad=borderpad,
+ child=self.da,
+ prop=None,
+ frameon=frameon)
+
+
+
+if __name__ == "__main__":
+ import matplotlib.pyplot as plt
+ from matplotlib.patches import Circle
+
+ #import matplotlib.offsetbox
+ #matplotlib.offsetbox.DEBUG=False
+
+ #ax = plt.subplot(1,1,1)
+ plt.clf()
+ plt.cla()
+ plt.draw()
+ ax = plt.gca()
+ ax.set_aspect(1.)
+
+ at = AnchoredText("Figure 1a",
+ loc=2, frameon=True)
+ at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
+ ax.add_artist(at)
+
+ ada = AnchoredDrawingArea(20, 20, 0, 0,
+ loc=1, pad=0., frameon=False)
+ p = Circle((10, 10), 10)
+ ada.da.add_artist(p)
+ ax.add_artist(ada)
+
+
+ as = AnchoredSizeBar(ax, 0.1, r"1$^{\prime}$",
+ loc=8,
+ pad=0.1, borderpad=0.5, sep=5,
+ frameon=False)
+ ax.add_artist(as)
+
+
+ ae = AnchoredEllipse(ax, width=0.1, height=0.15, angle=0.,
+ loc=3, pad=0.5, borderpad=0.4, frameon=True)
+
+ ax.add_artist(ae)
+
+ plt.draw()
+ plt.show()
+
+
Added: trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py (rev 0)
+++ trunk/matplotlib/lib/mpl_toolkits/axes_grid/axes_divider.py 2009-04-17 19:35:59 UTC (rev 7048)
@@ -0,0 +1,652 @@
+"""
+The axes_divider module provide helper classes to adjust the axes
+positions of set of images in the drawing time.
+
+ Size: This provides a classese of units that the size of each axes
+ will be determined. For example, you can specify a fixed size
+
+ Divider: this is the class that uis used calculates the axes
+ position. It divides the given renctangular area into several
+ areas. You intialize the divider by setting the horizontal and
+ vertical list of sizes that the division will be based on. You
+ then use the new_locator method, whose return value is a callable
+ object that can be used to set the axes_locator of the axes.
+
+"""
+
+import matplotlib.axes as maxes
+import matplotlib.transforms as mtransforms
+
+import matplotlib.cbook as cbook
+from matplotlib.axes import SubplotBase
+
+import new
+
+
+class Size(object):
+ """
+ provides a classese of units that will be used with AxesDivider
+ class (or others) to determine the size of each axes. The unit
+ classes define __call__ that returns a tuple of two floats,
+ meaning relative and absolute sizes, respectively.
+
+ Note that this class is nothing more than a simple tuple of two
+ floats. Take a look at the Divid...
[truncated message content] |
|
From: <lee...@us...> - 2009-04-17 16:34:14
|
Revision: 7047
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7047&view=rev
Author: leejjoon
Date: 2009-04-17 16:34:09 +0000 (Fri, 17 Apr 2009)
Log Message:
-----------
Added a support for bbox_to_anchor in offsetbox.AnchoredOffsetbox
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/offsetbox.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-04-17 02:31:16 UTC (rev 7046)
+++ trunk/matplotlib/CHANGELOG 2009-04-17 16:34:09 UTC (rev 7047)
@@ -1,5 +1,9 @@
======================================================================
+2009-04-17 Added a support for bbox_to_anchor in
+ offsetbox.AnchoredOffsetbox. Improved a documentation.
+ - JJL
+
2009-04-16 Fixed a offsetbox bug that multiline texts are not
correctly aligned. - JJL
Modified: trunk/matplotlib/lib/matplotlib/offsetbox.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/offsetbox.py 2009-04-17 02:31:16 UTC (rev 7046)
+++ trunk/matplotlib/lib/matplotlib/offsetbox.py 2009-04-17 16:34:09 UTC (rev 7047)
@@ -19,7 +19,12 @@
import matplotlib.artist as martist
import matplotlib.text as mtext
import numpy as np
+from matplotlib.transforms import Bbox, TransformedBbox, BboxTransformTo
+from matplotlib.font_manager import FontProperties
+from matplotlib.patches import FancyBboxPatch
+from matplotlib import rcParams
+
from matplotlib.patches import bbox_artist as mbbox_artist
DEBUG=False
# for debuging use
@@ -291,7 +296,7 @@
for c in self.get_visible_children():
if isinstance(c, PackerBase) and c.mode == "expand":
c.set_width(self.width)
-
+
whd_list = [c.get_extent(renderer) for c in self.get_visible_children()]
whd_list = [(w, h, xd, (h-yd)) for w, h, xd, yd in whd_list]
@@ -752,7 +757,7 @@
self.ref_offset_transform.translate(-ub.x0, -ub.y0)
# restor offset transform
self.offset_transform.matrix_from_values(*_off)
-
+
return ub.width, ub.height, 0., 0.
@@ -767,15 +772,51 @@
bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
-from matplotlib.font_manager import FontProperties
-from matplotlib.patches import FancyBboxPatch
-from matplotlib import rcParams
-from matplotlib.transforms import Bbox
class AnchoredOffsetbox(OffsetBox):
+ """
+ An offset box placed according to the legend location
+ loc. AnchoredOffsetbox has a single child. When multiple children
+ is needed, use other OffsetBox class to enlose them. By default,
+ the offset box is anchored against its parent axes. You may
+ explicitly specify the bbox_to_anchor.
+ """
+
def __init__(self, loc, pad=0.4, borderpad=0.5,
- child=None, prop=None, frameon=True):
+ child=None, prop=None, frameon=True,
+ bbox_to_anchor=None,
+ bbox_transform=None):
+ """
+ loc is a string or an integer specifying the legend location.
+ The valid location codes are::
+ 'upper right' : 1,
+ 'upper left' : 2,
+ 'lower left' : 3,
+ 'lower right' : 4,
+ 'right' : 5,
+ 'center left' : 6,
+ 'center right' : 7,
+ 'lower center' : 8,
+ 'upper center' : 9,
+ 'center' : 10,
+
+
+ pad : pad around the child for drawing a frame. given in
+ fraction of fontsize.
+
+ borderpad : pad between offsetbox frame and the bbox_to_anchor,
+
+ child : OffsetBox instance that will be anchored.
+
+ prop : font property. This is only used as a reference for paddings.
+
+ frameon : draw a frame box if True.
+
+ bbox_to_anchor : bbox to anchor. If None, use axes.bbox.
+
+ """
+
super(AnchoredOffsetbox, self).__init__()
self.set_child(child)
@@ -788,7 +829,7 @@
self.prop=FontProperties(size=rcParams["legend.fontsize"])
else:
self.prop = prop
-
+
self.patch = FancyBboxPatch(
xy=(0.0, 0.0), width=1., height=1.,
facecolor='w', edgecolor='k',
@@ -797,48 +838,121 @@
)
self.patch.set_boxstyle("square",pad=0)
self._drawFrame = frameon
+ #self._parent_bbox = bbox_to_anchor
+ self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)
+
+
+
def set_child(self, child):
+ "set the child to be anchored"
self._child = child
+ def get_child(self):
+ "return the child"
+ return self._child
+
def get_children(self):
+ "return the list of children"
return [self._child]
- def get_child(self):
- return self._child
def get_extent(self, renderer):
+ """
+ return the extent of the artist. The extent of the child
+ added with the pad is returned
+ """
w, h, xd, yd = self.get_child().get_extent(renderer)
fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
pad = self.pad * fontsize
return w+2*pad, h+2*pad, xd+pad, yd+pad
+
+ def get_bbox_to_anchor(self):
+ """
+ return the bbox that the legend will be anchored
+ """
+ if self._bbox_to_anchor is None:
+ return self.axes.bbox
+ else:
+ transform = self._bbox_to_anchor_transform
+ if transform is None:
+ transform = BboxTransformTo(self.axes.bbox)
+
+ return TransformedBbox(self._bbox_to_anchor,
+ transform)
+
+
+
+ def set_bbox_to_anchor(self, bbox, transform=None):
+ """
+ set the bbox that the child will be anchored.
+
+ *bbox* can be a Bbox instance, a list of [left, bottom, width,
+ height], or a list of [left, bottom] where the width and
+ height will be assumed to be zero. The bbox will be
+ transformed to display coordinate by the given transform. If
+ transform is None, axes.transAxes will be use.
+ """
+ if bbox is None:
+ self._bbox_to_anchor = None
+ elif isinstance(bbox, Bbox):
+ self._bbox_to_anchor = bbox
+ else:
+ try:
+ l = len(bbox)
+ except TypeError:
+ raise ValueError("Invalid argument for bbox : %s" % str(bbox))
+
+ if l == 2:
+ bbox = [bbox[0], bbox[1], 0, 0]
+
+ self._bbox_to_anchor = Bbox.from_bounds(*bbox)
+
+ self._bbox_to_anchor_transform = transform
+
+
def get_window_extent(self, renderer):
'''
get the bounding box in display space.
'''
+ self._update_offset_func(renderer)
w, h, xd, yd = self.get_extent(renderer)
ox, oy = self.get_offset(w, h, xd, yd)
return Bbox.from_bounds(ox-xd, oy-yd, w, h)
- def draw(self, renderer):
- if not self.get_visible(): return
+ def _update_offset_func(self, renderer, fontsize=None):
+ """
+ Update the offset func which depends on the dpi of the
+ renderer (because of the padding).
+ """
+ if fontsize is None:
+ fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
-
def _offset(w, h, xd, yd, fontsize=fontsize, self=self):
bbox = Bbox.from_bounds(0, 0, w, h)
borderpad = self.borderpad*fontsize
+ bbox_to_anchor = self.get_bbox_to_anchor()
+
x0, y0 = self._get_anchored_bbox(self.loc,
bbox,
- self.axes.bbox,
+ bbox_to_anchor,
borderpad)
return x0+xd, y0+yd
self.set_offset(_offset)
+
+ def draw(self, renderer):
+ "draw the artist"
+
+ if not self.get_visible(): return
+
+ fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
+ self._update_offset_func(renderer, fontsize)
+
if self._drawFrame:
# update the location and size of the legend
bbox = self.get_window_extent(renderer)
@@ -860,6 +974,10 @@
def _get_anchored_bbox(self, loc, bbox, parentbbox, borderpad):
+ """
+ return the position of the bbox anchored at the parentbbox
+ with the loc code, with the borderpad.
+ """
assert loc in range(1,11) # called only internally
BEST, UR, UL, LL, LR, R, CL, CR, LC, UC, C = range(11)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2009-04-17 02:31:20
|
Revision: 7046
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7046&view=rev
Author: leejjoon
Date: 2009-04-17 02:31:16 +0000 (Fri, 17 Apr 2009)
Log Message:
-----------
Fixed a offsetbox bug that multiline texts are not correctly aligned.
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/offsetbox.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-04-16 17:30:29 UTC (rev 7045)
+++ trunk/matplotlib/CHANGELOG 2009-04-17 02:31:16 UTC (rev 7046)
@@ -1,5 +1,8 @@
======================================================================
+2009-04-16 Fixed a offsetbox bug that multiline texts are not
+ correctly aligned. - JJL
+
2009-04-16 Fixed a bug in mixed mode renderer that images produced by
an rasterizing backend are placed with incorrect size.
- JJL
@@ -17,7 +20,7 @@
create an output file. Thanks to Joao Luis Silva for reporting
this. - JKS
-2009-04-05 _png.read_png() reads 12 bit PNGs (patch from
+2009-04-05 _png.read_png() reads 12 bit PNGs (patch from
Tobias Wood) - ADS
2009-04-04 Allow log axis scale to clip non-positive values to
Modified: trunk/matplotlib/lib/matplotlib/offsetbox.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/offsetbox.py 2009-04-16 17:30:29 UTC (rev 7045)
+++ trunk/matplotlib/lib/matplotlib/offsetbox.py 2009-04-17 02:31:16 UTC (rev 7046)
@@ -620,27 +620,26 @@
line = info[0][0] # first line
_, hh, dd = renderer.get_text_width_height_descent(
- clean_line, self._text._fontproperties, ismath=ismath)
+ line, self._text._fontproperties, ismath=ismath)
self._baseline_transform.clear()
- if len(info) > 1 and self._multilinebaseline: # multi line
- d = h-(hh-dd) # the baseline of the first line
+ d = h-(hh-dd) # the baseline of the first line
+ if len(info) > 1 and self._multilinebaseline:
d_new = 0.5 * h - 0.5 * (h_ - d_)
-
self._baseline_transform.translate(0, d - d_new)
d = d_new
else: # single line
- h_d = max(h_ - d_, h-dd)
+ h_d = max(h_ - d_, h-d)
if self.get_minimumdescent():
## to have a minimum descent, #i.e., "l" and "p" have same
## descents.
- d = max(dd, d_)
- else:
- d = dd
+ d = max(d, d_)
+ #else:
+ # d = d
h = h_d + d
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2009-04-16 17:30:34
|
Revision: 7045
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7045&view=rev
Author: leejjoon
Date: 2009-04-16 17:30:29 +0000 (Thu, 16 Apr 2009)
Log Message:
-----------
updated changelog for r7044
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-04-16 17:28:41 UTC (rev 7044)
+++ trunk/matplotlib/CHANGELOG 2009-04-16 17:30:29 UTC (rev 7045)
@@ -1,5 +1,9 @@
======================================================================
+2009-04-16 Fixed a bug in mixed mode renderer that images produced by
+ an rasterizing backend are placed with incorrect size.
+ - JJL
+
2008-04-14 Added Jonathan Taylor's Reinier Heeres' port of John
Porters' mplot3d to svn trunk. Package in
mpl_toolkits.mplot3d and demo is examples/mplot3d/demo.py.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <lee...@us...> - 2009-04-16 17:28:53
|
Revision: 7044
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7044&view=rev
Author: leejjoon
Date: 2009-04-16 17:28:41 +0000 (Thu, 16 Apr 2009)
Log Message:
-----------
Fixed a bug in mixed mode renderer that images produced by
an rasterizing backend are placed with incorrect size.
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backend_bases.py
trunk/matplotlib/lib/matplotlib/backends/backend_mixed.py
trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
trunk/matplotlib/lib/matplotlib/backends/backend_svg.py
Added Paths:
-----------
trunk/matplotlib/examples/misc/tight_bbox_test.py
trunk/matplotlib/lib/matplotlib/tight_bbox.py
Added: trunk/matplotlib/examples/misc/tight_bbox_test.py
===================================================================
--- trunk/matplotlib/examples/misc/tight_bbox_test.py (rev 0)
+++ trunk/matplotlib/examples/misc/tight_bbox_test.py 2009-04-16 17:28:41 UTC (rev 7044)
@@ -0,0 +1,14 @@
+import matplotlib.pyplot as plt
+import numpy as np
+
+ax = plt.axes([0.1, 0.3, 0.5, 0.5])
+
+ax.pcolormesh(np.array([[1,2],[3,4]]))
+plt.yticks([0.5, 1.5], ["long long tick label",
+ "tick label"])
+plt.ylabel("My y-label")
+plt.title("Check saved figures for their bboxes")
+for ext in ["png", "pdf", "svg", "svgz", "eps"]:
+ print "saving tight_bbox_test.%s" % (ext,)
+ plt.savefig("tight_bbox_test.%s" % (ext,), bbox_inches="tight")
+plt.show()
Modified: trunk/matplotlib/lib/matplotlib/backend_bases.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backend_bases.py 2009-04-15 17:52:23 UTC (rev 7043)
+++ trunk/matplotlib/lib/matplotlib/backend_bases.py 2009-04-16 17:28:41 UTC (rev 7044)
@@ -36,6 +36,8 @@
from matplotlib.transforms import Bbox, TransformedBbox, Affine2D
import cStringIO
+import matplotlib.tight_bbox as tight_bbox
+
class RendererBase:
"""An abstract base class to handle drawing/rendering operations.
@@ -271,7 +273,6 @@
gc.set_alpha(rgbFace[-1])
rgbFace = rgbFace[:3]
gc.set_antialiased(antialiaseds[i % Naa])
-
if Nurls:
gc.set_url(urls[i % Nurls])
@@ -1426,7 +1427,16 @@
if bbox_inches:
# call adjust_bbox to save only the given area
if bbox_inches == "tight":
- # save the figure to estimate the bounding box
+ # when bbox_inches == "tight", it saves the figure
+ # twice. The first save command is just to estimate
+ # the bounding box of the figure. A stringIO object is
+ # used as a temporary file object, but it causes a
+ # problem for some backends (ps backend with
+ # usetex=True) if they expect a filename, not a
+ # file-like object. As I think it is best to change
+ # the backend to support file-like object, i'm going
+ # to leave it as it is. However, a better solution
+ # than stringIO seems to be needed. -JJL
result = getattr(self, method_name)(
cStringIO.StringIO(),
dpi=dpi,
@@ -1439,10 +1449,13 @@
pad = kwargs.pop("pad_inches", 0.1)
bbox_inches = bbox_inches.padded(pad)
- restore_bbox = self._adjust_bbox(self.figure, format,
- bbox_inches)
+ restore_bbox = tight_bbox.adjust_bbox(self.figure, format,
+ bbox_inches)
+
+ _bbox_inches_restore = (bbox_inches, restore_bbox)
+ else:
+ _bbox_inches_restore = None
-
try:
result = getattr(self, method_name)(
filename,
@@ -1450,6 +1463,7 @@
facecolor=facecolor,
edgecolor=edgecolor,
orientation=orientation,
+ bbox_inches_restore=_bbox_inches_restore,
**kwargs)
finally:
if bbox_inches and restore_bbox:
@@ -1463,108 +1477,8 @@
return result
- def _adjust_bbox(self, fig, format, bbox_inches):
- """
- Temporarily adjust the figure so that only the specified area
- (bbox_inches) is saved.
- It modifies fig.bbox, fig.bbox_inches,
- fig.transFigure._boxout, and fig.patch. While the figure size
- changes, the scale of the original figure is conserved. A
- function whitch restores the original values are returned.
- """
- origBbox = fig.bbox
- origBboxInches = fig.bbox_inches
- _boxout = fig.transFigure._boxout
-
- asp_list = []
- locator_list = []
- for ax in fig.axes:
- pos = ax.get_position(original=False).frozen()
- locator_list.append(ax.get_axes_locator())
- asp_list.append(ax.get_aspect())
-
- def _l(a, r, pos=pos): return pos
- ax.set_axes_locator(_l)
- ax.set_aspect("auto")
-
-
-
- def restore_bbox():
-
- for ax, asp, loc in zip(fig.axes, asp_list, locator_list):
- ax.set_aspect(asp)
- ax.set_axes_locator(loc)
-
- fig.bbox = origBbox
- fig.bbox_inches = origBboxInches
- fig.transFigure._boxout = _boxout
- fig.transFigure.invalidate()
- fig.patch.set_bounds(0, 0, 1, 1)
-
- if format in ["png", "raw", "rgba"]:
- self._adjust_bbox_png(fig, bbox_inches)
- return restore_bbox
- elif format in ["pdf", "eps"]:
- self._adjust_bbox_pdf(fig, bbox_inches)
- return restore_bbox
- else:
- warnings.warn("bbox_inches option for %s backend is not implemented yet." % (format))
- return None
-
-
- def _adjust_bbox_png(self, fig, bbox_inches):
- """
- _adjust_bbox for png (Agg) format
- """
-
- tr = fig.dpi_scale_trans
-
- _bbox = TransformedBbox(bbox_inches,
- tr)
- x0, y0 = _bbox.x0, _bbox.y0
- fig.bbox_inches = Bbox.from_bounds(0, 0,
- bbox_inches.width,
- bbox_inches.height)
-
- x0, y0 = _bbox.x0, _bbox.y0
- w1, h1 = fig.bbox.width, fig.bbox.height
- self.figure.transFigure._boxout = Bbox.from_bounds(-x0, -y0,
- w1, h1)
- self.figure.transFigure.invalidate()
-
- fig.bbox = TransformedBbox(fig.bbox_inches, tr)
-
- fig.patch.set_bounds(x0/w1, y0/h1,
- fig.bbox.width/w1, fig.bbox.height/h1)
-
-
- def _adjust_bbox_pdf(self, fig, bbox_inches):
- """
- _adjust_bbox for pdf & eps format
- """
-
- tr = Affine2D().scale(72)
-
- _bbox = TransformedBbox(bbox_inches, tr)
-
- fig.bbox_inches = Bbox.from_bounds(0, 0,
- bbox_inches.width,
- bbox_inches.height)
- x0, y0 = _bbox.x0, _bbox.y0
- f = 72. / fig.dpi
- w1, h1 = fig.bbox.width*f, fig.bbox.height*f
- self.figure.transFigure._boxout = Bbox.from_bounds(-x0, -y0,
- w1, h1)
- self.figure.transFigure.invalidate()
-
- fig.bbox = TransformedBbox(fig.bbox_inches, tr)
-
- fig.patch.set_bounds(x0/w1, y0/h1,
- fig.bbox.width/w1, fig.bbox.height/h1)
-
-
def get_default_filetype(self):
raise NotImplementedError
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_mixed.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_mixed.py 2009-04-15 17:52:23 UTC (rev 7043)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_mixed.py 2009-04-16 17:28:41 UTC (rev 7044)
@@ -1,5 +1,6 @@
from matplotlib._image import frombuffer
from matplotlib.backends.backend_agg import RendererAgg
+from matplotlib.tight_bbox import process_figure_for_rasterizing
class MixedModeRenderer(object):
"""
@@ -9,8 +10,12 @@
complex objects, such as quad meshes, are rasterised and then
output as images.
"""
- def __init__(self, width, height, dpi, vector_renderer, raster_renderer_class=None):
+ def __init__(self, figure, width, height, dpi, vector_renderer,
+ raster_renderer_class=None,
+ bbox_inches_restore=None):
"""
+ figure: The figure instance.
+
width: The width of the canvas in logical units
height: The height of the canvas in logical units
@@ -38,6 +43,13 @@
self._raster_renderer = None
self._rasterizing = 0
+ # A renference to the figure is needed as we need to change
+ # the figure dpi before and after the rasterization. Although
+ # this looks ugly, I couldn't find a better solution. -JJL
+ self.figure=figure
+
+ self._bbox_inches_restore = bbox_inches_restore
+
self._set_current_renderer(vector_renderer)
_methods = """
@@ -56,6 +68,7 @@
renderer.start_rasterizing = self.start_rasterizing
renderer.stop_rasterizing = self.stop_rasterizing
+
def start_rasterizing(self):
"""
Enter "raster" mode. All subsequent drawing commands (until
@@ -65,12 +78,25 @@
If start_rasterizing is called multiple times before
stop_rasterizing is called, this method has no effect.
"""
+
+ # change the dpi of the figure temporarily.
+ self.figure.set_dpi(self.dpi)
+
+ if self._bbox_inches_restore: # when tight bbox is used
+ r = process_figure_for_rasterizing(self.figure,
+ self._bbox_inches_restore,
+ mode="png")
+
+ self._bbox_inches_restore = r
+
+
if self._rasterizing == 0:
self._raster_renderer = self._raster_renderer_class(
self._width*self.dpi, self._height*self.dpi, self.dpi)
self._set_current_renderer(self._raster_renderer)
self._rasterizing += 1
+
def stop_rasterizing(self):
"""
Exit "raster" mode. All of the drawing that was done since
@@ -91,6 +117,17 @@
image = frombuffer(buffer, w, h, True)
image.is_grayscale = False
image.flipud_out()
- self._renderer.draw_image(l, height - b - h, image, None)
+ self._renderer.draw_image(int(float(l)/self.dpi*72.),
+ int((float(height) - b - h)/self.dpi*72.),
+ image, None)
self._raster_renderer = None
self._rasterizing = False
+
+ # restore the figure dpi.
+ self.figure.set_dpi(72)
+
+ if self._bbox_inches_restore: # when tight bbox is used
+ r = process_figure_for_rasterizing(self.figure,
+ self._bbox_inches_restore,
+ mode="pdf")
+ self._bbox_inches_restore = r
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-04-15 17:52:23 UTC (rev 7043)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_pdf.py 2009-04-16 17:28:41 UTC (rev 7044)
@@ -1990,8 +1990,10 @@
else:
file = PdfFile(filename)
file.newPage(width, height)
- renderer = MixedModeRenderer(
- width, height, 72, RendererPdf(file, image_dpi))
+ _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
+ renderer = MixedModeRenderer(self.figure,
+ width, height, image_dpi, RendererPdf(file, image_dpi),
+ bbox_inches_restore=_bbox_inches_restore)
self.figure.draw(renderer)
renderer.finalize()
if isinstance(filename, PdfPages): # finish off this page
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_svg.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2009-04-15 17:52:23 UTC (rev 7043)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_svg.py 2009-04-16 17:28:41 UTC (rev 7044)
@@ -612,7 +612,7 @@
fh_to_close = None
else:
raise ValueError("filename must be a path or a file-like object")
- return self._print_svg(filename, svgwriter, fh_to_close)
+ return self._print_svg(filename, svgwriter, fh_to_close, **kwargs)
def print_svgz(self, filename, *args, **kwargs):
if is_string_like(filename):
@@ -625,7 +625,7 @@
raise ValueError("filename must be a path or a file-like object")
return self._print_svg(filename, svgwriter, fh_to_close)
- def _print_svg(self, filename, svgwriter, fh_to_close=None):
+ def _print_svg(self, filename, svgwriter, fh_to_close=None, **kwargs):
self.figure.set_dpi(72.0)
width, height = self.figure.get_size_inches()
w, h = width*72, height*72
@@ -633,8 +633,20 @@
if rcParams['svg.image_noscale']:
renderer = RendererSVG(w, h, svgwriter, filename)
else:
- renderer = MixedModeRenderer(
- width, height, 72.0, RendererSVG(w, h, svgwriter, filename))
+ # setting mixed renderer dpi other than 72 results in
+ # incorrect size of the rasterized image. It seems that the
+ # svg internally uses fixed dpi of 72 and seems to cause
+ # the problem. I hope someone who knows the svg backends
+ # take a look at this problem. Meanwhile, the dpi
+ # parameter is ignored and image_dpi is fixed at 72. - JJL
+
+ #image_dpi = kwargs.pop("dpi", 72)
+ image_dpi = 72
+ _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
+ renderer = MixedModeRenderer(self.figure,
+ width, height, image_dpi, RendererSVG(w, h, svgwriter, filename),
+ bbox_inches_restore=_bbox_inches_restore)
+
self.figure.draw(renderer)
renderer.finalize()
if fh_to_close is not None:
Added: trunk/matplotlib/lib/matplotlib/tight_bbox.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/tight_bbox.py (rev 0)
+++ trunk/matplotlib/lib/matplotlib/tight_bbox.py 2009-04-16 17:28:41 UTC (rev 7044)
@@ -0,0 +1,127 @@
+"""
+This module is to support *bbox_inches* option in savefig command.
+"""
+
+import warnings
+from matplotlib.transforms import Bbox, TransformedBbox, Affine2D
+
+
+def adjust_bbox(fig, format, bbox_inches):
+ """
+ Temporarily adjust the figure so that only the specified area
+ (bbox_inches) is saved.
+
+ It modifies fig.bbox, fig.bbox_inches,
+ fig.transFigure._boxout, and fig.patch. While the figure size
+ changes, the scale of the original figure is conserved. A
+ function whitch restores the original values are returned.
+ """
+
+ origBbox = fig.bbox
+ origBboxInches = fig.bbox_inches
+ _boxout = fig.transFigure._boxout
+
+ asp_list = []
+ locator_list = []
+ for ax in fig.axes:
+ pos = ax.get_position(original=False).frozen()
+ locator_list.append(ax.get_axes_locator())
+ asp_list.append(ax.get_aspect())
+
+ def _l(a, r, pos=pos): return pos
+ ax.set_axes_locator(_l)
+ ax.set_aspect("auto")
+
+
+
+ def restore_bbox():
+
+ for ax, asp, loc in zip(fig.axes, asp_list, locator_list):
+ ax.set_aspect(asp)
+ ax.set_axes_locator(loc)
+
+ fig.bbox = origBbox
+ fig.bbox_inches = origBboxInches
+ fig.transFigure._boxout = _boxout
+ fig.transFigure.invalidate()
+ fig.patch.set_bounds(0, 0, 1, 1)
+
+ if format in ["png", "raw", "rgba"]:
+ adjust_bbox_png(fig, bbox_inches)
+ return restore_bbox
+ elif format in ["pdf", "eps", "svg", "svgz"]:
+ adjust_bbox_pdf(fig, bbox_inches)
+ return restore_bbox
+ else:
+ warnings.warn("bbox_inches option for %s backend is not implemented yet." % (format))
+ return None
+
+
+def adjust_bbox_png(fig, bbox_inches):
+ """
+ adjust_bbox for png (Agg) format
+ """
+
+ tr = fig.dpi_scale_trans
+
+ _bbox = TransformedBbox(bbox_inches,
+ tr)
+ x0, y0 = _bbox.x0, _bbox.y0
+ fig.bbox_inches = Bbox.from_bounds(0, 0,
+ bbox_inches.width,
+ bbox_inches.height)
+
+ x0, y0 = _bbox.x0, _bbox.y0
+ w1, h1 = fig.bbox.width, fig.bbox.height
+ fig.transFigure._boxout = Bbox.from_bounds(-x0, -y0,
+ w1, h1)
+ fig.transFigure.invalidate()
+
+ fig.bbox = TransformedBbox(fig.bbox_inches, tr)
+
+ fig.patch.set_bounds(x0/w1, y0/h1,
+ fig.bbox.width/w1, fig.bbox.height/h1)
+
+
+def adjust_bbox_pdf(fig, bbox_inches):
+ """
+ adjust_bbox for pdf & eps format
+ """
+
+ tr = Affine2D().scale(72)
+
+ _bbox = TransformedBbox(bbox_inches, tr)
+
+ fig.bbox_inches = Bbox.from_bounds(0, 0,
+ bbox_inches.width,
+ bbox_inches.height)
+ x0, y0 = _bbox.x0, _bbox.y0
+ f = 72. / fig.dpi
+ w1, h1 = fig.bbox.width*f, fig.bbox.height*f
+ fig.transFigure._boxout = Bbox.from_bounds(-x0, -y0,
+ w1, h1)
+ fig.transFigure.invalidate()
+
+ fig.bbox = TransformedBbox(fig.bbox_inches, tr)
+
+ fig.patch.set_bounds(x0/w1, y0/h1,
+ fig.bbox.width/w1, fig.bbox.height/h1)
+
+
+def process_figure_for_rasterizing(figure,
+ bbox_inches_restore, mode):
+
+ """
+ This need to be called when figure dpi changes during the drawing
+ (e.g., rasterizing). It recovers the bbox and re-adjust it with
+ the new dpi.
+ """
+
+ bbox_inches, restore_bbox = bbox_inches_restore
+ restore_bbox()
+ r = adjust_bbox(figure, mode,
+ bbox_inches)
+
+ return bbox_inches, r
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-04-15 17:52:32
|
Revision: 7043
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7043&view=rev
Author: jdh2358
Date: 2009-04-15 17:52:23 +0000 (Wed, 15 Apr 2009)
Log Message:
-----------
Merged revisions 7042 via svnmerge from
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/v0_98_5_maint
........
r7042 | jdh2358 | 2009-04-15 10:47:18 -0700 (Wed, 15 Apr 2009) | 1 line
fix for tkagg filextension bug reported by fperez
........
Modified Paths:
--------------
trunk/matplotlib/lib/matplotlib/backends/backend_tkagg.py
Property Changed:
----------------
trunk/matplotlib/
trunk/matplotlib/doc/pyplots/README
trunk/matplotlib/doc/sphinxext/gen_gallery.py
trunk/matplotlib/doc/sphinxext/gen_rst.py
trunk/matplotlib/lib/matplotlib/sphinxext/mathmpl.py
trunk/matplotlib/lib/matplotlib/sphinxext/only_directives.py
trunk/matplotlib/lib/matplotlib/sphinxext/plot_directive.py
Property changes on: trunk/matplotlib
___________________________________________________________________
Modified: svnmerge-integrated
- /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-7039
+ /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-7042
Modified: svn:mergeinfo
- /branches/v0_91_maint:5753-5771
/branches/v0_98_5_maint:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773,6781,6792,6800,6802,6805,6809,6811,6822,6827,6850,6854,6856,6859,6861-6873,6883-6884,6886,6890-6891,6906-6909,6911-6912,6915-6916,6918,6920-6925,6927-6928,6934,6941,6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035
+ /branches/v0_91_maint:5753-5771
/branches/v0_98_5_maint:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773,6781,6792,6800,6802,6805,6809,6811,6822,6827,6850,6854,6856,6859,6861-6873,6883-6884,6886,6890-6891,6906-6909,6911-6912,6915-6916,6918,6920-6925,6927-6928,6934,6941,6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035,7042
Property changes on: trunk/matplotlib/doc/pyplots/README
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_98_5_maint/doc/pyplots/README:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773,6781,6792,6800,6802,6805,6822,6827,6850,6854,6856,6859,6861-6873,6883-6884,6886,6890-6891,6911-6912,6915-6916,6918,6920-6925,6927-6928,6934,6941,6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035
+ /branches/v0_98_5_maint/doc/pyplots/README:6581,6585,6587,6589-6609,6614,6616,6625,6652,6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773,6781,6792,6800,6802,6805,6822,6827,6850,6854,6856,6859,6861-6873,6883-6884,6886,6890-6891,6911-6912,6915-6916,6918,6920-6925,6927-6928,6934,6941,6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035,7042
Property changes on: trunk/matplotlib/doc/sphinxext/gen_gallery.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/_templates/gen_gallery.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_gallery.py:6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773,6781,6792,6800,6802,6805,6822,6827,6850,6854,6856,6859,6861-6873,6883-6884,6886,6890-6891,6911-6912,6915-6916,6918,6920-6925,6927-6928,6934,6941,6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035
+ /branches/v0_91_maint/doc/_templates/gen_gallery.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_gallery.py:6660-6662,6672-6673,6714-6715,6717-6732,6752-6754,6761-6773,6781,6792,6800,6802,6805,6822,6827,6850,6854,6856,6859,6861-6873,6883-6884,6886,6890-6891,6911-6912,6915-6916,6918,6920-6925,6927-6928,6934,6941,6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035,7042
Property changes on: trunk/matplotlib/doc/sphinxext/gen_rst.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/examples/gen_rst.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_rst.py:6714-6715,6717-6732,6752-6754,6761-6773,6781,6792,6800,6802,6805,6822,6827,6850,6854,6856,6859,6861-6873,6883-6884,6886,6890-6891,6911-6912,6915-6916,6918,6920-6925,6927-6928,6934,6941,6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035
+ /branches/v0_91_maint/doc/examples/gen_rst.py:5753-5771
/branches/v0_98_5_maint/doc/sphinxext/gen_rst.py:6714-6715,6717-6732,6752-6754,6761-6773,6781,6792,6800,6802,6805,6822,6827,6850,6854,6856,6859,6861-6873,6883-6884,6886,6890-6891,6911-6912,6915-6916,6918,6920-6925,6927-6928,6934,6941,6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035,7042
Modified: trunk/matplotlib/lib/matplotlib/backends/backend_tkagg.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/backends/backend_tkagg.py 2009-04-15 17:47:18 UTC (rev 7042)
+++ trunk/matplotlib/lib/matplotlib/backends/backend_tkagg.py 2009-04-15 17:52:23 UTC (rev 7043)
@@ -708,11 +708,17 @@
tk_filetypes = [
(name, '*.%s' % ext) for (ext, name) in sorted_filetypes]
+ # adding a default extension seems to break the
+ # asksaveasfilename dialog when you choose various save types
+ # from the dropdown. Passing in the empty string seems to
+ # work - JDH
+ #defaultextension = self.canvas.get_default_filetype()
+ defaultextension = ''
fname = asksaveasfilename(
master=self.window,
title='Save the figure',
filetypes = tk_filetypes,
- defaultextension = self.canvas.get_default_filetype()
+ defaultextension = defaultextension
)
if fname == "" or fname == ():
Property changes on: trunk/matplotlib/lib/matplotlib/sphinxext/mathmpl.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/sphinxext/mathmpl.py:5753-5771
/branches/v0_98_5_maint/lib/matplotlib/sphinxext/mathmpl.py:6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035
+ /branches/v0_91_maint/doc/sphinxext/mathmpl.py:5753-5771
/branches/v0_98_5_maint/lib/matplotlib/sphinxext/mathmpl.py:6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035,7042
Property changes on: trunk/matplotlib/lib/matplotlib/sphinxext/only_directives.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/sphinxext/only_directives.py:5753-5771
/branches/v0_98_5_maint/lib/matplotlib/sphinxext/only_directives.py:6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035
+ /branches/v0_91_maint/doc/sphinxext/only_directives.py:5753-5771
/branches/v0_98_5_maint/lib/matplotlib/sphinxext/only_directives.py:6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035,7042
Property changes on: trunk/matplotlib/lib/matplotlib/sphinxext/plot_directive.py
___________________________________________________________________
Modified: svn:mergeinfo
- /branches/v0_91_maint/doc/sphinxext/plot_directive.py:5753-5771
/branches/v0_98_5_maint/lib/matplotlib/sphinxext/plot_directive.py:6920-6925,6934,6941,6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035
+ /branches/v0_91_maint/doc/sphinxext/plot_directive.py:5753-5771
/branches/v0_98_5_maint/lib/matplotlib/sphinxext/plot_directive.py:6920-6925,6934,6941,6946,6948,6950,6952,6960,6972,6984-6985,6990,6995,6997-7001,7014,7016,7018,7024-7025,7033,7035,7042
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-04-15 17:47:21
|
Revision: 7042
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7042&view=rev
Author: jdh2358
Date: 2009-04-15 17:47:18 +0000 (Wed, 15 Apr 2009)
Log Message:
-----------
fix for tkagg filextension bug reported by fperez
Modified Paths:
--------------
branches/v0_98_5_maint/lib/matplotlib/backends/backend_tkagg.py
Modified: branches/v0_98_5_maint/lib/matplotlib/backends/backend_tkagg.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/backends/backend_tkagg.py 2009-04-14 14:29:31 UTC (rev 7041)
+++ branches/v0_98_5_maint/lib/matplotlib/backends/backend_tkagg.py 2009-04-15 17:47:18 UTC (rev 7042)
@@ -708,11 +708,17 @@
tk_filetypes = [
(name, '*.%s' % ext) for (ext, name) in sorted_filetypes]
+ # adding a default extension seems to break the
+ # asksaveasfilename dialog when you choose various save types
+ # from the dropdown. Passing in the empty string seems to
+ # work - JDH
+ #defaultextension = self.canvas.get_default_filetype()
+ defaultextension = ''
fname = asksaveasfilename(
master=self.window,
title='Save the figure',
filetypes = tk_filetypes,
- defaultextension = self.canvas.get_default_filetype()
+ defaultextension = defaultextension
)
if fname == "" or fname == ():
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-04-14 14:29:36
|
Revision: 7041
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7041&view=rev
Author: jdh2358
Date: 2009-04-14 14:29:31 +0000 (Tue, 14 Apr 2009)
Log Message:
-----------
added mpl_toolkits.mplot3d
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/doc/users/credits.rst
trunk/matplotlib/doc/users/toolkits.rst
trunk/matplotlib/examples/pylab_examples/finance_work2.py
trunk/matplotlib/examples/tests/backend_driver.py
trunk/matplotlib/setup.py
Added Paths:
-----------
trunk/matplotlib/examples/mplot3d/
trunk/matplotlib/examples/mplot3d/demo.py
trunk/matplotlib/lib/mpl_toolkits/mplot3d/
trunk/matplotlib/lib/mpl_toolkits/mplot3d/__init__.py
trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py
trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py
trunk/matplotlib/lib/mpl_toolkits/mplot3d/axis3d.py
trunk/matplotlib/lib/mpl_toolkits/mplot3d/proj3d.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-04-13 03:02:41 UTC (rev 7040)
+++ trunk/matplotlib/CHANGELOG 2009-04-14 14:29:31 UTC (rev 7041)
@@ -1,6 +1,11 @@
======================================================================
-2008-04-12 Release 0.98.5.3 at r7038
+2008-04-14 Added Jonathan Taylor's Reinier Heeres' port of John
+ Porters' mplot3d to svn trunk. Package in
+ mpl_toolkits.mplot3d and demo is examples/mplot3d/demo.py.
+ Thanks Reiner
+
+
2009-04-06 The pdf backend now escapes newlines and linefeeds in strings.
Fixes sf bug #2708559; thanks to Tiago Pereira for the report.
Modified: trunk/matplotlib/doc/users/credits.rst
===================================================================
--- trunk/matplotlib/doc/users/credits.rst 2009-04-13 03:02:41 UTC (rev 7040)
+++ trunk/matplotlib/doc/users/credits.rst 2009-04-14 14:29:31 UTC (rev 7041)
@@ -166,4 +166,9 @@
base. He also rewrote the transformation infrastructure to support
custom projections and scales.
+John Porter, Jonathon Taylor and Reinier Heeres
+ John Porter wrote the mplot3d module for basic 3D plotting in
+ matplotlib, and Jonathon Taylor and Reinier Heeres ported it to the
+ refactored transform trunk.
+
Modified: trunk/matplotlib/doc/users/toolkits.rst
===================================================================
--- trunk/matplotlib/doc/users/toolkits.rst 2009-04-13 03:02:41 UTC (rev 7040)
+++ trunk/matplotlib/doc/users/toolkits.rst 2009-04-14 14:29:31 UTC (rev 7041)
@@ -37,10 +37,19 @@
Natgrid
========
-
+
mpl_toolkits.natgrid is an interface to natgrid C library for gridding
irregularly spaced data. This requires a separate installation of the
natgrid toolkit from the sourceforge `download
<http://sourceforge.net/project/showfiles.php?group_id=80706&package_id=142792>`_
page.
-
+
+.. _toolkit_mplot3d:
+
+mplot3d
+===========
+
+mpl_toolkits.mplot3d provides some basic 3D plotting (scatter, surf,
+line, mesh) tools. Not the fastest or feature complete 3D library out
+there, but ships with matplotlib and thus may be a lighter weight
+solution for some use cases.
Added: trunk/matplotlib/examples/mplot3d/demo.py
===================================================================
--- trunk/matplotlib/examples/mplot3d/demo.py (rev 0)
+++ trunk/matplotlib/examples/mplot3d/demo.py 2009-04-14 14:29:31 UTC (rev 7041)
@@ -0,0 +1,138 @@
+import random
+import numpy as np
+import matplotlib.pyplot as plt
+import mpl_toolkits.mplot3d.axes3d as axes3d
+from matplotlib.colors import Normalize, colorConverter
+
+def test_scatter():
+ f = plt.figure()
+ ax = axes3d.Axes3D(f)
+
+ n = 100
+ for c,zl,zh in [('r',-50,-25),('b',-30,-5)]:
+ xs,ys,zs = zip(*
+ [(random.randrange(23,32),
+ random.randrange(100),
+ random.randrange(zl,zh)
+ ) for i in range(n)])
+ ax.scatter3D(xs,ys,zs, c=c)
+
+ ax.set_xlabel('------------ X Label --------------------')
+ ax.set_ylabel('------------ Y Label --------------------')
+ ax.set_zlabel('------------ Z Label --------------------')
+
+def test_wire():
+ f = plt.figure()
+ ax = axes3d.Axes3D(f)
+
+ X,Y,Z = axes3d.get_test_data(0.05)
+ ax.plot_wireframe(X,Y,Z, rstride=10,cstride=10)
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+
+def test_surface():
+ f = plt.figure()
+ ax = axes3d.Axes3D(f)
+
+ X,Y,Z = axes3d.get_test_data(0.05)
+ ax.plot_surface(X,Y,Z, rstride=10,cstride=10)
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+
+def test_contour():
+ f = plt.figure()
+ ax = axes3d.Axes3D(f)
+
+ X,Y,Z = axes3d.get_test_data(0.05)
+ cset = ax.contour3D(X,Y,Z)
+ ax.clabel(cset, fontsize=9, inline=1)
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+
+def test_contourf():
+ f = plt.figure()
+ ax = axes3d.Axes3D(f)
+
+ X,Y,Z = axes3d.get_test_data(0.05)
+ cset = ax.contourf3D(X,Y,Z)
+ ax.clabel(cset, fontsize=9, inline=1)
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+
+def test_plot():
+ f = plt.figure()
+ ax = axes3d.Axes3D(f)
+
+ xs = np.arange(0,4*np.pi+0.1,0.1)
+ ys = np.sin(xs)
+ ax.plot(xs,ys, label='zl')
+ ax.plot(xs,ys+max(xs),label='zh')
+ ax.plot(xs,ys,dir='x', label='xl')
+ ax.plot(xs,ys,dir='x', z=max(xs),label='xh')
+ ax.plot(xs,ys,dir='y', label='yl')
+ ax.plot(xs,ys,dir='y', z=max(xs), label='yh')
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+ ax.legend()
+
+def test_polys():
+ f = plt.figure()
+ ax = axes3d.Axes3D(f)
+
+ cc = lambda arg: colorConverter.to_rgba(arg, alpha=0.6)
+
+ xs = np.arange(0,10,0.4)
+ verts = []
+ zs = [0.0,1.0,2.0,3.0]
+ for z in zs:
+ ys = [random.random() for x in xs]
+ ys[0],ys[-1] = 0,0
+ verts.append(zip(xs,ys))
+
+ from matplotlib.collections import PolyCollection
+ poly = PolyCollection(verts, facecolors = [cc('r'),cc('g'),cc('b'),
+ cc('y')])
+ poly.set_alpha(0.7)
+ ax.add_collection(poly,zs=zs,dir='y')
+
+ ax.set_xlim(0,10)
+ ax.set_ylim(-1,4)
+ ax.set_zlim(0,1)
+
+def test_scatter2D():
+ f = plt.figure()
+ ax = axes3d.Axes3D(f)
+
+ xs = [random.random() for i in range(20)]
+ ys = [random.random() for x in xs]
+ ax.scatter(xs, ys)
+ ax.scatter(xs, ys, dir='y', c='r')
+ ax.scatter(xs, ys, dir='x', c='g')
+
+def test_bar2D():
+ f = plt.figure()
+ ax = axes3d.Axes3D(f)
+
+ for c,z in zip(['r','g','b', 'y'],[30,20,10,0]):
+ xs = np.arange(20)
+ ys = [random.random() for x in xs]
+ ax.bar(xs, ys, z=z, dir='y', color=c, alpha=0.8)
+
+if __name__ == "__main__":
+
+ test_scatter()
+ test_wire()
+ test_surface()
+ test_contour()
+ test_contourf()
+ test_plot()
+ test_polys()
+ test_scatter2D()
+# test_bar2D()
+
+ plt.show()
Modified: trunk/matplotlib/examples/pylab_examples/finance_work2.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/finance_work2.py 2009-04-13 03:02:41 UTC (rev 7040)
+++ trunk/matplotlib/examples/pylab_examples/finance_work2.py 2009-04-14 14:29:31 UTC (rev 7041)
@@ -216,10 +216,21 @@
+class MyLocator(mticker.MaxNLocator):
+ def __init__(self, *args, **kwargs):
+ mticker.MaxNLocator.__init__(self, *args, **kwargs)
+
+ def __call__(self, *args, **kwargs):
+ return mticker.MaxNLocator.__call__(self, *args, **kwargs)
+
# at most 5 ticks, pruning the upper and lower so they don't overlap
# with other ticks
-ax2.yaxis.set_major_locator(mticker.MaxNLocator(5, prune='both'))
-ax3.yaxis.set_major_locator(mticker.MaxNLocator(5, prune='both'))
+#ax2.yaxis.set_major_locator(mticker.MaxNLocator(5, prune='both'))
+#ax3.yaxis.set_major_locator(mticker.MaxNLocator(5, prune='both'))
+
+ax2.yaxis.set_major_locator(MyLocator(5, prune='both'))
+ax3.yaxis.set_major_locator(MyLocator(5, prune='both'))
+
plt.show()
Modified: trunk/matplotlib/examples/tests/backend_driver.py
===================================================================
--- trunk/matplotlib/examples/tests/backend_driver.py 2009-04-13 03:02:41 UTC (rev 7040)
+++ trunk/matplotlib/examples/tests/backend_driver.py 2009-04-14 14:29:31 UTC (rev 7041)
@@ -240,6 +240,11 @@
]
+mplot3d_dir = os.path.join('..', 'mplot3d')
+mplot3d_files = [
+ 'demo.py',
+ ]
+
# dict from dir to files we know we don't want to test (eg examples
# not using pyplot, examples requiring user input, animation examples,
# examples that may only work in certain environs (usetex examples?),
@@ -271,7 +276,8 @@
files = (
[os.path.join(api_dir, fname) for fname in api_files] +
[os.path.join(pylab_dir, fname) for fname in pylab_files] +
- [os.path.join(units_dir, fname) for fname in units_files]
+ [os.path.join(units_dir, fname) for fname in units_files] +
+ [os.path.join(mplot3d_dir, fname) for fname in mplot3d_files]
)
# tests known to fail on a given backend
Added: trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py (rev 0)
+++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/art3d.py 2009-04-14 14:29:31 UTC (rev 7041)
@@ -0,0 +1,269 @@
+#!/usr/bin/python
+# art3d.py, original mplot3d version by John Porter
+# Parts rewritten by Reinier Heeres <re...@he...>
+
+from matplotlib import lines, text, path as mpath
+from matplotlib.collections import Collection, LineCollection, \
+ PolyCollection, PatchCollection
+from matplotlib.patches import Patch, Rectangle
+from matplotlib.colors import Normalize
+from matplotlib import transforms
+
+import types
+import numpy as np
+import proj3d
+
+class Text3D(text.Text):
+
+ def __init__(self, x=0, y=0, z=0, text='', dir='z'):
+ text.Text.__init__(self, x, y, text)
+ self.set_3d_properties(z, dir)
+
+ def set_3d_properties(self, z=0, dir='z'):
+ x, y = self.get_position()
+ self._position3d = juggle_axes(x, y, z, dir)
+
+ def draw(self, renderer):
+ x, y, z = self._position3d
+ x, y, z = proj3d.proj_transform(x, y, z, renderer.M)
+ self.set_position(x, y)
+ text.Text.draw(self, renderer)
+
+def text_2d_to_3d(obj, z=0, dir='z'):
+ """Convert a Text to a Text3D object."""
+ obj.__class__ = Text3D
+ obj.set_3d_properties(z, dir)
+
+class Line3D(lines.Line2D):
+
+ def __init__(self, xs, ys, zs, *args, **kwargs):
+ lines.Line2D.__init__(self, [], [], *args, **kwargs)
+ self._verts3d = xs, ys, zs
+
+ def set_3d_properties(self, zs=0, dir='z'):
+ xs = self.get_xdata()
+ ys = self.get_ydata()
+ try:
+ zs = float(zs)
+ zs = [zs for x in xs]
+ except:
+ pass
+ self._verts3d = juggle_axes(xs, ys, zs, dir)
+
+ def draw(self, renderer):
+ xs3d, ys3d, zs3d = self._verts3d
+ xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
+ self.set_data(xs, ys)
+ lines.Line2D.draw(self, renderer)
+
+def line_2d_to_3d(line, z=0, dir='z'):
+ line.__class__ = Line3D
+ line.set_3d_properties(z, dir)
+
+def path_to_3d_segment(path, z=0, dir='z'):
+ '''Convert a path to a 3d segment.'''
+ seg = []
+ for (pathseg, code) in path.iter_segments():
+ seg.append(pathseg)
+ seg3d = [juggle_axes(x, y, z, dir) for (x, y) in seg]
+ return seg3d
+
+def paths_to_3d_segments(paths, zs=0, dir='z'):
+ '''Convert paths from a collection object to 3d segments.'''
+
+ try:
+ zs = float(zs)
+ zs = [zs for i in range(len(paths))]
+ except:
+ pass
+
+ segments = []
+ for path, z in zip(paths, zs):
+ segments.append(path_to_3d_segment(path, z, dir))
+ return segments
+
+class Line3DCollection(LineCollection):
+
+ def __init__(self, segments, *args, **kwargs):
+ LineCollection.__init__(self, segments, *args, **kwargs)
+
+ def set_segments(self, segments):
+ self._segments3d = segments
+ LineCollection.set_segments(self, [])
+
+ def draw(self, renderer):
+ xyslist = [
+ proj3d.proj_trans_points(points, renderer.M) for points in
+ self._segments3d]
+ segments_2d = [zip(xs,ys) for (xs,ys,zs) in xyslist]
+ LineCollection.set_segments(self, segments_2d)
+ LineCollection.draw(self, renderer)
+
+def line_collection_2d_to_3d(col, z=0, dir='z'):
+ """Convert a LineCollection to a Line3DCollection object."""
+ segments3d = paths_to_3d_segments(col.get_paths(), z, dir)
+ col.__class__ = Line3DCollection
+ col.set_segments(segments3d)
+
+class Patch3D(Patch):
+
+ def __init__(self, *args, **kwargs):
+ zs = kwargs.pop('zs', [])
+ dir = kwargs.pop('dir', 'z')
+ Patch.__init__(self, *args, **kwargs)
+ self.set_3d_properties(zs, dir)
+
+ def set_3d_properties(self, verts, z=0, dir='z'):
+ self._segment3d = [juggle_axes(x, y, z, dir) for (x, y) in verts]
+ self._facecolor3d = Patch.get_facecolor(self)
+
+ def get_path(self):
+ return self._path2d
+
+ def get_facecolor(self):
+ return self._facecolor2d
+
+ def draw(self, renderer):
+ s = self._segment3d
+ xs, ys, zs = zip(*s)
+ vxs,vys,vzs,vis = proj3d.proj_transform_clip(xs,ys,zs, renderer.M)
+ self._path2d = mpath.Path(zip(vxs, vys))
+ # FIXME: coloring
+ self._facecolor2d = self._facecolor3d
+ Patch.draw(self, renderer)
+
+def patch_2d_to_3d(patch, z=0, dir='z'):
+ """Convert a Patch to a Patch3D object."""
+ verts = patch.get_verts()
+ patch.__class__ = Patch3D
+ patch.set_3d_properties(verts, z, dir)
+
+class Patch3DCollection(PatchCollection):
+
+ def __init__(self, *args, **kwargs):
+ PatchCollection.__init__(self, *args, **kwargs)
+
+ def set_3d_properties(self, zs, dir):
+ xs, ys = zip(*self.get_offsets())
+ self._offsets3d = juggle_axes(xs, ys, zs, dir)
+ self._facecolor3d = self.get_facecolor()
+ self._edgecolor3d = self.get_edgecolor()
+
+ def draw(self, renderer):
+ xs,ys,zs = self._offsets3d
+ vxs,vys,vzs,vis = proj3d.proj_transform_clip(xs,ys,zs, renderer.M)
+ #FIXME: mpl allows us no way to unset the collection alpha value
+ self._alpha = None
+ self.set_facecolors(zalpha(self._facecolor3d, vzs))
+ self.set_edgecolors(zalpha(self._edgecolor3d, vzs))
+ PatchCollection.set_offsets(self, zip(vxs, vys))
+ PatchCollection.draw(self, renderer)
+
+def patch_collection_2d_to_3d(col, zs=0, dir='z'):
+ """Convert a PatchCollection to a Patch3DCollection object."""
+ col.__class__ = Patch3DCollection
+ col.set_3d_properties(zs, dir)
+
+class Poly3DCollection(PolyCollection):
+
+ def __init__(self, verts, *args, **kwargs):
+ PolyCollection.__init__(self, verts, *args, **kwargs)
+ self.set_3d_properties()
+
+ def get_vector(self, segments3d):
+ """optimise points for projection"""
+ si = 0
+ ei = 0
+ segis = []
+ points = []
+ for p in segments3d:
+ points.extend(p)
+ ei = si+len(p)
+ segis.append((si,ei))
+ si = ei
+ xs,ys,zs = zip(*points)
+ ones = np.ones(len(xs))
+ self._vec = np.array([xs,ys,zs,ones])
+ self._segis = segis
+
+ def set_verts(self, verts, closed=True):
+ self.get_vector(verts)
+ # 2D verts will be updated at draw time
+ PolyCollection.set_verts(self, [], closed)
+
+ def set_3d_properties(self):
+ self._zsort = 1
+ self._facecolors3d = PolyCollection.get_facecolors(self)
+ self._edgecolors3d = self.get_edgecolors()
+
+ def get_facecolors(self):
+ return self._facecolors2d
+ get_facecolor = get_facecolors
+
+ def draw(self, renderer):
+ txs, tys, tzs, tis = proj3d.proj_transform_vec_clip(self._vec, renderer.M)
+ xyslist = [(txs[si:ei], tys[si:ei], tzs[si:ei], tis[si:ei]) \
+ for si, ei in self._segis]
+ colors = self._facecolors3d
+ #
+ # if required sort by depth (furthest drawn first)
+ if self._zsort:
+ z_segments_2d = [(min(zs),max(tis),zip(xs,ys),c) for
+ (xs,ys,zs,tis),c in zip(xyslist,colors)]
+ z_segments_2d.sort()
+ z_segments_2d.reverse()
+ else:
+ raise ValueError, "whoops"
+ segments_2d = [s for z,i,s,c in z_segments_2d if i]
+ colors = [c for z,i,s,c in z_segments_2d if i]
+ PolyCollection.set_verts(self, segments_2d)
+ self._facecolors2d = colors
+ return Collection.draw(self, renderer)
+
+def poly_collection_2d_to_3d(col, zs=None, dir='z'):
+ """Convert a PolyCollection to a Poly3DCollection object."""
+ segments_3d = paths_to_3d_segments(col.get_paths(), zs, dir)
+ col.__class__ = Poly3DCollection
+ col.set_verts(segments_3d)
+ col.set_3d_properties()
+
+def juggle_axes(xs,ys,zs, dir):
+ """
+ Depending on the direction of the plot re-order the axis.
+ This is so that 2d plots can be plotted along any direction.
+ """
+ if dir == 'x': return zs,xs,ys
+ elif dir == 'y': return xs,zs,ys
+ else: return xs,ys,zs
+
+def iscolor(c):
+ try:
+ return (len(c) == 4 or len(c) == 3) and hasattr(c[0], '__float__')
+ except (IndexError):
+ return False
+
+def get_colors(c, num):
+ """Stretch the color argument to provide the required number num"""
+
+ if type(c)==type("string"):
+ c = colors.colorConverter.to_rgba(colors)
+
+ if iscolor(c):
+ return [c] * num
+ if len(c) == num:
+ return c
+ elif iscolor(c):
+ return [c] * num
+ elif iscolor(c[0]):
+ return [c[0]] * num
+ else:
+ raise ValueError, 'unknown color format %s' % c
+
+def zalpha(colors, zs):
+ """Modify the alphas of the color list according to depth"""
+ colors = get_colors(colors,len(zs))
+ norm = Normalize(min(zs),max(zs))
+ sats = 1 - norm(zs)*0.7
+ colors = [(c[0],c[1],c[2],c[3]*s) for c,s in zip(colors,sats)]
+ return colors
+
Added: trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py (rev 0)
+++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/axes3d.py 2009-04-14 14:29:31 UTC (rev 7041)
@@ -0,0 +1,868 @@
+#!/usr/bin/python
+# axes3d.py, original mplot3d version by John Porter
+# Created: 23 Sep 2005
+# Parts fixed by Reinier Heeres <re...@he...>
+
+"""
+3D projection glued onto 2D Axes.
+
+Axes3D
+"""
+
+from matplotlib import pyplot as plt
+import random
+
+from matplotlib.axes import Axes
+from matplotlib import cbook
+from matplotlib.transforms import Bbox
+import numpy as np
+from matplotlib.colors import Normalize, colorConverter
+
+import art3d
+import proj3d
+import axis3d
+
+def sensible_format_data(self, value):
+ """Used to generate more comprehensible numbers in status bar"""
+ if abs(value) > 1e4 or abs(value)<1e-3:
+ s = '%1.4e'% value
+ return self._formatSciNotation(s)
+ else:
+ return '%4.3f' % value
+
+def unit_bbox():
+ box = Bbox(np.array([[0,0],[1,1]]))
+ return box
+
+class Axes3DI(Axes):
+ """Wrap an Axes object
+
+ The x,y data coordinates, which are manipulated by set_xlim and
+ set_ylim are used as the target view coordinates by the 3D
+ transformations. These coordinates are mostly invisible to the
+ outside world.
+
+ set_w_xlim, set_w_ylim and set_w_zlim manipulate the 3D world
+ coordinates which are scaled to represent the data and are stored
+ in the xy_dataLim, zz_datalim bboxes.
+
+ The axes representing the x,y,z world dimensions are self.w_xaxis,
+ self.w_yaxis and self.w_zaxis. They can probably be controlled in
+ more or less the normal ways.
+ """
+ def __init__(self, fig, rect=[0.0, 0.0, 1.0, 1.0], *args, **kwargs):
+ self.fig = fig
+ self.cids = []
+
+ azim = kwargs.pop('azim', -60)
+ elev = kwargs.pop('elev', 30)
+
+ self.xy_viewLim = unit_bbox()
+ self.zz_viewLim = unit_bbox()
+ self.xy_dataLim = unit_bbox()
+ self.zz_dataLim = unit_bbox()
+ # inihibit autoscale_view until the axises are defined
+ # they can't be defined until Axes.__init__ has been called
+ self.view_init(elev, azim)
+ self._ready = 0
+ Axes.__init__(self, self.fig, rect,
+ frameon=True,
+ xticks=[], yticks=[], *args, **kwargs)
+
+ self.M = None
+
+ self._ready = 1
+ self.mouse_init()
+ self.create_axes()
+ self.set_top_view()
+
+ self.axesPatch.set_linewidth(0)
+ self.fig.add_axes(self)
+
+ def set_top_view(self):
+ # this happens to be the right view for the viewing coordinates
+ # moved up and to the left slightly to fit labels and axes
+ xdwl = (0.95/self.dist)
+ xdw = (0.9/self.dist)
+ ydwl = (0.95/self.dist)
+ ydw = (0.9/self.dist)
+ #
+ self.set_xlim(-xdwl,xdw)
+ self.set_ylim(-ydwl,ydw)
+
+ def really_set_xlim(self, vmin, vmax):
+ self.viewLim.intervalx().set_bounds(vmin, vmax)
+
+ def really_set_ylim(self, vmin, vmax):
+ self.viewLim.intervaly().set_bounds(vmin, vmax)
+
+ def vlim_argument(self, get_lim, *args):
+ if not args:
+ vmin,vmax = get_lim()
+ elif len(args)==2:
+ vmin,vmax = args
+ elif len(args)==1:
+ vmin,vmax = args[0]
+ return vmin,vmax
+
+ def nset_xlim(self, *args):
+ raise
+ vmin,vmax = self.vlim_argument(self.get_xlim)
+ print 'xlim', vmin,vmax
+
+ def nset_ylim(self, *args):
+ vmin,vmax = self.vlim_argument(self.get_ylim)
+ print 'ylim', vmin,vmax
+
+ def create_axes(self):
+ self.w_xaxis = axis3d.XAxis('x',self.xy_viewLim.intervalx,
+ self.xy_dataLim.intervalx, self)
+ self.w_yaxis = axis3d.YAxis('y',self.xy_viewLim.intervaly,
+ self.xy_dataLim.intervaly, self)
+ self.w_zaxis = axis3d.ZAxis('z',self.zz_viewLim.intervalx,
+ self.zz_dataLim.intervalx, self)
+
+ def unit_cube(self,vals=None):
+ minx,maxx,miny,maxy,minz,maxz = vals or self.get_w_lims()
+ xs,ys,zs = ([minx,maxx,maxx,minx,minx,maxx,maxx,minx],
+ [miny,miny,maxy,maxy,miny,miny,maxy,maxy],
+ [minz,minz,minz,minz,maxz,maxz,maxz,maxz])
+ return zip(xs,ys,zs)
+
+ def tunit_cube(self,vals=None,M=None):
+ if M is None:
+ M = self.M
+ xyzs = self.unit_cube(vals)
+ tcube = proj3d.proj_points(xyzs,M)
+ return tcube
+
+ def tunit_edges(self, vals=None,M=None):
+ tc = self.tunit_cube(vals,M)
+ edges = [(tc[0],tc[1]),
+ (tc[1],tc[2]),
+ (tc[2],tc[3]),
+ (tc[3],tc[0]),
+
+ (tc[0],tc[4]),
+ (tc[1],tc[5]),
+ (tc[2],tc[6]),
+ (tc[3],tc[7]),
+
+ (tc[4],tc[5]),
+ (tc[5],tc[6]),
+ (tc[6],tc[7]),
+ (tc[7],tc[4])]
+ return edges
+
+ def draw(self, renderer):
+ # draw the background patch
+ self.axesPatch.draw(renderer)
+ self._frameon = False
+
+ # add the projection matrix to the renderer
+ self.M = self.get_proj()
+ renderer.M = self.M
+ renderer.vvec = self.vvec
+ renderer.eye = self.eye
+ renderer.get_axis_position = self.get_axis_position
+
+ self.w_xaxis.draw(renderer)
+ self.w_yaxis.draw(renderer)
+ self.w_zaxis.draw(renderer)
+ Axes.draw(self, renderer)
+
+ def get_axis_position(self):
+ vals = self.get_w_lims()
+ tc = self.tunit_cube(vals,self.M)
+ xhigh = tc[1][2]>tc[2][2]
+ yhigh = tc[3][2]>tc[2][2]
+ zhigh = tc[0][2]>tc[2][2]
+ return xhigh,yhigh,zhigh
+
+ def update_datalim(self, xys):
+ pass
+
+ def update_datalim_numerix(self, x, y):
+ pass
+
+ def auto_scale_xyz(self, X,Y,Z=None,had_data=None):
+ x,y,z = map(np.asarray, (X,Y,Z))
+ try:
+ x,y = x.flatten(),y.flatten()
+ if Z is not None:
+ z = z.flatten()
+ except AttributeError:
+ raise
+
+ # This updates the bounding boxes as to keep a record as
+ # to what the minimum sized rectangular volume holds the
+ # data.
+ self.xy_dataLim.update_from_data_xy(np.array([x, y]).T, not had_data)
+ if z is not None:
+ self.zz_dataLim.update_from_data_xy(np.array([z, z]).T, not had_data)
+
+ # Let autoscale_view figure out how to use this data.
+ self.autoscale_view()
+
+ def autoscale_view(self, scalex=True, scaley=True, scalez=True):
+ # This method looks at the rectanglular volume (see above)
+ # of data and decides how to scale the view portal to fit it.
+
+ self.set_top_view()
+ if not self._ready: return
+
+ if not self.get_autoscale_on(): return
+ if scalex:
+ self.set_w_xlim(self.xy_dataLim.intervalx)
+ if scaley:
+ self.set_w_ylim(self.xy_dataLim.intervaly)
+ if scalez:
+ self.set_w_zlim(self.zz_dataLim.intervalx)
+
+ def get_w_lims(self):
+ '''Get 3d world limits.'''
+ minpy,maxx = self.get_w_xlim()
+ miny,maxy = self.get_w_ylim()
+ minz,maxz = self.get_w_zlim()
+ return minpy,maxx,miny,maxy,minz,maxz
+
+ def _determine_lims(self, xmin=None, xmax=None, *args, **kwargs):
+ if xmax is None and cbook.iterable(xmin):
+ xmin, xmax = xmin
+ return (xmin, xmax)
+
+ def set_w_zlim(self, *args, **kwargs):
+ '''Set 3d z limits.'''
+ lims = self._determine_lims(*args, **kwargs)
+ self.zz_viewLim.intervalx = lims
+ return lims
+
+ def set_w_xlim(self, *args, **kwargs):
+ '''Set 3d x limits.'''
+ lims = self._determine_lims(*args, **kwargs)
+ self.xy_viewLim.intervalx = lims
+ return lims
+
+ def set_w_ylim(self, *args, **kwargs):
+ '''Set 3d y limits.'''
+ lims = self._determine_lims(*args, **kwargs)
+ self.xy_viewLim.intervaly = lims
+ return lims
+
+ def get_w_zlim(self):
+ return self.zz_viewLim.intervalx
+
+ def get_w_xlim(self):
+ return self.xy_viewLim.intervalx
+
+ def get_w_ylim(self):
+ return self.xy_viewLim.intervaly
+
+ def pany(self, numsteps):
+ print 'numsteps', numsteps
+
+ def panpy(self, numsteps):
+ print 'numsteps', numsteps
+
+ def view_init(self, elev, azim):
+ self.dist = 10
+ self.elev = elev
+ self.azim = azim
+
+ def get_proj(self):
+ """Create the projection matrix from the current viewing
+ position.
+
+ elev stores the elevation angle in the z plane
+ azim stores the azimuth angle in the x,y plane
+
+ dist is the distance of the eye viewing point from the object
+ point.
+
+ """
+ relev,razim = np.pi * self.elev/180, np.pi * self.azim/180
+
+ xmin,xmax = self.get_w_xlim()
+ ymin,ymax = self.get_w_ylim()
+ zmin,zmax = self.get_w_zlim()
+
+ # transform to uniform world coordinates 0-1.0,0-1.0,0-1.0
+ worldM = proj3d.world_transformation(xmin,xmax,
+ ymin,ymax,
+ zmin,zmax)
+
+ # look into the middle of the new coordinates
+ R = np.array([0.5,0.5,0.5])
+ #
+ xp = R[0] + np.cos(razim)*np.cos(relev)*self.dist
+ yp = R[1] + np.sin(razim)*np.cos(relev)*self.dist
+ zp = R[2] + np.sin(relev)*self.dist
+ E = np.array((xp, yp, zp))
+ #
+ self.eye = E
+ self.vvec = R - E
+ self.vvec = self.vvec / proj3d.mod(self.vvec)
+
+ if abs(relev) > np.pi/2:
+ # upside down
+ V = np.array((0,0,-1))
+ else:
+ V = np.array((0,0,1))
+ zfront,zback = -self.dist,self.dist
+
+ viewM = proj3d.view_transformation(E,R,V)
+ perspM = proj3d.persp_transformation(zfront,zback)
+ M0 = np.dot(viewM,worldM)
+ M = np.dot(perspM,M0)
+ return M
+
+ def mouse_init(self):
+ self.button_pressed = None
+ canv = self.figure.canvas
+ if canv != None:
+ c1 = canv.mpl_connect('motion_notify_event', self.on_move)
+ c2 = canv.mpl_connect('button_press_event', self.button_press)
+ c3 = canv.mpl_connect('button_release_event', self.button_release)
+ self.cids = [c1, c2, c3]
+
+ def cla(self):
+ # Disconnect the various events we set.
+ for cid in self.cids:
+ self.figure.canvas.mpl_disconnect(cid)
+ self.cids = []
+ Axes.cla(self)
+
+ def button_press(self, event):
+ self.button_pressed = event.button
+ self.sx,self.sy = event.xdata,event.ydata
+
+ def button_release(self, event):
+ self.button_pressed = None
+
+ def format_xdata(self, x):
+ """
+ Return x string formatted. This function will use the attribute
+ self.fmt_xdata if it is callable, else will fall back on the xaxis
+ major formatter
+ """
+ try: return self.fmt_xdata(x)
+ except TypeError:
+ fmt = self.w_xaxis.get_major_formatter()
+ return sensible_format_data(fmt,x)
+
+ def format_ydata(self, y):
+ """
+ Return y string formatted. This function will use the attribute
+ self.fmt_ydata if it is callable, else will fall back on the yaxis
+ major formatter
+ """
+ try: return self.fmt_ydata(y)
+ except TypeError:
+ fmt = self.w_yaxis.get_major_formatter()
+ return sensible_format_data(fmt,y)
+
+ def format_zdata(self, z):
+ """
+ Return y string formatted. This function will use the attribute
+ self.fmt_ydata if it is callable, else will fall back on the yaxis
+ major formatter
+ """
+ try: return self.fmt_zdata(z)
+ except (AttributeError,TypeError):
+ fmt = self.w_zaxis.get_major_formatter()
+ return sensible_format_data(fmt,z)
+
+ def format_coord(self, xd, yd):
+ """Given the 2D view coordinates attempt to guess a 3D coordinate
+
+ Looks for the nearest edge to the point and then assumes that the point is
+ at the same z location as the nearest point on the edge.
+ """
+
+ if self.M is None:
+ return ''
+
+ if self.button_pressed == 1:
+ return 'azimuth=%d deg, elevation=%d deg ' % (self.azim, self.elev)
+ # ignore xd and yd and display angles instead
+
+ p = (xd,yd)
+ edges = self.tunit_edges()
+ #lines = [proj3d.line2d(p0,p1) for (p0,p1) in edges]
+ ldists = [(proj3d.line2d_seg_dist(p0,p1,p),i) for i,(p0,p1) in enumerate(edges)]
+ ldists.sort()
+ # nearest edge
+ edgei = ldists[0][1]
+ #
+ p0,p1 = edges[edgei]
+
+ # scale the z value to match
+ x0,y0,z0 = p0
+ x1,y1,z1 = p1
+ d0 = np.hypot(x0-xd,y0-yd)
+ d1 = np.hypot(x1-xd,y1-yd)
+ dt = d0+d1
+ z = d1/dt * z0 + d0/dt * z1
+ #print 'mid', edgei, d0, d1, z0, z1, z
+
+ x,y,z = proj3d.inv_transform(xd,yd,z,self.M)
+
+ xs = self.format_xdata(x)
+ ys = self.format_ydata(y)
+ zs = self.format_ydata(z)
+ return 'x=%s, y=%s, z=%s'%(xs,ys,zs)
+
+ def on_move(self, event):
+ """Mouse moving
+
+ button-1 rotates
+ button-3 zooms
+ """
+ if not self.button_pressed:
+ return
+
+ if self.M is None:
+ return
+ # this shouldn't be called before the graph has been drawn for the first time!
+ x, y = event.xdata, event.ydata
+
+ # In case the mouse is out of bounds.
+ if x == None:
+
+ return
+ dx,dy = x-self.sx,y-self.sy
+ x0,x1 = self.get_xlim()
+ y0,y1 = self.get_ylim()
+ w = (x1-x0)
+ h = (y1-y0)
+ self.sx,self.sy = x,y
+
+ if self.button_pressed == 1:
+ # rotate viewing point
+ # get the x and y pixel coords
+ if dx == 0 and dy == 0: return
+ #
+ self.elev = axis3d.norm_angle(self.elev - (dy/h)*180)
+ self.azim = axis3d.norm_angle(self.azim - (dx/w)*180)
+ self.get_proj()
+ self.figure.canvas.draw()
+ elif self.button_pressed == 2:
+ # pan view
+ # project xv,yv,zv -> xw,yw,zw
+ # pan
+ #
+ pass
+ elif self.button_pressed == 3:
+ # zoom view
+ # hmmm..this needs some help from clipping....
+ minpy,maxx,miny,maxy,minz,maxz = self.get_w_lims()
+ df = 1-((h - dy)/h)
+ dx = (maxx-minpy)*df
+ dy = (maxy-miny)*df
+ dz = (maxz-minz)*df
+ self.set_w_xlim(minpy-dx,maxx+dx)
+ self.set_w_ylim(miny-dy,maxy+dy)
+ self.set_w_zlim(minz-dz,maxz+dz)
+ self.get_proj()
+ self.figure.canvas.draw()
+
+ def set_xlabel(self, xlabel, fontdict=None, **kwargs):
+ #par = cbook.popd(kwargs, 'par',None)
+ #label.set_par(par)
+ #
+ label = self.w_xaxis.get_label()
+ label.set_text(xlabel)
+ if fontdict is not None: label.update(fontdict)
+ label.update(kwargs)
+ return label
+
+ def set_ylabel(self, ylabel, fontdict=None, **kwargs):
+ label = self.w_yaxis.get_label()
+ label.set_text(ylabel)
+ if fontdict is not None: label.update(fontdict)
+ label.update(kwargs)
+ return label
+
+ def set_zlabel(self, zlabel, fontdict=None, **kwargs):
+ label = self.w_zaxis.get_label()
+ label.set_text(zlabel)
+ if fontdict is not None: label.update(fontdict)
+ label.update(kwargs)
+ return label
+
+ def plot(self, *args, **kwargs):
+ had_data = self.has_data()
+
+ zval = kwargs.pop( 'z', 0)
+ zdir = kwargs.pop('dir', 'z')
+ lines = Axes.plot(self, *args, **kwargs)
+ for line in lines:
+ art3d.line_2d_to_3d(line, z=zval, dir=zdir)
+
+ xs = lines[0].get_xdata()
+ ys = lines[0].get_ydata()
+ zs = [zval for x in xs]
+ xs,ys,zs = art3d.juggle_axes(xs,ys,zs,zdir)
+ self.auto_scale_xyz(xs,ys,zs, had_data)
+ return lines
+
+ def plot3D(self, xs, ys, zs, *args, **kwargs):
+ had_data = self.has_data()
+ lines = Axes.plot(self, xs,ys, *args, **kwargs)
+ if len(lines)==1:
+ line = lines[0]
+ art3d.line_2d_to_3d(line, zs)
+ self.auto_scale_xyz(xs,ys,zs, had_data)
+ return lines
+
+ plot3d=plot3D
+
+ def plot_surface(self, X, Y, Z, *args, **kwargs):
+ had_data = self.has_data()
+
+ rows, cols = Z.shape
+ tX,tY,tZ = np.transpose(X), np.transpose(Y), np.transpose(Z)
+ rstride = kwargs.pop('rstride', 10)
+ cstride = kwargs.pop('cstride', 10)
+ #
+ polys = []
+ boxes = []
+ for rs in np.arange(0,rows-1,rstride):
+ for cs in np.arange(0,cols-1,cstride):
+ ps = []
+ corners = []
+ for a,ta in [(X,tX),(Y,tY),(Z,tZ)]:
+ ztop = a[rs][cs:min(cols,cs+cstride+1)]
+ zleft = ta[min(cols-1,cs+cstride)][rs:min(rows,rs+rstride+1)]
+ zbase = a[min(rows-1,rs+rstride)][cs:min(cols,cs+cstride+1):]
+ zbase = zbase[::-1]
+ zright = ta[cs][rs:min(rows,rs+rstride+1):]
+ zright = zright[::-1]
+ corners.append([ztop[0],ztop[-1],zbase[0],zbase[-1]])
+ z = np.concatenate((ztop,zleft,zbase,zright))
+ ps.append(z)
+ boxes.append(map(np.array,zip(*corners)))
+ polys.append(zip(*ps))
+ #
+ lines = []
+ shade = []
+ for box in boxes:
+ n = proj3d.cross(box[0]-box[1],
+ box[0]-box[2])
+ n = n/proj3d.mod(n)*5
+ shade.append(np.dot(n,[-1,-1,0.5]))
+ lines.append((box[0],n+box[0]))
+ #
+ color = np.array([0,0,1,1])
+ norm = Normalize(min(shade),max(shade))
+ colors = [color * (0.5+norm(v)*0.5) for v in shade]
+ for c in colors: c[3] = 1
+ polyc = art3d.Poly3DCollection(polys, facecolors=colors, *args, **kwargs)
+ polyc._zsort = 1
+ self.add_collection(polyc)
+ #
+ self.auto_scale_xyz(X,Y,Z, had_data)
+ return polyc
+
+ def plot_wireframe(self, X, Y, Z, *args, **kwargs):
+ rstride = kwargs.pop("rstride", 1)
+ cstride = kwargs.pop("cstride", 1)
+
+ had_data = self.has_data()
+ rows,cols = Z.shape
+
+ tX,tY,tZ = np.transpose(X), np.transpose(Y), np.transpose(Z)
+
+ rii = [i for i in range(0,rows,rstride)]+[rows-1]
+ cii = [i for i in range(0,cols,cstride)]+[cols-1]
+ xlines = [X[i] for i in rii]
+ ylines = [Y[i] for i in rii]
+ zlines = [Z[i] for i in rii]
+ #
+ txlines = [tX[i] for i in cii]
+ tylines = [tY[i] for i in cii]
+ tzlines = [tZ[i] for i in cii]
+ #
+ lines = [zip(xl,yl,zl) for xl,yl,zl in zip(xlines,ylines,zlines)]
+ lines += [zip(xl,yl,zl) for xl,yl,zl in zip(txlines,tylines,tzlines)]
+ linec = self.add_lines(lines, *args, **kwargs)
+
+ self.auto_scale_xyz(X,Y,Z, had_data)
+ return linec
+
+ def contour3D(self, X, Y, Z, *args, **kwargs):
+ had_data = self.has_data()
+ cset = self.contour(X, Y, Z, *args, **kwargs)
+ for z, linec in zip(cset.levels, cset.collections):
+ zl = []
+ art3d.line_collection_2d_to_3d(linec, z)
+ self.auto_scale_xyz(X,Y,Z, had_data)
+ return cset
+
+ def clabel(self, *args, **kwargs):
+# r = Axes.clabel(self, *args, **kwargs)
+ return None
+
+ def contourf3D(self, X, Y, Z, *args, **kwargs):
+ had_data = self.has_data()
+
+ cset = self.contourf(X, Y, Z, *args, **kwargs)
+ levels = cset.levels
+ colls = cset.collections
+
+ for z1,z2,linec in zip(levels,levels[1:],colls):
+ zs = [z1] * (len(linec.get_paths()[0])/2)
+ zs += [z2] * (len(linec.get_paths()[0])/2)
+ art3d.poly_collection_2d_to_3d(linec, zs)
+ self.auto_scale_xyz(X,Y,Z, had_data)
+ return cset
+
+ def scatter3D(self, xs, ys, zs, *args, **kwargs):
+ had_data = self.has_data()
+ patches = Axes.scatter(self,xs,ys,*args,**kwargs)
+ patches = art3d.patch_collection_2d_to_3d(patches, zs)
+ self.auto_scale_xyz(xs,ys,zs, had_data)
+ return patches
+ scatter3d = scatter3D
+
+ def add_lines(self, lines, *args, **kwargs):
+ linec = art3d.Line3DCollection(lines, *args, **kwargs)
+ self.add_collection(linec)
+ return linec
+ """
+ def text3D(self, x,y,z,s, *args, **kwargs):
+ text = Axes.text(self,x,y,s,*args,**kwargs)
+ art3d.wrap_text(text,z)
+ return text
+ """
+ def ahvline(self, x,y):
+ pass
+
+ def ahvxplane(self, x):
+ pass
+
+ def ahvyplane(self, y):
+ pass
+
+class Scaler:
+ def __init__(self, points):
+ self.inpoints = points
+ self.drawpoints = None
+
+ def update(self, lims):
+ for x,y,z in self.points:
+ pass
+
+class Axes3D:
+ """
+ Wrapper for Axes3DI
+
+ Provides set_xlim, set_ylim etc.
+
+ 2D functions can be caught here and mapped
+ to their 3D approximations.
+
+ This should probably be the case for plot etc...
+ """
+ def __init__(self, fig, *args, **kwargs):
+ self.__dict__['wrapped'] = Axes3DI(fig, *args, **kwargs)
+
+ def set_xlim(self, *args, **kwargs):
+ self.wrapped.set_w_xlim(*args, **kwargs)
+
+ def set_ylim(self, *args, **kwargs):
+ self.wrapped.set_w_ylim(*args, **kwargs)
+
+ def set_zlim(self, *args, **kwargs):
+ self.wrapped.set_w_zlim(*args, **kwargs)
+
+ def __getattr__(self, k):
+ return getattr(self.wrapped,k)
+
+ def __setattr__(self, k,v):
+ return setattr(self.wrapped,k,v)
+
+ def add_collection(self, polys, zs=None, dir='z'):
+ art3d.poly_collection_2d_to_3d(polys, zs=zs, dir=dir)
+ self.add_3DCollection(polys)
+
+ def add_3DCollection(self, patches):
+ self.wrapped.add_collection(patches)
+
+ def text(self, x,y, text, *args,**kwargs):
+ self.wrapped.text3D(x,y,0,text,*args,**kwargs)
+
+ def scatter(self, xs,ys,zs=None,dir='z',*args,**kwargs):
+ patches = self.wrapped.scatter(xs,ys,*args,**kwargs)
+ if zs is None:
+ zs = [0]*len(xs)
+ art3d.patch_collection_2d_to_3d(patches, zs=zs, dir=dir)
+ return patches
+
+ def bar(self, left, height, z=0, dir='z', *args, **kwargs):
+ had_data = self.has_data()
+ patches = self.wrapped.bar(left, height, *args, **kwargs)
+ verts = []
+ for p in patches:
+ vs = p.get_verts()
+ zs = [z]*len(vs)
+ verts += vs.tolist()
+ art3d.patch_2d_to_3d(p, zs[0], dir)
+ if 'alpha' in kwargs:
+ p.set_alpha(kwargs['alpha'])
+ xs,ys = zip(*verts)
+ zs = [z]*len(xs)
+ xs,ys,zs=art3d.juggle_axes(xs,ys,zs,dir)
+ self.wrapped.auto_scale_xyz(xs,ys,zs, had_data)
+ return patches
+
+def test_scatter():
+ f = plt.figure()
+ ax = Axes3D(f)
+
+ n = 100
+ for c,zl,zh in [('r',-50,-25),('b',-30,-5)]:
+ xs,ys,zs = zip(*
+ [(random.randrange(23,32),
+ random.randrange(100),
+ random.randrange(zl,zh)
+ ) for i in range(n)])
+ ax.scatter3D(xs,ys,zs, c=c)
+
+ ax.set_xlabel('------------ X Label --------------------')
+ ax.set_ylabel('------------ Y Label --------------------')
+ ax.set_zlabel('------------ Z Label --------------------')
+
+def get_test_data(delta=0.05):
+ from matplotlib.mlab import bivariate_normal
+ x = y = np.arange(-3.0, 3.0, delta)
+ X, Y = np.meshgrid(x,y)
+
+ Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
+ Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
+ Z = Z2-Z1
+
+ X = X * 10
+ Y = Y * 10
+ Z = Z * 500
+ return X,Y,Z
+
+def test_wire():
+ f = plt.figure()
+ ax = Axes3D(f)
+
+ X,Y,Z = get_test_data(0.05)
+ ax.plot_wireframe(X,Y,Z, rstride=10,cstride=10)
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+
+def test_surface():
+ f = plt.figure()
+ ax = Axes3D(f)
+
+ X,Y,Z = get_test_data(0.05)
+ ax.plot_surface(X,Y,Z, rstride=10,cstride=10)
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+
+def test_contour():
+ f = plt.figure()
+ ax = Axes3D(f)
+
+ X,Y,Z = get_test_data(0.05)
+ cset = ax.contour3D(X,Y,Z)
+ ax.clabel(cset, fontsize=9, inline=1)
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+
+def test_contourf():
+ f = plt.figure()
+ ax = Axes3D(f)
+
+ X,Y,Z = get_test_data(0.05)
+ cset = ax.contourf3D(X,Y,Z)
+ ax.clabel(cset, fontsize=9, inline=1)
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+
+def test_plot():
+ f = plt.figure()
+ ax = Axes3D(f)
+
+ xs = np.arange(0,4*np.pi+0.1,0.1)
+ ys = np.sin(xs)
+ ax.plot(xs,ys, label='zl')
+ ax.plot(xs,ys+max(xs),label='zh')
+ ax.plot(xs,ys,dir='x', label='xl')
+ ax.plot(xs,ys,dir='x', z=max(xs),label='xh')
+ ax.plot(xs,ys,dir='y', label='yl')
+ ax.plot(xs,ys,dir='y', z=max(xs), label='yh')
+ ax.set_xlabel('X')
+ ax.set_ylabel('Y')
+ ax.set_zlabel('Z')
+ ax.legend()
+
+def test_polys():
+ f = plt.figure()
+ ax = Axes3D(f)
+
+ cc = lambda arg: colorConverter.to_rgba(arg, alpha=0.6)
+
+ xs = np.arange(0,10,0.4)
+ verts = []
+ zs = [0.0,1.0,2.0,3.0]
+ for z in zs:
+ ys = [random.random() for x in xs]
+ ys[0],ys[-1] = 0,0
+ verts.append(zip(xs,ys))
+
+ from matplotlib.collections import PolyCollection
+ poly = PolyCollection(verts, facecolors = [cc('r'),cc('g'),cc('b'),
+ cc('y')])
+ poly.set_alpha(0.7)
+ ax.add_collection(poly,zs=zs,dir='y')
+
+ ax.set_xlim(0,10)
+ ax.set_ylim(-1,4)
+ ax.set_zlim(0,1)
+
+def test_scatter2D():
+ f = plt.figure()
+ ax = Axes3D(f)
+
+ xs = [random.random() for i in range(20)]
+ ys = [random.random() for x in xs]
+ ax.scatter(xs, ys)
+ ax.scatter(xs, ys, dir='y', c='r')
+ ax.scatter(xs, ys, dir='x', c='g')
+
+def test_bar2D():
+ f = plt.figure()
+ ax = Axes3D(f)
+
+ for c,z in zip(['r','g','b', 'y'],[30,20,10,0]):
+ xs = np.arange(20)
+ ys = [random.random() for x in xs]
+ ax.bar(xs, ys, z=z, dir='y', color=c, alpha=0.8)
+
+if __name__ == "__main__":
+ import pylab
+ import axis3d; reload(axis3d);
+ import art3d; reload(art3d);
+ import proj3d; reload(proj3d);
+
+ test_scatter()
+ test_wire()
+ test_surface()
+ test_contour()
+ test_contourf()
+ test_plot()
+ test_polys()
+ test_scatter2D()
+# test_bar2D()
+
+ pylab.show()
Added: trunk/matplotlib/lib/mpl_toolkits/mplot3d/axis3d.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/mplot3d/axis3d.py (rev 0)
+++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/axis3d.py 2009-04-14 14:29:31 UTC (rev 7041)
@@ -0,0 +1,310 @@
+#!/usr/bin/python
+# axis3d.py, original mplot3d version by John Porter
+# Created: 23 Sep 2005
+# Parts rewritten by Reinier Heeres <re...@he...>
+
+import math
+import copy
+
+from matplotlib import lines
+from matplotlib import axis
+from matplotlib import patches
+from matplotlib import text
+
+import art3d
+import proj3d
+
+import numpy as np
+
+def norm_angle(a):
+ """Return angle between -180 and +180"""
+ a = (a+360)%360
+ if a > 180: a = a-360
+ return a
+
+def norm_text_angle(a):
+ """Return angle between -90 and +90"""
+ a = (a + 180) % 180
+ if a > 90:
+ a = a - 180
+ return a
+
+def get_flip_min_max(coord, index, mins, maxs):
+ if coord[index] == mins[index]:
+ return maxs[index]
+ else:
+ return mins[index]
+
+def move_from_center(coord, centers, deltas, axmask=(True, True, True)):
+ '''Return a coordinate that is moved by "deltas" away from the center.'''
+ ret = copy.copy(coord)
+ for i in range(3):
+ if not axmask[i]:
+ continue
+ if coord[i] < centers[i]:
+ coord[i] -= deltas[i]
+ else:
+ coord[i] += deltas[i]
+ return coord
+
+def tick_update_position(tick, tickxs, tickys, labelpos):
+ '''Update tick line and label position and style.'''
+
+ for (label, on) in ((tick.label1, tick.label1On), \
+ (tick.label2, tick.label2On)):
+ if on:
+ label.set_position(labelpos)
+
+ tick.tick1On, tick.tick2On = True, False
+ tick.tick1line.set_linestyle('-')
+ tick.tick1line.set_marker('')
+ tick.tick1line.set_data(tickxs, tickys)
+
+class Axis(axis.XAxis):
+
+ # These points from the unit cube make up the x, y and z-planes
+ _PLANES = (
+ (0, 3, 7, 4), (1, 2, 6, 5), # yz planes
+ (0, 1, 5, 4), (3, 2, 6, 7), # xz planes
+ (0, 1, 2, 3), (4, 5, 6, 7), # xy planes
+ )
+
+ # Some properties for the axes
+ _AXINFO = {
+ 'x': {'i': 0, 'tickdir': 1,
+ 'color': (0.95, 0.95, 0.95, 0.5)},
+ 'y': {'i': 1, 'tickdir': 0,
+ 'color': (0.90, 0.90, 0.90, 0.5)},
+ 'z': {'i': 2, 'tickdir': 0,
+ 'color': (0.925, 0.925, 0.925, 0.5)},
+ }
+
+ def __init__(self, adir, v_intervalx, d_intervalx, axes, *args, **kwargs):
+ # adir identifies which axes this is
+ self.adir = adir
+ # data and viewing intervals for this direction
+ self.d_interval = d_intervalx
+ self.v_interval = v_intervalx
+ #
+ axis.XAxis.__init__(self, axes, *args, **kwargs)
+ self.line = lines.Line2D(xdata=(0,0),ydata=(0,0),
+ linewidth=0.75,
+ color=(0,0,0,0),
+ antialiased=True,
+ )
+
+ # Store dummy data in Polygon object
+ self.has_pane = True
+ self.pane = patches.Polygon(np.array([[0,0],[0,1],[1,0],[0,0]]),
+ alpha=0.8,
+ facecolor=(1,1,1,0),
+ edgecolor=(1,1,1,0))
+
+ self.axes._set_artist_props(self.line)
+ self.axes._set_artist_props(self.pane)
+ self.gridlines = art3d.Line3DCollection([], )
+ self.axes._set_artist_props(self.gridlines)
+ self.axes._set_artist_props(self.label)
+ self.label._transform = self.axes.transData
+ self.set_rotate_label(kwargs.get('rotate_label', None))
+
+ def get_tick_positions(self):
+ majorTicks = self.get_major_ticks()
+ majorLocs = self.major.locator()
+ self.major.formatter.set_locs(majorLocs)
+ majorLabels = [self.major.formatter(val, i) for i, val in enumerate(majorLocs)]
+ return majorLabels,majorLocs
+
+ def get_major_ticks(self):
+ ticks = axis.XAxis.get_major_ticks(self)
+ for t in ticks:
+ def update_coords(renderer,self=t.label1):
+ return text_update_coords(self, renderer)
+ # Text overrides setattr so need this to force new method
+ t.tick1line.set_transform(self.axes.transData)
+ t.tick2line.set_transform(self.axes.transData)
+ t.gridline.set_transform(self.axes.transData)
+ t.label1.set_transform(self.axes.transData)
+ t.label2.set_transform(self.axes.transData)
+ return ticks
+
+ def set_pane(self, xys, color):
+ if self.has_pane:
+ xys = np.asarray(xys)
+ xys = xys[:,:2]
+ self.pane.xy = xys
+ self.pane.set_edgecolor(color)
+ self.pane.set_facecolor(color)
+ self.pane.set_alpha(color[-1])
+
+ def set_rotate_label(self, val):
+ '''
+ Whether to rotate the axis label: True, False or None.
+ If set to None the label will be rotated if longer than 4 chars.
+ '''
+ self._rotate_label = val
+
+ def get_rotate_label(self, text):
+ if self._rotate_label is not None:
+ return self._rotate_label
+ else:
+ return len(text) > 4
+
+ def draw(self, renderer):
+ self.label._transform = self.axes.transData
+ renderer.open_group('axis3d')
+
+ # code from XAxis
+ majorTicks = self.get_major_ticks()
+ majorLocs = self.major.locator()
+
+ # filter locations here so that no extra grid lines are drawn
+ interval = self.get_view_interval()
+ majorLocs = [loc for loc in majorLocs if interval[0] < loc < interval[1]]
+ self.major.formatter.set_locs(majorLocs)
+ majorLabels = [self.major.formatter(val, i)
+ for i, val in enumerate(majorLocs)]
+
+ # Determine bounds
+ minx,maxx,miny,maxy,minz,maxz = self.axes.get_w_lims()
+ mins = (minx, miny, minz)
+ maxs = (maxx, maxy, maxz)
+ centers = [(maxv + minv) / 2 for minv, maxv in zip(mins, maxs)]
+ deltas = [(maxv - minv) / 12 for minv, maxv in zip(mins, maxs)]
+ mins = [minv - delta / 4 for minv, delta in zip(mins, deltas)]
+ maxs = [maxv + delta / 4 for maxv, delta in zip(maxs, deltas)]
+
+ # Determine which planes should be visible by the avg z value
+ vals = mins[0], maxs[0], mins[1], maxs[1], mins[2], maxs[2]
+ tc = self.axes.tunit_cube(vals,renderer.M)
+ avgz = [tc[p1][2] + tc[p2][2] + tc[p3][2] + tc[p4][2] for \
+ p1, p2, p3, p4 in self._PLANES]
+ highs = [avgz[2*i] < avgz[2*i+1] for i in range(3)]
+
+ # Draw plane
+ info = self._AXINFO[self.adir]
+ index = info['i']
+ if not highs[index]:
+ plane = self._PLANES[2 * index]
+ else:
+ plane = self._PLANES[2 * index + 1]
+ xys = [tc[p] for p in plane]
+ self.set_pane(xys, info['color'])
+ self.pane.draw(renderer)
+
+ # Determine grid lines
+ minmax = []
+ for i, val in enumerate(highs):
+ if val:
+ minmax.append(maxs[i])
+ else:
+ minmax.append(mins[i])
+
+ # Draw main axis line
+ juggled = art3d.juggle_axes(0, 2, 1, self.adir)
+ edgep1 = copy.copy(minmax)
+ edgep1[juggled[0]] = get_flip_min_max(edgep1, juggled[0], mins, maxs)
+ edgep2 = copy.copy(edgep1)
+ edgep2[juggled[1]] = get_flip_min_max(edgep2, juggled[1], mins, maxs)
+ pep = proj3d.proj_trans_points([edgep1, edgep2], renderer.M)
+ self.line.set_data((pep[0][0], pep[0][1]), (pep[1][0], pep[1][1]))
+ self.line.draw(renderer)
+
+ # Grid points where the planes meet
+ xyz0 = []
+ for val in majorLocs:
+ coord = copy.copy(minmax)
+ coord[index] = val
+ xyz0.append(coord)
+
+ # Draw labels
+ dy = pep[1][1] - pep[1][0]
+ dx = pep[0][1] - pep[0][0]
+ lxyz = [(v1 + v2) / 2 for v1, v2 in zip(edgep1, edgep2)]
+ labeldeltas = [1.3 * x for x in deltas]
+ lxyz = move_from_center(lxyz, centers, labeldeltas)
+ tlx,tly,tlz = proj3d.proj_transform(lxyz[0], lxyz[1], lxyz[2], renderer.M)
+ self.label.set_position((tlx, tly))
+ if self.get_rotate_label(self.label.get_text()):
+ angle = norm_text_angle(math.degrees(math.atan2(dy, dx)))
+ self.label.set_rotation(angle)
+ self.label.set_va('center')
+ self.label.draw(renderer)
+
+ # Grid points at end of one plane
+ xyz1 = copy.deepcopy(xyz0)
+ newindex = (index + 1) % 3
+ newval = get_flip_min_max(xyz1[0], newindex, mins, maxs)
+ for i in range(len(majorLocs)):
+ xyz1[i][newindex] = newval
+
+ # Grid points at end of the other plane
+ xyz2 = copy.deepcopy(xyz0)
+ newindex = (index + 2) % 3
+ newval = get_flip_min_max(xyz2[0], newindex, mins, maxs)
+ for i in range(len(majorLocs)):
+ xyz2[i][newindex] = newval
+
+ lines = zip(xyz1, xyz0, xyz2)
+ self.gridlines.set_segments(lines)
+ self.gridlines.set_color([(0.9,0.9,0.9,1)] * len(lines))
+ self.gridlines.draw(renderer)
+
+ # Draw ticks
+ tickdir = info['tickdir']
+ tickdelta = deltas[tickdir]
+ if highs[tickdir]:
+ ticksign = 1
+ else:
+ ticksign = -1
+
+ for tick, loc, label in zip(majorTicks, majorLocs, majorLabels):
+ if tick is None:
+ continue
+
+ # Get tick line positions
+ pos = copy.copy(edgep1)
+ pos[index] = loc
+ pos[tickdir] = edgep1[tickdir] + 0.1 * ticksign * tickdelta
+ x1, y1, z1 = proj3d.proj_transform(pos[0], pos[1], pos[2], renderer.M)
+ pos[tickdir] = edgep1[tickdir] - 0.2 * ticksign * tickdelta
+ x2, y2, z2 = proj3d.proj_transform(pos[0], pos[1], pos[2], renderer.M)
+
+ # Get position of label
+ labeldeltas = [0.6 * x for x in deltas]
+ axmask = [True, True, True]
+ axmask[index] = False
+ pos[tickdir] = edgep1[tickdir]
+ pos = move_from_center(pos, centers, labeldeltas, axmask)
+ lx, ly, lz = proj3d.proj_transform(pos[0], pos[1], pos[2], renderer.M)
+
+ tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly))
+ tick.set_label1(label)
+ tick.set_label2(label)
+ tick.draw(renderer)
+
+ renderer.close_group('axis3d')
+
+ def get_view_interval(self):
+ """return the Interval instance for this axis view limits"""
+ return self.v_interval
+
+# Each type of axis should be looking in a different place for its
+# current data limits so we do this with classes. I think there is
+# a lot more that I can and should move down into these classes also.
+
+class XAxis(Axis):
+ def get_data_interval(self):
+ 'return the Interval instance for this axis data limits'
+ return self.axes.xy_dataLim.intervalx
+
+
+class YAxis(Axis):
+ def get_data_interval(self):
+ 'return the Interval instance for this axis data limits'
+ return self.axes.xy_dataLim.intervaly
+
+class ZAxis(Axis):
+ def get_data_interval(self):
+ 'return the Interval instance for this axis data limits'
+ return self.axes.zz_dataLim.intervalx
Added: trunk/matplotlib/lib/mpl_toolkits/mplot3d/proj3d.py
===================================================================
--- trunk/matplotlib/lib/mpl_toolkits/mplot3d/proj3d.py (rev 0)
+++ trunk/matplotlib/lib/mpl_toolkits/mplot3d/proj3d.py 2009-04-14 14:29:31 UTC (rev 7041)
@@ -0,0 +1,286 @@
+#!/usr/bin/python
+# 3dproj.py
+#
+"""
+Various transforms used for by the 3D code
+"""
+
+from matplotlib.collections import LineCollection
+from matplotlib.patches import Circle
+import numpy as np
+import numpy.linalg as linalg
+
+def _hide_cross(a,b):
+ """
+ Cross product of two vectors
+ A x B = <Ay*Bz - Az*By, Az*Bx - Ax*Bz, Ax*By - Ay*Bx>
+ a x b = [a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1]
+ """
+ return np.array([a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1] - a[1]*b[0]])
+cross = _hide_cross
+
+def line2d(p0,p1):
+ """
+ Return 2D equation of line in the form ax+by+c = 0
+ """
+ # x + x1 = 0
+ x0,y0 = p0[:2]
+ x1,y1 = p1[:2]
+ #
+ if x0==x1:
+ a = -1
+ b = 0
+ c = x1
+ elif y0==y1:
+ a = 0
+ b = 1
+ c = -y1
+ else:
+ a = (y0-y1)
+ b = (x0-x1)
+ c = (x0*y1 - x1*y0)
+ return a,b,c
+
+def line2d_dist(l, p):
+ """
+ Distance from line to point
+ line is a tuple of coefficients a,b,c
+ """
+ a,b,c = l
+ x0,y0 = p
+ return abs((a*x0 + b*y0 + c)/np.sqrt(a**2+b**2))
+
+
+def line2d_seg_dist(p1,p2, p0):
+ """distance(s) from line defined by p1 - p2 to point(s) p0
+
+ p0[0] = x(s)
+ p0[1] = y(s)
+
+ intersection point p = p1 + u*(p2-p1)
+ and intersection point lies within segement if u is between 0 and 1
+ """
+
+ x21 = p2[0] - p1[0]
+ y21 = p2[1] - p1[1]
+ x01 = np.asarray(p0[0]) - p1[0]
+ y01 = np.asarray(p0[1]) - p1[1]
+
+ u = (x01*x21 + y01*y21)/float(abs(x21**2 + y21**2))
+ u = np.clip(u, 0, 1)
+ d = np.sqrt((x01 - u*x21)**2 + (y01 - u*y21)**2)
+
+ return d
+
+
+def test_lines_dists():
+ ax = pylab.gca()
+
+ xs,ys = (0,30),(20,150)
+ pylab.plot(xs,ys)
+ points = zip(xs,ys)
+ p0,p1 = points
+
+ xs,ys = (0,0,20,30),(100,150,30,200)
+ pylab.scatter(xs,ys)
+ #
+ dist = line2d_seg_dist(p0,p1,(xs[0],ys[0]))
+ dist = line2d_seg_dist(p0,p1,np.array((xs,ys)))
+ for x,y,d in zip(xs,ys,dist):
+ c = Circle((x,y),d,fill=0)
+ ax.add_patch(c)
+ #
+ pylab.xlim(-200,...
[truncated message content] |
|
From: <jd...@us...> - 2009-04-13 03:02:51
|
Revision: 7040
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7040&view=rev
Author: jdh2358
Date: 2009-04-13 03:02:41 +0000 (Mon, 13 Apr 2009)
Log Message:
-----------
Merged revisions 7037-7039 via svnmerge from
https://matplotlib.svn.sourceforge.net/svnroot/matplotlib/branches/v0_98_5_maint
........
r7037 | cmoad | 2009-04-10 21:24:37 -0500 (Fri, 10 Apr 2009) | 1 line
added python 2.6 / tcltk 8.5 check
........
r7038 | cmoad | 2009-04-12 21:22:30 -0500 (Sun, 12 Apr 2009) | 1 line
minor rev bump
........
r7039 | jdh2358 | 2009-04-12 21:56:11 -0500 (Sun, 12 Apr 2009) | 1 line
fixed csv2rec bug referenced in sf bug 2745173
........
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/doc/matplotlibrc
trunk/matplotlib/lib/matplotlib/mlab.py
trunk/matplotlib/setupext.py
Property Changed:
----------------
trunk/matplotlib/
Property changes on: trunk/matplotlib
___________________________________________________________________
Modified: svnmerge-integrated
- /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-7035
+ /branches/v0_91_maint:1-6428 /branches/v0_98_5_maint:1-7039
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-04-13 02:56:11 UTC (rev 7039)
+++ trunk/matplotlib/CHANGELOG 2009-04-13 03:02:41 UTC (rev 7040)
@@ -1,3 +1,6 @@
+======================================================================
+2008-04-12 Release 0.98.5.3 at r7038
+
2009-04-06 The pdf backend now escapes newlines and linefeeds in strings.
Fixes sf bug #2708559; thanks to Tiago Pereira for the report.
Modified: trunk/matplotlib/doc/matplotlibrc
===================================================================
--- trunk/matplotlib/doc/matplotlibrc 2009-04-13 02:56:11 UTC (rev 7039)
+++ trunk/matplotlib/doc/matplotlibrc 2009-04-13 03:02:41 UTC (rev 7040)
@@ -27,7 +27,6 @@
# the default backend; one of GTK GTKAgg GTKCairo FltkAgg QtAgg TkAgg
# WX WXAgg Agg Cairo GD GDK Paint PS PDF SVG Template
backend : Agg
-numerix : numpy # numpy, Numeric or numarray
#maskedarray : False # True to use external maskedarray module
# instead of numpy.ma; this is a temporary
# setting for testing maskedarray.
Modified: trunk/matplotlib/lib/matplotlib/mlab.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/mlab.py 2009-04-13 02:56:11 UTC (rev 7039)
+++ trunk/matplotlib/lib/matplotlib/mlab.py 2009-04-13 03:02:41 UTC (rev 7040)
@@ -2552,8 +2552,14 @@
fh.seek(0)
reader = csv.reader(fh, delimiter=delimiter)
process_skiprows(reader)
+
if needheader:
- skipheader = reader.next()
+ while 1:
+ # skip past any comments and consume one line of column header
+ row = reader.next()
+ if len(row) and row[0].startswith(comments):
+ continue
+ break
# iterate over the remaining rows and convert the data to date
# objects, ints, or floats as approriate
Modified: trunk/matplotlib/setupext.py
===================================================================
--- trunk/matplotlib/setupext.py 2009-04-13 02:56:11 UTC (rev 7039)
+++ trunk/matplotlib/setupext.py 2009-04-13 03:02:41 UTC (rev 7040)
@@ -952,11 +952,14 @@
message = None
if sys.platform == 'win32':
major, minor1, minor2, s, tmp = sys.version_info
- if major == 2 and minor1 in [3, 4, 5]:
- module.include_dirs.extend(['win32_static/include/tcl8.4'])
+ if major == 2 and minor1 == 6:
+ module.include_dirs.extend(['win32_static/include/tcl85'])
+ module.libraries.extend(['tk85', 'tcl85'])
+ elif major == 2 and minor1 in [3, 4, 5]:
+ module.include_dirs.extend(['win32_static/include/tcl84'])
module.libraries.extend(['tk84', 'tcl84'])
elif major == 2 and minor1 == 2:
- module.include_dirs.extend(['win32_static/include/tcl8.3'])
+ module.include_dirs.extend(['win32_static/include/tcl83'])
module.libraries.extend(['tk83', 'tcl83'])
else:
raise RuntimeError('No tk/win32 support for this python version yet')
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <jd...@us...> - 2009-04-13 02:56:27
|
Revision: 7039
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7039&view=rev
Author: jdh2358
Date: 2009-04-13 02:56:11 +0000 (Mon, 13 Apr 2009)
Log Message:
-----------
fixed csv2rec bug referenced in sf bug 2745173
Modified Paths:
--------------
branches/v0_98_5_maint/doc/matplotlibrc
branches/v0_98_5_maint/lib/matplotlib/mlab.py
Modified: branches/v0_98_5_maint/doc/matplotlibrc
===================================================================
--- branches/v0_98_5_maint/doc/matplotlibrc 2009-04-13 02:22:30 UTC (rev 7038)
+++ branches/v0_98_5_maint/doc/matplotlibrc 2009-04-13 02:56:11 UTC (rev 7039)
@@ -27,7 +27,6 @@
# the default backend; one of GTK GTKAgg GTKCairo FltkAgg QtAgg TkAgg
# WX WXAgg Agg Cairo GD GDK Paint PS PDF SVG Template
backend : Agg
-numerix : numpy # numpy, Numeric or numarray
#maskedarray : False # True to use external maskedarray module
# instead of numpy.ma; this is a temporary
# setting for testing maskedarray.
Modified: branches/v0_98_5_maint/lib/matplotlib/mlab.py
===================================================================
--- branches/v0_98_5_maint/lib/matplotlib/mlab.py 2009-04-13 02:22:30 UTC (rev 7038)
+++ branches/v0_98_5_maint/lib/matplotlib/mlab.py 2009-04-13 02:56:11 UTC (rev 7039)
@@ -2532,8 +2532,14 @@
fh.seek(0)
reader = csv.reader(fh, delimiter=delimiter)
process_skiprows(reader)
+
if needheader:
- skipheader = reader.next()
+ while 1:
+ # skip past any comments and consume one line of column header
+ row = reader.next()
+ if len(row) and row[0].startswith(comments):
+ continue
+ break
# iterate over the remaining rows and convert the data to date
# objects, ints, or floats as approriate
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <cm...@us...> - 2009-04-13 02:22:47
|
Revision: 7038
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7038&view=rev
Author: cmoad
Date: 2009-04-13 02:22:30 +0000 (Mon, 13 Apr 2009)
Log Message:
-----------
minor rev bump
Modified Paths:
--------------
branches/v0_98_5_maint/CHANGELOG
Modified: branches/v0_98_5_maint/CHANGELOG
===================================================================
--- branches/v0_98_5_maint/CHANGELOG 2009-04-11 02:24:37 UTC (rev 7037)
+++ branches/v0_98_5_maint/CHANGELOG 2009-04-13 02:22:30 UTC (rev 7038)
@@ -1,3 +1,6 @@
+======================================================================
+2008-04-12 Release 0.98.5.3 at r7038
+
2009-04-06 The pdf backend now escapes newlines and linefeeds in strings.
Fixes sf bug #2708559; thanks to Tiago Pereira for the report.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|