0
# Figure and Subplot Creation
1
2
Core functionality for creating figures and subplot arrangements with proplot's enhanced grid layouts, automatic sizing, and publication-ready formatting options. Proplot provides significant enhancements over matplotlib's default figure creation with automatic layout management, physical unit support, and advanced subplot sharing capabilities.
3
4
## Capabilities
5
6
### Figure Creation
7
8
Create empty proplot figures with enhanced layout management and automatic sizing capabilities.
9
10
```python { .api }
11
def figure(**kwargs):
12
"""
13
Create an empty proplot figure with enhanced features.
14
15
Parameters:
16
- figwidth (unit-spec): Figure width in physical units
17
- figheight (unit-spec): Figure height in physical units
18
- figsize (tuple): Figure size as (width, height) tuple
19
- journal (str): Preset journal size ('aaas1', 'agu1', 'nat1', etc.)
20
- tight (bool): Enable tight layout algorithm
21
- **kwargs: Additional parameters passed to Figure constructor
22
23
Returns:
24
proplot.figure.Figure: Enhanced figure instance
25
"""
26
```
27
28
### Subplot Grid Creation
29
30
Create figures with subplot grids using proplot's enhanced grid system with automatic spacing and alignment.
31
32
```python { .api }
33
def subplots(*args, **kwargs):
34
"""
35
Create figure with subplots using proplot's enhanced grid system.
36
37
Parameters:
38
- nrows (int): Number of subplot rows (default: 1)
39
- ncols (int): Number of subplot columns (default: 1)
40
- array (array-like): 2D array specifying subplot arrangement
41
- proj (str): Projection name for all subplots
42
- sharex (int/bool/str): X-axis sharing level (0-4)
43
- sharey (int/bool/str): Y-axis sharing level (0-4)
44
- share (int/bool/str): Both axes sharing level
45
- spanx (bool): Span x-axis labels across subplots
46
- spany (bool): Span y-axis labels across subplots
47
- refwidth (unit-spec): Reference subplot width
48
- refheight (unit-spec): Reference subplot height
49
- refaspect (float/tuple): Reference aspect ratio
50
- wspace (unit-spec): Width spacing between subplots
51
- hspace (unit-spec): Height spacing between subplots
52
- **kwargs: Figure creation and formatting parameters
53
54
Returns:
55
tuple: (fig, axs) where fig is Figure and axs is SubplotGrid
56
"""
57
```
58
59
### Enhanced Figure Class
60
61
Main proplot figure class with automatic layout management, panel integration, and advanced formatting capabilities.
62
63
```python { .api }
64
class Figure:
65
"""
66
Main proplot figure class with automatic layout management.
67
68
Enhanced replacement for matplotlib.figure.Figure with:
69
- Physical unit support for all dimensions
70
- Automatic layout algorithm with tight spacing
71
- Integrated panel (colorbar/legend) management
72
- Academic journal size presets
73
- Advanced subplot sharing and spanning
74
"""
75
76
def __init__(self, *,
77
# Figure sizing
78
figwidth=None, figheight=None, figsize=None,
79
width=None, height=None,
80
journal=None,
81
82
# Reference subplot sizing
83
refnum=None, ref=None,
84
refwidth=None, refheight=None,
85
axwidth=None, axheight=None,
86
refaspect=None, aspect=None,
87
88
# Axis sharing
89
sharex=None, sharey=None, share=None,
90
91
# Label spanning and alignment
92
spanx=None, spany=None, span=None,
93
alignx=None, aligny=None, align=None,
94
95
# Spacing and layout
96
left=None, right=None, top=None, bottom=None,
97
wspace=None, hspace=None, space=None,
98
99
# Tight layout
100
tight=None,
101
outerpad=None, innerpad=None, panelpad=None,
102
wpad=None, hpad=None, pad=None,
103
104
**kwargs):
105
"""
106
Create enhanced figure with automatic layout management.
107
108
Parameters:
109
- figwidth/width (unit-spec): Figure width
110
- figheight/height (unit-spec): Figure height
111
- figsize (tuple): Figure size (width, height)
112
- journal (str): Academic journal preset size
113
- refwidth/axwidth (unit-spec): Reference subplot width
114
- refheight/axheight (unit-spec): Reference subplot height
115
- refaspect/aspect (float/tuple): Reference aspect ratio
116
- sharex/sharey/share (int/bool/str): Axis sharing levels
117
- spanx/spany/span (bool): Label spanning flags
118
- alignx/aligny/align (bool): Label alignment flags
119
- left/right/top/bottom (unit-spec): Figure margins
120
- wspace/hspace/space (unit-spec): Subplot spacing
121
- tight (bool): Enable tight layout algorithm
122
- outerpad/innerpad/panelpad (unit-spec): Layout padding
123
- **kwargs: Additional matplotlib Figure parameters
124
"""
125
126
def add_subplot(self, *args, number=None, **kwargs):
127
"""
128
Add single subplot to figure.
129
130
Parameters:
131
- *args: Subplot specification (nrows, ncols, index) or GridSpec
132
- number (int): Explicit subplot number
133
- proj (str): Projection name for this subplot
134
- **kwargs: Axes creation and formatting parameters
135
136
Returns:
137
proplot.axes.Axes: Created axes instance
138
"""
139
140
def add_subplots(self, array=None, *, ncols=1, nrows=1,
141
order='C', proj=None, projection=None,
142
proj_kw=None, projection_kw=None,
143
basemap=None, **kwargs):
144
"""
145
Add multiple subplots to figure.
146
147
Parameters:
148
- array (array-like): 2D array specifying subplot layout
149
- ncols (int): Number of columns (if array not specified)
150
- nrows (int): Number of rows (if array not specified)
151
- order (str): Subplot numbering order ('C' or 'F')
152
- proj/projection (str/sequence): Projection(s) for subplots
153
- proj_kw/projection_kw (dict): Projection keyword arguments
154
- basemap (bool): Use basemap projections
155
- **kwargs: Gridspec and subplot parameters
156
157
Returns:
158
proplot.gridspec.SubplotGrid: Container of created axes
159
"""
160
161
def colorbar(self, mappable, values=None, loc=None, location=None,
162
row=None, col=None, rows=None, cols=None, span=None,
163
space=None, pad=None, width=None, **kwargs):
164
"""
165
Add colorbar panel to figure.
166
167
Parameters:
168
- mappable: Mappable object for colorbar (ScalarMappable, Axes, etc.)
169
- values (array-like): Explicit colorbar tick values
170
- loc/location (str): Panel location ('left', 'right', 'top', 'bottom')
171
- row/col/rows/cols (int/sequence): Subplot selection for panel
172
- span (bool/int/sequence): Span panel across multiple subplots
173
- space (unit-spec): Space between panel and subplots
174
- pad (unit-spec): Padding around panel content
175
- width (unit-spec): Panel width
176
- **kwargs: Colorbar formatting parameters
177
178
Returns:
179
matplotlib.colorbar.Colorbar: Created colorbar instance
180
"""
181
182
def legend(self, handles=None, labels=None, loc=None, location=None,
183
row=None, col=None, rows=None, cols=None, span=None,
184
space=None, pad=None, width=None, **kwargs):
185
"""
186
Add legend panel to figure.
187
188
Parameters:
189
- handles (sequence): Legend handles (artists)
190
- labels (sequence): Legend labels (strings)
191
- loc/location (str): Panel location ('left', 'right', 'top', 'bottom')
192
- row/col/rows/cols (int/sequence): Subplot selection for panel
193
- span (bool/int/sequence): Span panel across multiple subplots
194
- space (unit-spec): Space between panel and subplots
195
- pad (unit-spec): Padding around panel content
196
- width (unit-spec): Panel width
197
- **kwargs: Legend formatting parameters
198
199
Returns:
200
matplotlib.legend.Legend: Created legend instance
201
"""
202
203
def format(self, axs=None, *,
204
figtitle=None, suptitle=None, suptitle_kw=None,
205
llabels=None, leftlabels=None, leftlabels_kw=None,
206
rlabels=None, rightlabels=None, rightlabels_kw=None,
207
blabels=None, bottomlabels=None, bottomlabels_kw=None,
208
tlabels=None, toplabels=None, toplabels_kw=None,
209
rowlabels=None, collabels=None,
210
includepanels=None, mathtext_fallback=None, **kwargs):
211
"""
212
Format figure and subplot labels.
213
214
Parameters:
215
- axs (SubplotGrid): Specific axes to format (default: all)
216
- figtitle/suptitle (str): Figure title
217
- suptitle_kw (dict): Title formatting parameters
218
- leftlabels/llabels/rowlabels (sequence): Left side labels
219
- rightlabels/rlabels (sequence): Right side labels
220
- bottomlabels/blabels/collabels (sequence): Bottom labels
221
- toplabels/tlabels (sequence): Top labels
222
- *labels_kw (dict): Label-specific formatting parameters
223
- includepanels (bool): Include panels in formatting
224
- mathtext_fallback (bool): Enable mathtext fallback
225
- **kwargs: Additional formatting parameters passed to axes
226
"""
227
228
def save(self, filename, **kwargs):
229
"""
230
Save figure with enhanced path handling.
231
232
Parameters:
233
- filename (str): Output filename with user path expansion
234
- **kwargs: Additional parameters passed to matplotlib savefig
235
"""
236
237
@property
238
def gridspec(self):
239
"""proplot.gridspec.GridSpec: The figure's GridSpec instance."""
240
241
@property
242
def subplotgrid(self):
243
"""proplot.gridspec.SubplotGrid: All numbered subplots."""
244
```
245
246
### Grid Specification
247
248
Advanced grid specification class for precise subplot arrangement and spacing control.
249
250
```python { .api }
251
class GridSpec:
252
"""
253
Grid specification for advanced subplot arrangement.
254
255
Enhanced replacement for matplotlib.gridspec.GridSpec with:
256
- Physical unit support for all spacing parameters
257
- Advanced panel integration
258
- Automatic tight layout calculation
259
- Flexible ratio-based sizing
260
"""
261
262
def __init__(self, nrows=1, ncols=1, *,
263
# Margins
264
left=None, right=None, top=None, bottom=None,
265
266
# Spacing
267
wspace=None, hspace=None, space=None,
268
269
# Ratios
270
wratios=None, hratios=None,
271
width_ratios=None, height_ratios=None,
272
273
# Tight layout
274
wequal=None, hequal=None, equal=None,
275
outerpad=None, innerpad=None, panelpad=None,
276
wpad=None, hpad=None, pad=None,
277
278
**kwargs):
279
"""
280
Create grid specification for subplot layout.
281
282
Parameters:
283
- nrows (int): Number of grid rows
284
- ncols (int): Number of grid columns
285
- left/right/top/bottom (unit-spec): Fixed figure margins
286
- wspace/hspace/space (unit-spec/sequence): Inter-subplot spacing
287
- wratios/width_ratios (sequence): Relative subplot widths
288
- hratios/height_ratios (sequence): Relative subplot heights
289
- wequal/hequal/equal (bool): Equal spacing flags
290
- outerpad/innerpad/panelpad (unit-spec): Layout padding
291
- wpad/hpad/pad (unit-spec/sequence): Tight layout padding
292
- **kwargs: Additional matplotlib GridSpec parameters
293
"""
294
295
def update(self, **kwargs):
296
"""
297
Update grid parameters and reposition subplots.
298
299
Parameters:
300
- **kwargs: Any GridSpec constructor parameters
301
"""
302
303
def get_geometry(self):
304
"""
305
Get total grid geometry including panels.
306
307
Returns:
308
tuple: (total_rows, total_cols) including panel space
309
"""
310
311
def get_subplot_geometry(self):
312
"""
313
Get subplot-only grid geometry.
314
315
Returns:
316
tuple: (subplot_rows, subplot_cols) excluding panels
317
"""
318
319
def get_panel_geometry(self):
320
"""
321
Get panel-only grid geometry.
322
323
Returns:
324
tuple: (panel_rows, panel_cols) for panel space only
325
"""
326
327
@property
328
def figure(self):
329
"""proplot.figure.Figure: Associated figure instance."""
330
331
@property
332
def nrows(self):
333
"""int: Number of subplot rows."""
334
335
@property
336
def ncols(self):
337
"""int: Number of subplot columns."""
338
339
@property
340
def hratios(self):
341
"""list: Height ratios for rows."""
342
343
@property
344
def wratios(self):
345
"""list: Width ratios for columns."""
346
```
347
348
### Subplot Container
349
350
List-like container for managing collections of subplots with both 1D and 2D indexing capabilities.
351
352
```python { .api }
353
class SubplotGrid:
354
"""
355
Container for subplot grids with enhanced indexing and formatting.
356
357
List-like container that supports:
358
- 1D indexing: axs[0], axs[1:3], axs[-1]
359
- 2D indexing: axs[0,1], axs[:,0], axs[1,:]
360
- Collective formatting: axs.format(xlim=(0,10))
361
- Dynamic method generation for all axes operations
362
"""
363
364
def __init__(self, sequence=None, **kwargs):
365
"""
366
Create subplot grid container.
367
368
Parameters:
369
- sequence (iterable): Initial sequence of axes
370
- **kwargs: Additional container parameters
371
"""
372
373
def __getitem__(self, key):
374
"""
375
Get subplot(s) using 1D or 2D indexing.
376
377
Parameters:
378
- key (int/slice/tuple): Index specification
379
380
Returns:
381
Axes or SubplotGrid: Single axes or subset of axes
382
"""
383
384
def format(self, **kwargs):
385
"""
386
Format all axes in the grid.
387
388
Parameters:
389
- **kwargs: Formatting parameters passed to each axes
390
"""
391
392
def panel(self, *args, **kwargs):
393
"""
394
Create panels for all axes in grid.
395
396
Parameters:
397
- *args, **kwargs: Panel creation parameters
398
399
Returns:
400
SubplotGrid: Container of created panel axes
401
"""
402
403
@property
404
def figure(self):
405
"""proplot.figure.Figure: Associated figure instance."""
406
407
@property
408
def gridspec(self):
409
"""proplot.gridspec.GridSpec: Associated GridSpec instance."""
410
411
@property
412
def shape(self):
413
"""tuple: Grid shape as (nrows, ncols)."""
414
```
415
416
## Journal Size Presets
417
418
Predefined figure sizes for academic journals:
419
420
```python { .api }
421
JOURNAL_SIZES = {
422
# Science magazines
423
'aaas1': '5.5cm', # Single column Science
424
'aaas2': '12cm', # Double column Science
425
426
# American Geophysical Union
427
'agu1': ('95mm', '115mm'), # Single column
428
'agu2': ('190mm', '115mm'), # Double column
429
'agu3': ('95mm', '230mm'), # Single column, full page
430
'agu4': ('190mm', '230mm'), # Double column, full page
431
432
# American Meteorological Society
433
'ams1': 3.2, # Single column (inches)
434
'ams2': 5.5, # Small double column
435
'ams3': 6.5, # Large double column
436
'ams4': 7.48, # Full page width
437
438
# Nature Research
439
'nat1': 89, # Single column (mm)
440
'nat2': 183, # Double column (mm)
441
442
# PNAS
443
'pnas1': 8.7, # Single column (cm)
444
'pnas2': 11.4, # 1.3 column
445
'pnas3': 17.8, # Double column (cm)
446
447
# Additional formats available...
448
}
449
```
450
451
## Axis Sharing Levels
452
453
Comprehensive sharing system for coordinating axes across subplots:
454
455
```python { .api }
456
# Sharing level specifications:
457
SHARING_LEVELS = {
458
0: "No sharing",
459
False: "No sharing",
460
461
1: "Share labels only",
462
'labels': "Share labels only",
463
'labs': "Share labels only",
464
465
2: "Share labels and limits",
466
'limits': "Share labels and limits",
467
'lims': "Share labels and limits",
468
469
3: "Share labels, limits, and tick labels",
470
True: "Share labels, limits, and tick labels",
471
472
4: "Complete sharing across all subplots",
473
'all': "Complete sharing across all subplots"
474
}
475
```
476
477
## Usage Examples
478
479
### Basic Figure Creation
480
481
```python
482
import proplot as pplt
483
484
# Simple figure
485
fig = pplt.figure(figwidth=8, figheight=6)
486
487
# Figure with subplots
488
fig, axs = pplt.subplots(nrows=2, ncols=2, figwidth=10)
489
490
# Journal format
491
fig, axs = pplt.subplots(ncols=3, journal='nature2')
492
```
493
494
### Advanced Subplot Layouts
495
496
```python
497
# Custom arrangement with array
498
array = [[1, 1, 2], [3, 4, 4]]
499
fig, axs = pplt.subplots(array=array, figwidth=12)
500
501
# Physical unit spacing
502
fig, axs = pplt.subplots(
503
nrows=2, ncols=3,
504
wspace='1cm', hspace='15mm',
505
refwidth='2in', refaspect=1.2
506
)
507
508
# Advanced sharing and spanning
509
fig, axs = pplt.subplots(
510
nrows=2, ncols=3,
511
share='limits', # Share axis limits
512
span=True, # Span axis labels
513
align=True # Align axis labels
514
)
515
```
516
517
### Panel Integration
518
519
```python
520
# Figure-level colorbar
521
fig, axs = pplt.subplots(ncols=2)
522
m = axs[0].contourf(data)
523
fig.colorbar(m, loc='right', span=True)
524
525
# Multiple panels
526
fig, axs = pplt.subplots(nrows=2, ncols=2)
527
fig.colorbar(mappable1, loc='bottom', col=1)
528
fig.legend(handles, loc='right', span=True)
529
```
530
531
### Dynamic Formatting
532
533
```python
534
# Format entire figure
535
fig.format(
536
suptitle='Main Title',
537
leftlabels=['Treatment A', 'Treatment B'],
538
bottomlabels=['Day 1', 'Day 2', 'Day 3']
539
)
540
541
# Format all subplots
542
axs.format(
543
xlim=(0, 100),
544
ylim=(0, 50),
545
grid=True,
546
xlabel='Time (seconds)',
547
ylabel='Response'
548
)
549
```
550
551
This comprehensive figure and subplot system enables sophisticated layouts with minimal code while maintaining full matplotlib compatibility and providing powerful enhancements for scientific publication.