0
# Object-Oriented API
1
2
Direct manipulation of Figure and Axes objects provides maximum control and flexibility. This approach is recommended for complex layouts, programmatic plot generation, and when building reusable plotting functions.
3
4
## Core Concepts
5
6
The object-oriented API centers on two main classes:
7
- **Figure**: The top-level container for all plot elements
8
- **Axes**: Individual plotting areas within a figure
9
10
## Capabilities
11
12
### Figure Class
13
14
Top-level container managing the entire plot canvas.
15
16
```python { .api }
17
from matplotlib.figure import Figure
18
19
class Figure:
20
def __init__(self, figsize=None, dpi=None, facecolor=None,
21
edgecolor=None, linewidth=0.0, frameon=None,
22
subplotpars=None, tight_layout=None, constrained_layout=None,
23
layout=None, **kwargs):
24
"""Create a new figure."""
25
26
def add_subplot(self, nrows=1, ncols=1, index=1, **kwargs) -> Axes:
27
"""Add an Axes to the figure as part of a subplot arrangement."""
28
29
def add_axes(self, rect, projection=None, polar=False, **kwargs) -> Axes:
30
"""Add an Axes to the figure."""
31
32
def add_gridspec(self, nrows=1, ncols=1, **kwargs) -> GridSpec:
33
"""Return a GridSpec that has this figure as a parent."""
34
35
def add_subfigure(self, subplotspec, **kwargs) -> SubFigure:
36
"""Add a SubFigure to the figure as part of a subplot arrangement."""
37
38
def delaxes(self, ax) -> None:
39
"""Remove the Axes ax from the figure."""
40
41
def clear(self, keep_observers=False) -> None:
42
"""Clear the figure."""
43
44
def draw(self, renderer) -> None:
45
"""Draw the Artist (and its children) using the given renderer."""
46
47
def savefig(self, fname, *, transparent=None, **kwargs) -> None:
48
"""Save the current figure."""
49
50
def show(self, warn=True) -> None:
51
"""If using a GUI backend, display the figure window."""
52
53
def tight_layout(self, *, pad=1.08, h_pad=None, w_pad=None, rect=None) -> None:
54
"""Adjust the padding between and around subplots."""
55
56
def suptitle(self, t, **kwargs) -> Text:
57
"""Add a centered suptitle to the figure."""
58
59
def text(self, x, y, s, **kwargs) -> Text:
60
"""Add text to the figure."""
61
62
def get_axes(self) -> list:
63
"""Return a list of axes in the Figure."""
64
65
def get_size_inches(self) -> tuple:
66
"""Return the current size of the figure in inches."""
67
68
def set_size_inches(self, w, h=None, forward=True) -> None:
69
"""Set the figure size in inches."""
70
```
71
72
### Axes Class
73
74
Individual plotting area containing the actual data visualization.
75
76
```python { .api }
77
from matplotlib.axes import Axes
78
79
class Axes:
80
# Plotting methods
81
def plot(self, *args, scalex=True, scaley=True, data=None, **kwargs) -> list:
82
"""Plot y versus x as lines and/or markers."""
83
84
def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
85
vmin=None, vmax=None, alpha=None, linewidths=None,
86
edgecolors=None, plotnonfinite=False, **kwargs) -> PathCollection:
87
"""A scatter plot of y vs. x with varying marker size and/or color."""
88
89
def bar(self, x, height, width=0.8, bottom=None, *, align='center',
90
data=None, **kwargs) -> BarContainer:
91
"""Make a bar plot."""
92
93
def barh(self, y, width, height=0.8, left=None, *, align='center',
94
data=None, **kwargs) -> BarContainer:
95
"""Make a horizontal bar plot."""
96
97
def hist(self, x, bins=None, range=None, density=False, weights=None,
98
cumulative=False, bottom=None, histtype='bar', align='mid',
99
orientation='vertical', rwidth=None, log=False, color=None,
100
label=None, stacked=False, **kwargs) -> tuple:
101
"""Compute and plot a histogram."""
102
103
def pie(self, x, explode=None, labels=None, colors=None, autopct=None,
104
pctdistance=0.6, shadow=False, labeldistance=1.1,
105
startangle=0, radius=1, counterclock=True, wedgeprops=None,
106
textprops=None, center=(0, 0), frame=False, rotatelabels=False,
107
normalize=True, **kwargs) -> tuple:
108
"""Plot a pie chart."""
109
110
def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
111
positions=None, widths=None, patch_artist=None,
112
bootstrap=None, usermedians=None, conf_intervals=None,
113
meanline=None, showmeans=None, showcaps=None,
114
showbox=None, showfliers=None, boxprops=None,
115
labels=None, flierprops=None, medianprops=None,
116
meanprops=None, capprops=None, whiskerprops=None,
117
manage_ticks=True, autorange=False, zorder=None,
118
capwidths=None, **kwargs) -> dict:
119
"""Make a box and whisker plot."""
120
121
def violinplot(self, dataset, positions=None, vert=True, widths=0.5,
122
showmeans=False, showextrema=True, showmedians=False,
123
quantiles=None, points=100, bw_method=None, **kwargs) -> dict:
124
"""Make a violin plot."""
125
126
def errorbar(self, x, y, yerr=None, xerr=None, fmt='', ecolor=None,
127
elinewidth=None, capsize=None, barsabove=False,
128
lolims=False, uplims=False, xlolims=False, xuplims=False,
129
errorevery=1, capthick=None, **kwargs) -> ErrorbarContainer:
130
"""Plot y versus x with error bars."""
131
132
# 2D plotting methods
133
def imshow(self, X, cmap=None, norm=None, aspect=None, interpolation=None,
134
alpha=None, vmin=None, vmax=None, origin=None, extent=None,
135
filternorm=True, filterrad=4.0, resample=None, url=None,
136
**kwargs) -> AxesImage:
137
"""Display data as an image, i.e., on a 2D regular raster."""
138
139
def contour(self, X, Y, Z, levels=None, **kwargs) -> QuadContourSet:
140
"""Draw contour lines."""
141
142
def contourf(self, X, Y, Z, levels=None, **kwargs) -> QuadContourSet:
143
"""Draw filled contours."""
144
145
def pcolormesh(self, X, Y, C, **kwargs) -> QuadMesh:
146
"""Create a pseudocolor plot with a non-regular rectangular grid."""
147
148
def quiver(self, X, Y, U, V, C=None, **kwargs) -> Quiver:
149
"""Plot a 2D field of arrows."""
150
151
# Labeling and annotation methods
152
def set_xlabel(self, xlabel, fontdict=None, labelpad=None, *,
153
loc=None, **kwargs) -> Text:
154
"""Set the label for the x-axis."""
155
156
def set_ylabel(self, ylabel, fontdict=None, labelpad=None, *,
157
loc=None, **kwargs) -> Text:
158
"""Set the label for the y-axis."""
159
160
def set_title(self, label, fontdict=None, loc=None, pad=None, *,
161
y=None, **kwargs) -> Text:
162
"""Set a title for the Axes."""
163
164
def text(self, x, y, s, fontdict=None, **kwargs) -> Text:
165
"""Add text to the Axes."""
166
167
def annotate(self, text, xy, xytext=None, xycoords='data', textcoords=None,
168
arrowprops=None, annotation_clip=None, **kwargs) -> Annotation:
169
"""Annotate the point xy with text."""
170
171
def legend(self, *args, **kwargs) -> Legend:
172
"""Place a legend on the Axes."""
173
174
# Axis control methods
175
def set_xlim(self, left=None, right=None, *, emit=True, auto=False,
176
xmin=None, xmax=None) -> tuple:
177
"""Set the x-axis view limits."""
178
179
def set_ylim(self, bottom=None, top=None, *, emit=True, auto=False,
180
ymin=None, ymax=None) -> tuple:
181
"""Set the y-axis view limits."""
182
183
def get_xlim(self) -> tuple:
184
"""Return the x-axis view limits."""
185
186
def get_ylim(self) -> tuple:
187
"""Return the y-axis view limits."""
188
189
def set_xscale(self, value, **kwargs) -> None:
190
"""Set the x-axis scale."""
191
192
def set_yscale(self, value, **kwargs) -> None:
193
"""Set the y-axis scale."""
194
195
def grid(self, visible=None, which='major', axis='both', **kwargs) -> None:
196
"""Configure the grid lines."""
197
198
def set_xticks(self, ticks, labels=None, *, minor=False, **kwargs) -> list:
199
"""Set the xaxis' tick locations and optionally labels."""
200
201
def set_yticks(self, ticks, labels=None, *, minor=False, **kwargs) -> list:
202
"""Set the yaxis' tick locations and optionally labels."""
203
204
def tick_params(self, axis='both', **kwargs) -> None:
205
"""Change the appearance of ticks, tick labels, and gridlines."""
206
207
# Layout and appearance methods
208
def clear(self) -> None:
209
"""Clear the Axes."""
210
211
def cla(self) -> None:
212
"""Clear the Axes."""
213
214
def set_aspect(self, aspect, adjustable=None, anchor=None, share=False) -> None:
215
"""Set the aspect ratio of the axes scaling."""
216
217
def margins(self, *margins, x=None, y=None, tight=True) -> tuple:
218
"""Set or retrieve autoscaling margins."""
219
220
def invert_xaxis(self) -> None:
221
"""Invert the x-axis."""
222
223
def invert_yaxis(self) -> None:
224
"""Invert the y-axis."""
225
```
226
227
### Subplot Creation
228
229
Various ways to create subplot layouts.
230
231
```python { .api }
232
from matplotlib.gridspec import GridSpec
233
234
class GridSpec:
235
def __init__(self, nrows, ncols, figure=None, left=None, bottom=None,
236
right=None, top=None, wspace=None, hspace=None,
237
width_ratios=None, height_ratios=None):
238
"""Create a GridSpec."""
239
240
def __getitem__(self, key) -> SubplotSpec:
241
"""Create and return a SubplotSpec instance."""
242
243
def subplot_mosaic(mosaic, *, sharex=False, sharey=False, width_ratios=None,
244
height_ratios=None, empty_sentinel='.', subplot_kw=None,
245
gridspec_kw=None, **fig_kw) -> tuple:
246
"""Build a layout of Axes based on ASCII art or nested lists."""
247
```
248
249
## Usage Examples
250
251
### Basic Object-Oriented Plot
252
253
```python
254
from matplotlib.figure import Figure
255
import numpy as np
256
257
# Create figure and axes
258
fig = Figure(figsize=(10, 6))
259
ax = fig.add_subplot(111)
260
261
# Generate data and plot
262
x = np.linspace(0, 2*np.pi, 100)
263
y = np.sin(x)
264
265
ax.plot(x, y, 'b-', linewidth=2, label='sin(x)')
266
ax.set_xlabel('X values')
267
ax.set_ylabel('Y values')
268
ax.set_title('Sine Wave')
269
ax.legend()
270
ax.grid(True)
271
272
# Save or display
273
fig.savefig('sine_wave.png', dpi=300, bbox_inches='tight')
274
```
275
276
### Complex Subplot Layout
277
278
```python
279
from matplotlib.figure import Figure
280
from matplotlib.gridspec import GridSpec
281
import numpy as np
282
283
# Create figure with custom layout
284
fig = Figure(figsize=(12, 8))
285
gs = GridSpec(3, 3, figure=fig, hspace=0.3, wspace=0.3)
286
287
# Create different sized subplots
288
ax1 = fig.add_subplot(gs[0, :]) # Top row, all columns
289
ax2 = fig.add_subplot(gs[1, 0]) # Middle left
290
ax3 = fig.add_subplot(gs[1, 1:]) # Middle right (2 columns)
291
ax4 = fig.add_subplot(gs[2, :]) # Bottom row, all columns
292
293
# Plot different data in each subplot
294
x = np.linspace(0, 10, 100)
295
296
ax1.plot(x, np.sin(x))
297
ax1.set_title('Main Plot')
298
299
ax2.scatter(x[::10], np.cos(x[::10]))
300
ax2.set_title('Scatter')
301
302
ax3.bar(range(5), [1, 3, 2, 5, 4])
303
ax3.set_title('Bar Chart')
304
305
ax4.hist(np.random.normal(0, 1, 1000), bins=30)
306
ax4.set_title('Histogram')
307
308
fig.suptitle('Complex Layout Example')
309
```
310
311
### Programmatic Plot Generation
312
313
```python
314
from matplotlib.figure import Figure
315
import numpy as np
316
317
def create_comparison_plot(datasets, labels, title="Comparison"):
318
"""Create a multi-panel comparison plot."""
319
n_datasets = len(datasets)
320
fig = Figure(figsize=(4*n_datasets, 6))
321
322
for i, (data, label) in enumerate(zip(datasets, labels)):
323
ax = fig.add_subplot(1, n_datasets, i+1)
324
325
# Plot histogram and line plot
326
ax.hist(data, bins=30, alpha=0.7, density=True, label='Histogram')
327
328
# Add statistics
329
mean_val = np.mean(data)
330
std_val = np.std(data)
331
ax.axvline(mean_val, color='red', linestyle='--',
332
label=f'Mean: {mean_val:.2f}')
333
ax.axvline(mean_val + std_val, color='orange', linestyle='--', alpha=0.7)
334
ax.axvline(mean_val - std_val, color='orange', linestyle='--', alpha=0.7)
335
336
ax.set_title(f'{label}\\n(μ={mean_val:.2f}, σ={std_val:.2f})')
337
ax.legend()
338
ax.grid(True, alpha=0.3)
339
340
fig.suptitle(title)
341
return fig
342
343
# Usage
344
data1 = np.random.normal(0, 1, 1000)
345
data2 = np.random.normal(2, 1.5, 1000)
346
data3 = np.random.exponential(1, 1000)
347
348
fig = create_comparison_plot(
349
[data1, data2, data3],
350
['Normal(0,1)', 'Normal(2,1.5)', 'Exponential(1)'],
351
'Distribution Comparison'
352
)
353
```
354
355
### Custom Artist Management
356
357
```python
358
from matplotlib.figure import Figure
359
from matplotlib.patches import Rectangle, Circle
360
from matplotlib.lines import Line2D
361
import numpy as np
362
363
fig = Figure(figsize=(10, 8))
364
ax = fig.add_subplot(111)
365
366
# Add custom shapes
367
rect = Rectangle((0.2, 0.2), 0.3, 0.4, facecolor='lightblue',
368
edgecolor='blue', linewidth=2)
369
ax.add_patch(rect)
370
371
circle = Circle((0.7, 0.7), 0.1, facecolor='lightcoral',
372
edgecolor='red', linewidth=2)
373
ax.add_patch(circle)
374
375
# Add custom line
376
line_x = np.linspace(0, 1, 10)
377
line_y = 0.5 + 0.2 * np.sin(2 * np.pi * line_x * 3)
378
line = Line2D(line_x, line_y, color='green', linewidth=3,
379
linestyle='--', marker='o', markersize=8)
380
ax.add_line(line)
381
382
# Configure axes
383
ax.set_xlim(0, 1)
384
ax.set_ylim(0, 1)
385
ax.set_aspect('equal')
386
ax.set_title('Custom Artists Example')
387
ax.grid(True, alpha=0.3)
388
```