/
figure.py
164 lines (122 loc) · 4.59 KB
/
figure.py
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# -*- coding: utf-8 -*-
"""
This module implements the class that deals with graphics.
.. :copyright: (c) 2014 by Jelte Fennema.
:license: MIT, see License for more details.
"""
import posixpath
from .utils import fix_filename, make_temp_dir, NoEscape, escape_latex
from .base_classes import Float, UnsafeCommand
from .package import Package
import uuid
class Figure(Float):
"""A class that represents a Figure environment."""
def add_image(self, filename, *, width=NoEscape(r'0.8\textwidth'),
placement=NoEscape(r'\centering')):
"""Add an image to the figure.
Args
----
filename: str
Filename of the image.
width: str
The width of the image
placement: str
Placement of the figure, `None` is also accepted.
"""
if width is not None:
if self.escape:
width = escape_latex(width)
width = 'width=' + str(width)
if placement is not None:
self.append(placement)
self.append(StandAloneGraphic(image_options=width,
filename=fix_filename(filename)))
def _save_plot(self, *args, extension='pdf', **kwargs):
"""Save the plot.
Returns
-------
str
The basename with which the plot has been saved.
"""
import matplotlib.pyplot as plt
tmp_path = make_temp_dir()
filename = '{}.{}'.format(str(uuid.uuid4()), extension.strip('.'))
filepath = posixpath.join(tmp_path, filename)
plt.savefig(filepath, *args, **kwargs)
return filepath
def add_plot(self, *args, extension='pdf', **kwargs):
"""Add the current Matplotlib plot to the figure.
The plot that gets added is the one that would normally be shown when
using ``plt.show()``.
Args
----
args:
Arguments passed to plt.savefig for displaying the plot.
extension : str
extension of image file indicating figure file type
kwargs:
Keyword arguments passed to plt.savefig for displaying the plot. In
case these contain ``width`` or ``placement``, they will be used
for the same purpose as in the add_image command. Namely the width
and placement of the generated plot in the LaTeX document.
"""
add_image_kwargs = {}
for key in ('width', 'placement'):
if key in kwargs:
add_image_kwargs[key] = kwargs.pop(key)
filename = self._save_plot(*args, extension=extension, **kwargs)
self.add_image(filename, **add_image_kwargs)
class SubFigure(Figure):
"""A class that represents a subfigure from the subcaption package."""
packages = [Package('subcaption')]
#: By default a subfigure is not on its own paragraph since that looks
#: weird inside another figure.
separate_paragraph = False
_repr_attributes_mapping = {
'width': 'arguments',
}
def __init__(self, width=NoEscape(r'0.45\linewidth'), **kwargs):
"""
Args
----
width: str
Width of the subfigure itself. It needs a width because it is
inside another figure.
"""
super().__init__(arguments=width, **kwargs)
def add_image(self, filename, *, width=NoEscape(r'\linewidth'),
placement=None):
"""Add an image to the subfigure.
Args
----
filename: str
Filename of the image.
width: str
Width of the image in LaTeX terms.
placement: str
Placement of the figure, `None` is also accepted.
"""
super().add_image(filename, width=width, placement=placement)
class StandAloneGraphic(UnsafeCommand):
r"""A class representing a stand alone image."""
_latex_name = "includegraphics"
packages = [Package('graphicx')]
_repr_attributes_mapping = {
"filename": "arguments",
"image_options": "options"
}
def __init__(self, filename,
image_options=NoEscape(r'width=0.8\textwidth'),
extra_arguments=None):
r"""
Args
----
filename: str
The path to the image file
image_options: str or `list`
Specifies the options for the image (ie. height, width)
"""
arguments = [NoEscape(filename)]
super().__init__(command=self._latex_name, arguments=arguments,
options=image_options,
extra_arguments=extra_arguments)