-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathutils_mpl.py
More file actions
328 lines (264 loc) · 7.81 KB
/
utils_mpl.py
File metadata and controls
328 lines (264 loc) · 7.81 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
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
"""
Collection of small utils to create figures with Matplotlib:
- Setup nice default parameters (fonts, sizes, etc.).
- Create and save figures as PDFs and PNGs.
- Set the grid, axis limit, and axis ticks.
- Clone the exact size of an axes in a new figure.
"""
__author__ = "Thomas Guillod"
__copyright__ = "Thomas Guillod - Dartmouth College"
__license__ = "Mozilla Public License Version 2.0"
import matplotlib.pyplot as plt
import matplotlib.ticker as tkr
import numpy as np
def set_global():
"""
Set the global Matplotlib options.
"""
# set the font family
plt.rcParams["font.size"] = 9.0
plt.rcParams["font.family"] = "Times New Roman"
plt.rcParams["mathtext.default"] = "regular"
# set the axes parameters
plt.rcParams["axes.linewidth"] = 1.0
plt.rcParams["axes.labelsize"] = 9.0
plt.rcParams["axes.titlesize"] = 10.0
plt.rcParams["axes.labelpad"] = 8.0
plt.rcParams["axes.labelweight"] = "bold"
plt.rcParams["axes.titleweight"] = "bold"
# set the legend parameters
plt.rcParams["legend.edgecolor"] = "k"
plt.rcParams["legend.fancybox"] = False
plt.rcParams["legend.framealpha"] = 1.0
plt.rcParams["legend.fontsize"] = 9.0
def set_grid(fig, ax, major=True, minor=True):
"""
Set the grid for a plot.
Parameters
----------
fig : figure
Matplotlib figure.
ax : axes
Matplotlib axes to be considered.
major : bool
Use the major grid.
minor : bool
Use the minor grid.
"""
if major:
ax.grid(which="major", linewidth=0.75)
if minor:
ax.grid(which="minor", linewidth=0.25)
fig.tight_layout()
def get_bnd(bnd=None, margin=0.0, log=False):
"""
Get bound limits with specified tolerances.
Parameters
----------
bnd : array
Array with the min and max values.
margin : float
Relative margin for the bounds.
log : float
Determine if the axis is linear or logarithmic.
Returns
-------
v_min : float
Lower limit for the axis.
v_max : float
Upper limit for the axis.
"""
# scale the axis
if log:
bnd = np.log10(bnd)
# find the bounds
add_offset = (np.max(bnd) - np.min(bnd)) * margin
v_min = np.min(bnd) - add_offset
v_max = np.max(bnd) + add_offset
# unscale the axis
if log:
v_min = np.power(10.0, v_min)
v_max = np.power(10.0, v_max)
return v_min, v_max
def set_cbar(obj, bnd=None, margin=0.0, log=False):
"""
Create a colorbar and set the bounds (with tolerances).
Parameters
----------
obj : map
Mappable where the color limit is set.
bnd : array
Array with the min and max values.
margin : float
Relative margin for the bounds.
log : float
Determine if the axis is linear or logarithmic.
"""
if bnd is not None:
(v_min, v_max) = get_bnd(bnd=bnd, margin=margin, log=log)
obj.set_clim(v_min, v_max)
def set_x_axis(ax, bnd=None, margin=0.0, log=False):
"""
Set the bounds for the x-axis (with tolerances).
Parameters
----------
ax : axes
Matplotlib axes to be considered.
bnd : array
Array with the min and max values.
margin : float
Relative margin for the bounds.
log : float
Determine if the axis is linear or logarithmic.
"""
if bnd is not None:
(v_min, v_max) = get_bnd(bnd=bnd, margin=margin, log=log)
ax.set_xlim(v_min, v_max)
def set_y_axis(ax, bnd=None, margin=0.0, log=False):
"""
Set the bounds for the y-axis (with tolerances).
Parameters
----------
ax : axes
Matplotlib axes to be considered.
bnd : array
Array with the min and max values.
margin : float
Relative margin for the bounds.
log : float
Determine if the axis is linear or logarithmic.
"""
if bnd is not None:
(v_min, v_max) = get_bnd(bnd=bnd, margin=margin, log=log)
ax.set_ylim(v_min, v_max)
def set_format(axis, ticks=None, fmt=None):
"""
Set the tick locations and formats with the following options:
- A Matplotlib formatter can be provided.
- If a string is provided, StrMethodFormatter is used.
- If a calltable is provided, FuncFormatter is used.
Parameters
----------
axis : axis
Axis to be considered.
ticks : array
Position of the ticks.
fmt : format
Tick formatter (Formatter object, string, or function handle).
"""
# set the ticks
if ticks is not None:
axis.set_ticks(ticks)
# set the format
if fmt is not None:
if isinstance(fmt, tkr.Formatter):
axis.set_major_formatter(fmt)
elif isinstance(fmt, str):
axis.set_major_formatter(tkr.StrMethodFormatter(fmt))
elif callable(fmt):
axis.set_major_formatter(tkr.FuncFormatter(fmt))
else:
raise ValueError("invalid tick format")
def get_fig(size=(6, 4), dpi=100):
"""
Create a figure for a vector plot.
Parameters
----------
size : tuple
Size of the figure in inches.
dpi : int
Resolution of the figure in dpi.
Returns
-------
fig : figure
Matplotlib figure.
ax : axes
Matplotlib axes.
"""
# create the figure
fig = plt.figure(figsize=size, dpi=dpi)
ax = fig.gca()
return fig, ax
def get_fig_clone(fig, ax):
"""
Find the exact dimension (width and height) of the axes.
Find the bounds of the axes (x-axis, y-axis, and colorbar).
This function is used to split large plots in two parts:
- A vector plot with the axes, labels, ticks, legend, etc.
- A raster plot with the large payload (contour, scatter, etc.)
Parameters
----------
fig : figure
Matplotlib figure to be considered.
ax : axes
Matplotlib axes to be considered.
Returns
-------
size : tuple
Size of the figure in inches.
xlim : tuple
Limit for the x-axis.
ylim : tuple
Limit for the y-axis.
"""
# get the size of the axis of the vector figure
bbox = ax.get_window_extent()
width = bbox.width / fig.dpi
height = bbox.height / fig.dpi
size = (width, height)
xlim = ax.get_xlim()
ylim = ax.get_ylim()
return size, xlim, ylim
def set_fig_clone(fig, ax, size, xlim, ylim):
"""
Resize a figure to the specified dimensions.
The axes are occupied the complete figure.
The axes and grid are hidden.
This function is used to split large plots in two parts:
- A vector plot with the axes, labels, ticks, legend, etc.
- A raster plot with the large payload (e.g., contour, scatter, or image).
Parameters
----------
fig : figure
Matplotlib figure to be considered.
ax : axes
Matplotlib axes to be considered.
size : tuple
Size of the figure in inches.
xlim : tuple
Limit for the x-axis.
ylim : tuple
Limit for the y-axis.
"""
# set the axes
fig.set_size_inches(size)
ax.set_position([0.0, 0.0, 1.0, 1.0])
# set the extent
plt.xlim(xlim)
plt.ylim(ylim)
plt.grid(False)
plt.axis(False)
def save_svg(fig, filename):
"""
Save a plot to an SVG file.
Parameters
----------
fig : figure
Matplotlib figure to be saved.
filename : str
Path of the filename to be saved.
"""
fig.savefig(filename, transparent=True)
def save_png(fig, filename, dpi=100):
"""
Save a plot to a PNG file.
Parameters
----------
fig : figure
Matplotlib figure to be saved.
filename : str
Path of the filename to be saved.
dpi : int
Resolution (in dpi) for the export.
"""
fig.savefig(filename, dpi=dpi, transparent=True)