forked from pelson/matplotlib
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtight_bbox.py
More file actions
135 lines (103 loc) · 3.97 KB
/
tight_bbox.py
File metadata and controls
135 lines (103 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"""
This module is to support *bbox_inches* option in savefig command.
"""
from __future__ import print_function
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 which 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)
adjust_bbox_handler = _adjust_bbox_handler_d.get(format)
if adjust_bbox_handler is not None:
adjust_bbox_handler(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
"""
if fig._cachedRenderer.__class__.__name__ == "RendererPgf":
tr = Affine2D().scale(fig.dpi)
f = 1.
else:
tr = Affine2D().scale(72)
f = 72. / fig.dpi
_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
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
_adjust_bbox_handler_d = {}
for format in ["png", "raw", "rgba", "jpg", "jpeg", "tiff"]:
_adjust_bbox_handler_d[format] = adjust_bbox_png
for format in ["pdf", "eps", "svg", "svgz"]:
_adjust_bbox_handler_d[format] = adjust_bbox_pdf