Skip to content

Commit 5e10932

Browse files
committed
mpl_tollkits.axes_grid1 support auto-adjusted axes area
svn path=/trunk/matplotlib/; revision=8852
1 parent 582b723 commit 5e10932

File tree

4 files changed

+153
-1
lines changed

4 files changed

+153
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from mpl_toolkits.axes_grid1 import make_axes_locatable
2+
from mpl_toolkits.axes_grid1.axes_divider import make_axes_area_auto_adjustable
3+
4+
5+
6+
if __name__ == "__main__":
7+
8+
import matplotlib.pyplot as plt
9+
def ex1():
10+
plt.figure(1)
11+
ax = plt.axes([0,0,1,1])
12+
# ax = plt.subplot(111)
13+
14+
ax.set_yticks([0.5])
15+
ax.set_yticklabels(["very long label"])
16+
17+
make_axes_area_auto_adjustable(ax)
18+
19+
20+
def ex2():
21+
22+
plt.figure(2)
23+
ax1 = plt.axes([0,0,1,0.5])
24+
ax2 = plt.axes([0,0.5,1,0.5])
25+
26+
ax1.set_yticks([0.5])
27+
ax1.set_yticklabels(["very long label"])
28+
ax1.set_ylabel("Y label")
29+
30+
ax2.set_title("Title")
31+
32+
make_axes_area_auto_adjustable(ax1, pad=0.1, use_axes=[ax1, ax2])
33+
make_axes_area_auto_adjustable(ax2, pad=0.1, use_axes=[ax1, ax2])
34+
35+
def ex3():
36+
37+
fig = plt.figure(3)
38+
ax1 = plt.axes([0,0,1,1])
39+
divider = make_axes_locatable(ax1)
40+
41+
ax2 = divider.new_horizontal("100%", pad=0.3, sharey=ax1)
42+
ax2.tick_params(labelleft="off")
43+
fig.add_axes(ax2)
44+
45+
divider.add_auto_adjustable_area(use_axes=[ax1], pad=0.1,
46+
adjust_dirs=["left"])
47+
divider.add_auto_adjustable_area(use_axes=[ax2], pad=0.1,
48+
adjust_dirs=["right"])
49+
divider.add_auto_adjustable_area(use_axes=[ax1, ax2], pad=0.1,
50+
adjust_dirs=["top", "bottom"])
51+
52+
ax1.set_yticks([0.5])
53+
ax1.set_yticklabels(["very long label"])
54+
55+
ax2.set_title("Title")
56+
ax2.set_xlabel("X - Label")
57+
58+
ex1()
59+
ex2()
60+
ex3()
61+
62+
plt.show()

lib/matplotlib/axes.py

+2
Original file line numberDiff line numberDiff line change
@@ -8293,10 +8293,12 @@ def get_tightbbox(self, renderer):
82938293
if self.xaxis.get_visible():
82948294
artists.append(self.xaxis.label)
82958295
bbx1, bbx2 = self.xaxis.get_ticklabel_extents(renderer)
8296+
self.xaxis._update_label_position([bbx1], [bbx2])
82968297
bb.extend([bbx1, bbx2])
82978298
if self.yaxis.get_visible():
82988299
artists.append(self.yaxis.label)
82998300
bby1, bby2 = self.yaxis.get_ticklabel_extents(renderer)
8301+
self.yaxis._update_label_position([bby1], [bby2])
83008302
bb.extend([bby1, bby2])
83018303

83028304

lib/mpl_toolkits/axes_grid1/axes_divider.py

+37
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,32 @@ def new_locator(self, nx, ny, nx1=None, ny1=None):
260260
"""
261261
return AxesLocator(self, nx, ny, nx1, ny1)
262262

263+
def append_size(self, position, size):
264+
265+
if position == "left":
266+
self._horizontal.insert(0, size)
267+
self._xrefindex += 1
268+
elif position == "right":
269+
self._horizontal.append(size)
270+
elif position == "bottom":
271+
self._vertical.insert(0, size)
272+
self._yrefindex += 1
273+
elif position == "top":
274+
self._vertical.append(size)
275+
else:
276+
raise ValueError("the position must be one of left, right, bottom, or top")
277+
278+
279+
def add_auto_adjustable_area(self,
280+
use_axes, pad=0.1,
281+
adjust_dirs=["left", "right", "bottom", "top"],
282+
):
283+
from axes_size import Padded, SizeFromFunc, GetExtentHelper
284+
for d in adjust_dirs:
285+
helper = GetExtentHelper(use_axes, d)
286+
size = SizeFromFunc(helper)
287+
padded_size = Padded(size, pad) # pad in inch
288+
self.append_size(d, padded_size)
263289

264290

265291
class AxesLocator(object):
@@ -836,6 +862,17 @@ def make_axes_locatable(axes):
836862

837863
return divider
838864

865+
def make_axes_area_auto_adjustable(ax,
866+
use_axes=None, pad=0.1,
867+
adjust_dirs=["left", "right", "bottom", "top"]):
868+
869+
divider = make_axes_locatable(ax)
870+
871+
if use_axes is None:
872+
use_axes = ax
873+
874+
divider.add_auto_adjustable_area(use_axes=use_axes, pad=pad,
875+
adjust_dirs=adjust_dirs)
839876

840877
#from matplotlib.axes import Axes
841878
from mpl_axes import Axes

lib/mpl_toolkits/axes_grid1/axes_size.py

+52-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class (or others) to determine the size of each axes. The unit
1212
"""
1313

1414
import matplotlib.cbook as cbook
15-
15+
from matplotlib.axes import Axes
1616

1717
class _Base(object):
1818
"Base class"
@@ -238,3 +238,54 @@ def from_any(size, fraction_ref=None):
238238
raise ValueError("Unknown format")
239239

240240

241+
class SizeFromFunc(_Base):
242+
def __init__(self, func):
243+
self._func = func
244+
245+
def get_size(self, renderer):
246+
rel_size = 0.
247+
248+
bb = self._func(renderer)
249+
dpi = renderer.points_to_pixels(72.)
250+
abs_size = bb/dpi
251+
252+
return rel_size, abs_size
253+
254+
class GetExtentHelper(object):
255+
def _get_left(tight_bbox, axes_bbox):
256+
return axes_bbox.xmin - tight_bbox.xmin
257+
258+
def _get_right(tight_bbox, axes_bbox):
259+
return tight_bbox.xmax - axes_bbox.xmax
260+
261+
def _get_bottom(tight_bbox, axes_bbox):
262+
return axes_bbox.ymin - tight_bbox.ymin
263+
264+
def _get_top(tight_bbox, axes_bbox):
265+
return tight_bbox.ymax - axes_bbox.ymax
266+
267+
_get_func_map = dict(left=_get_left,
268+
right=_get_right,
269+
bottom=_get_bottom,
270+
top=_get_top)
271+
272+
del _get_left, _get_right, _get_bottom, _get_top
273+
274+
def __init__(self, ax, direction):
275+
if isinstance(ax, Axes):
276+
self._ax_list = [ax]
277+
else:
278+
self._ax_list = ax
279+
280+
try:
281+
self._get_func = self._get_func_map[direction]
282+
except KeyError:
283+
print "direction must be one of left, right, bottom, top"
284+
raise
285+
286+
def __call__(self, renderer):
287+
vl = [self._get_func(ax.get_tightbbox(renderer),
288+
ax.bbox) for ax in self._ax_list]
289+
return max(vl)
290+
291+

0 commit comments

Comments
 (0)