or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

3d-plotting.mdanimation.mdbackends.mdcolors-styling.mdindex.mdobject-oriented.mdpyplot.mdshapes.md

backends.mddocs/

0

# Backends and Export

1

2

Output format control and GUI integration. Matplotlib provides multiple backend implementations for different platforms, display systems, and file formats, enabling flexible deployment across environments.

3

4

## Capabilities

5

6

### Backend Management

7

8

Functions for selecting and controlling matplotlib backends.

9

10

```python { .api }

11

import matplotlib

12

import matplotlib.pyplot as plt

13

14

# Core matplotlib backend functions

15

def use(backend, *, force=True) -> None:

16

"""Select the backend used for rendering and GUI integration."""

17

18

def get_backend() -> str:

19

"""Return the name of the current backend."""

20

21

def interactive(b=None) -> bool:

22

"""Set or query interactive mode."""

23

24

def is_interactive() -> bool:

25

"""Return whether plots are updated after every plotting command."""

26

27

# Pyplot backend and interaction functions

28

def switch_backend(newbackend) -> None:

29

"""Switch the default backend."""

30

31

def show(*args, **kwargs) -> None:

32

"""Display all figures and enter the GUI event loop if needed."""

33

34

def ion() -> None:

35

"""Turn on interactive mode."""

36

37

def ioff() -> None:

38

"""Turn off interactive mode."""

39

```

40

41

### Interactive Backends

42

43

GUI backends for interactive plotting and user interaction.

44

45

```python { .api }

46

# Qt-based backends

47

'Qt5Agg' # Qt5 with Anti-Grain Geometry (AGG) rendering

48

'Qt5Cairo' # Qt5 with Cairo rendering

49

50

# Tkinter backend

51

'TkAgg' # Tk with AGG rendering

52

'TkCairo' # Tk with Cairo rendering

53

54

# GTK backends

55

'GTK3Agg' # GTK3 with AGG rendering

56

'GTK3Cairo' # GTK3 with Cairo rendering

57

58

# Platform-specific backends

59

'MacOSX' # Native macOS Cocoa backend

60

'WX' # wxPython backend

61

'WXAgg' # wxPython with AGG rendering

62

63

# Web-based backend

64

'WebAgg' # Web browser-based interactive backend

65

'notebook' # Jupyter notebook integration

66

'nbagg' # Jupyter notebook with interactivity

67

```

68

69

### Non-Interactive Backends

70

71

File output backends for saving plots without GUI interaction.

72

73

```python { .api }

74

# Raster formats

75

'Agg' # Anti-Grain Geometry (PNG, RGBA)

76

'Cairo' # Cairo graphics (PNG, PDF, PS, SVG)

77

78

# Vector formats

79

'PDF' # Portable Document Format

80

'PS' # PostScript

81

'SVG' # Scalable Vector Graphics

82

83

# Additional formats

84

'PGF' # PGF/TikZ for LaTeX

85

'Template' # Template backend for custom output

86

```

87

88

### File Export Functions

89

90

Functions for saving plots to various file formats.

91

92

```python { .api }

93

def savefig(fname, *, dpi='figure', format=None, metadata=None,

94

bbox_inches=None, pad_inches=0.1, facecolor='auto',

95

edgecolor='auto', backend=None, **kwargs) -> None:

96

"""Save the current figure to a file."""

97

98

# Figure.savefig method

99

class Figure:

100

def savefig(self, fname, *, transparent=None, dpi='figure', format=None,

101

metadata=None, bbox_inches=None, pad_inches=0.1,

102

facecolor='auto', edgecolor='auto', backend=None,

103

**kwargs) -> None:

104

"""Save the figure to a file."""

105

```

106

107

### Backend Base Classes

108

109

Base classes for implementing custom backends.

110

111

```python { .api }

112

from matplotlib.backends.backend_bases import *

113

114

class FigureCanvasBase:

115

"""Abstract base class for figure canvas implementations."""

116

117

def draw(self) -> None:

118

"""Draw the figure."""

119

120

def draw_idle(self) -> None:

121

"""Request a draw when the GUI is idle."""

122

123

def print_figure(self, filename, **kwargs) -> None:

124

"""Print/save the figure to a file."""

125

126

def mpl_connect(self, s, func) -> int:

127

"""Connect a callback function to a matplotlib event."""

128

129

def mpl_disconnect(self, cid) -> None:

130

"""Disconnect a callback by connection id."""

131

132

class RendererBase:

133

"""Abstract base class for renderers."""

134

135

def draw_path(self, gc, path, transform, rgbFace=None) -> None:

136

"""Draw a path using the graphics context."""

137

138

def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None) -> None:

139

"""Draw text at position (x, y)."""

140

141

def draw_image(self, gc, x, y, im, transform=None) -> None:

142

"""Draw an image at position (x, y)."""

143

144

class FigureManagerBase:

145

"""Abstract base class for figure window managers."""

146

147

def show(self) -> None:

148

"""Show the figure window."""

149

150

def destroy(self) -> None:

151

"""Destroy the figure window."""

152

153

def set_window_title(self, title) -> None:

154

"""Set the title of the figure window."""

155

```

156

157

### Format-Specific Options

158

159

Options and metadata for different output formats.

160

161

```python { .api }

162

# PNG format options

163

PNG_OPTIONS = {

164

'dpi': 'figure', # Resolution in dots per inch

165

'facecolor': 'auto', # Figure background color

166

'edgecolor': 'auto', # Figure edge color

167

'transparent': False, # Transparent background

168

'bbox_inches': None, # Bounding box (tight, or None)

169

'pad_inches': 0.1, # Padding around saved area

170

'metadata': None # PNG metadata dictionary

171

}

172

173

# PDF format options

174

PDF_OPTIONS = {

175

'dpi': 'figure',

176

'facecolor': 'auto',

177

'edgecolor': 'auto',

178

'bbox_inches': None,

179

'pad_inches': 0.1,

180

'metadata': None, # PDF metadata dictionary

181

'backend_pdf': None # Backend-specific options

182

}

183

184

# SVG format options

185

SVG_OPTIONS = {

186

'dpi': 'figure',

187

'facecolor': 'auto',

188

'edgecolor': 'auto',

189

'bbox_inches': None,

190

'pad_inches': 0.1,

191

'metadata': None, # SVG metadata

192

'svg.image_inline': True, # Embed images inline

193

'svg.fonttype': 'path' # How to handle fonts

194

}

195

196

# PostScript options

197

PS_OPTIONS = {

198

'dpi': 'figure',

199

'facecolor': 'auto',

200

'edgecolor': 'auto',

201

'bbox_inches': None,

202

'pad_inches': 0.1,

203

'papertype': 'auto', # Paper size

204

'orientation': 'portrait' # Page orientation

205

}

206

```

207

208

## Usage Examples

209

210

### Backend Selection

211

212

```python

213

import matplotlib

214

import matplotlib.pyplot as plt

215

import numpy as np

216

217

# Check current backend

218

print(f"Current backend: {matplotlib.get_backend()}")

219

220

# List available backends

221

print(f"Available interactive backends: {matplotlib.backend_bases.Backend}")

222

223

# Set specific backend (must be done before importing pyplot)

224

# matplotlib.use('TkAgg') # For Tkinter GUI

225

# matplotlib.use('Qt5Agg') # For Qt5 GUI

226

# matplotlib.use('Agg') # For non-interactive (file output only)

227

228

# Create a simple plot

229

x = np.linspace(0, 10, 100)

230

y = np.sin(x)

231

232

plt.figure(figsize=(10, 6))

233

plt.plot(x, y, 'b-', linewidth=2)

234

plt.title(f'Plot using {matplotlib.get_backend()} backend')

235

plt.xlabel('X')

236

plt.ylabel('sin(X)')

237

plt.grid(True)

238

plt.show()

239

```

240

241

### Saving to Multiple Formats

242

243

```python

244

import matplotlib.pyplot as plt

245

import numpy as np

246

247

# Create sample plot

248

x = np.linspace(0, 10, 100)

249

y1 = np.sin(x)

250

y2 = np.cos(x)

251

252

fig, ax = plt.subplots(figsize=(10, 6))

253

ax.plot(x, y1, 'b-', linewidth=2, label='sin(x)')

254

ax.plot(x, y2, 'r-', linewidth=2, label='cos(x)')

255

ax.set_xlabel('X')

256

ax.set_ylabel('Y')

257

ax.set_title('Trigonometric Functions')

258

ax.legend()

259

ax.grid(True)

260

261

# Save in different formats

262

formats = {

263

'PNG': {'format': 'png', 'dpi': 300, 'bbox_inches': 'tight'},

264

'PDF': {'format': 'pdf', 'bbox_inches': 'tight'},

265

'SVG': {'format': 'svg', 'bbox_inches': 'tight'},

266

'EPS': {'format': 'eps', 'bbox_inches': 'tight'},

267

'JPG': {'format': 'jpg', 'dpi': 150, 'bbox_inches': 'tight'}

268

}

269

270

for name, options in formats.items():

271

filename = f'trigonometric_plot.{options["format"]}'

272

try:

273

fig.savefig(filename, **options)

274

print(f"Saved as {filename}")

275

except Exception as e:

276

print(f"Could not save as {name}: {e}")

277

278

plt.show()

279

```

280

281

### High-Quality Publication Output

282

283

```python

284

import matplotlib.pyplot as plt

285

import numpy as np

286

287

# Set up for publication-quality output

288

plt.rcParams.update({

289

'font.size': 12,

290

'font.family': 'serif',

291

'text.usetex': False, # Set True if LaTeX is available

292

'figure.figsize': (8, 6),

293

'figure.dpi': 100,

294

'savefig.dpi': 300,

295

'savefig.format': 'pdf',

296

'savefig.bbox': 'tight',

297

'axes.linewidth': 1.2,

298

'axes.spines.top': False,

299

'axes.spines.right': False,

300

'xtick.major.size': 4,

301

'ytick.major.size': 4,

302

'legend.frameon': False

303

})

304

305

# Create publication-quality plot

306

x = np.linspace(0, 2*np.pi, 1000)

307

y1 = np.sin(x)

308

y2 = np.sin(2*x) * 0.5

309

y3 = np.sin(3*x) * 0.25

310

311

fig, ax = plt.subplots()

312

313

ax.plot(x, y1, 'k-', linewidth=1.5, label='$\\sin(x)$')

314

ax.plot(x, y2, 'k--', linewidth=1.5, label='$0.5\\sin(2x)$')

315

ax.plot(x, y3, 'k:', linewidth=1.5, label='$0.25\\sin(3x)$')

316

317

ax.set_xlabel('$x$ (radians)')

318

ax.set_ylabel('Amplitude')

319

ax.set_title('Harmonic Functions')

320

ax.legend(loc='upper right')

321

ax.grid(True, alpha=0.3, linewidth=0.5)

322

323

# Set custom axis limits and ticks

324

ax.set_xlim(0, 2*np.pi)

325

ax.set_xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi])

326

ax.set_xticklabels(['0', '$\\pi/2$', '$\\pi$', '$3\\pi/2$', '$2\\pi$'])

327

328

# Save with high quality settings

329

fig.savefig('publication_plot.pdf', dpi=300, bbox_inches='tight',

330

facecolor='white', edgecolor='none')

331

fig.savefig('publication_plot.png', dpi=600, bbox_inches='tight',

332

facecolor='white', edgecolor='none')

333

334

plt.show()

335

```

336

337

### Interactive Backend Comparison

338

339

```python

340

import matplotlib

341

import matplotlib.pyplot as plt

342

import numpy as np

343

344

def create_interactive_plot():

345

"""Create plot with interactive features."""

346

fig, ax = plt.subplots(figsize=(10, 6))

347

348

x = np.linspace(0, 10, 100)

349

y = np.sin(x)

350

351

line, = ax.plot(x, y, 'b-', linewidth=2)

352

ax.set_xlabel('X')

353

ax.set_ylabel('sin(X)')

354

ax.set_title(f'Interactive Plot - Backend: {matplotlib.get_backend()}')

355

ax.grid(True)

356

357

# Add interactive callback

358

def on_click(event):

359

if event.inaxes == ax:

360

print(f"Clicked at ({event.xdata:.2f}, {event.ydata:.2f})")

361

362

fig.canvas.mpl_connect('button_press_event', on_click)

363

364

return fig, ax

365

366

# Test different interactive backends

367

interactive_backends = ['Qt5Agg', 'TkAgg', 'MacOSX']

368

369

for backend in interactive_backends:

370

try:

371

# Note: In practice, backend should be set before importing pyplot

372

print(f"\\nTesting backend: {backend}")

373

374

# This would normally require restarting Python

375

# matplotlib.use(backend)

376

377

fig, ax = create_interactive_plot()

378

plt.show(block=False) # Non-blocking show

379

380

# Backend-specific features

381

if 'Qt' in matplotlib.get_backend():

382

print("Qt backend: Supports native zoom, pan, configure subplots")

383

elif 'Tk' in matplotlib.get_backend():

384

print("Tk backend: Lightweight, good for simple interactions")

385

elif 'MacOSX' in matplotlib.get_backend():

386

print("macOS backend: Native macOS integration")

387

388

except Exception as e:

389

print(f"Backend {backend} not available: {e}")

390

391

plt.show()

392

```

393

394

### Web-Based Backend

395

396

```python

397

import matplotlib

398

import matplotlib.pyplot as plt

399

import numpy as np

400

401

# Use WebAgg for web-based interaction

402

# matplotlib.use('WebAgg')

403

404

# Create interactive web plot

405

fig, ax = plt.subplots(figsize=(10, 6))

406

407

# Generate data

408

t = np.linspace(0, 4*np.pi, 200)

409

x = np.sin(t)

410

y = np.cos(t * 1.5)

411

412

ax.plot(t, x, 'b-', linewidth=2, label='sin(t)', alpha=0.8)

413

ax.plot(t, y, 'r-', linewidth=2, label='cos(1.5t)', alpha=0.8)

414

415

ax.set_xlabel('Time')

416

ax.set_ylabel('Amplitude')

417

ax.set_title('Interactive Web Plot')

418

ax.legend()

419

ax.grid(True, alpha=0.3)

420

421

# The WebAgg backend automatically creates a web server

422

# and opens the plot in a browser with zoom/pan controls

423

print("WebAgg backend creates interactive web interface")

424

print("Navigate to http://127.0.0.1:8988 to view the plot")

425

426

plt.show()

427

```

428

429

### Custom Metadata and Export Options

430

431

```python

432

import matplotlib.pyplot as plt

433

import numpy as np

434

from datetime import datetime

435

436

# Create plot with comprehensive metadata

437

fig, ax = plt.subplots(figsize=(10, 6))

438

439

x = np.linspace(0, 10, 100)

440

y = np.exp(-x/5) * np.sin(x)

441

442

ax.plot(x, y, 'b-', linewidth=2)

443

ax.set_xlabel('Distance (m)')

444

ax.set_ylabel('Amplitude')

445

ax.set_title('Exponentially Decaying Oscillation')

446

ax.grid(True, alpha=0.3)

447

448

# Comprehensive metadata

449

metadata_common = {

450

'Title': 'Exponentially Decaying Oscillation',

451

'Author': 'Scientific Computing Lab',

452

'Subject': 'Mathematical Visualization',

453

'Keywords': 'exponential decay, oscillation, mathematics',

454

'Creator': 'matplotlib',

455

'CreationDate': datetime.now(),

456

'Description': 'Plot showing exponential decay with oscillation'

457

}

458

459

# Format-specific exports with metadata

460

export_configs = {

461

'high_res_png': {

462

'filename': 'decay_oscillation_highres.png',

463

'format': 'png',

464

'dpi': 600,

465

'bbox_inches': 'tight',

466

'facecolor': 'white',

467

'edgecolor': 'none',

468

'metadata': metadata_common

469

},

470

'web_png': {

471

'filename': 'decay_oscillation_web.png',

472

'format': 'png',

473

'dpi': 150,

474

'bbox_inches': 'tight',

475

'facecolor': 'white',

476

'metadata': metadata_common

477

},

478

'vector_pdf': {

479

'filename': 'decay_oscillation_vector.pdf',

480

'format': 'pdf',

481

'bbox_inches': 'tight',

482

'metadata': metadata_common

483

},

484

'scalable_svg': {

485

'filename': 'decay_oscillation_scalable.svg',

486

'format': 'svg',

487

'bbox_inches': 'tight',

488

'metadata': metadata_common

489

}

490

}

491

492

# Export in all configured formats

493

for config_name, options in export_configs.items():

494

try:

495

fig.savefig(**options)

496

print(f"Exported {config_name}: {options['filename']}")

497

except Exception as e:

498

print(f"Failed to export {config_name}: {e}")

499

500

plt.show()

501

502

# Print file size comparison

503

import os

504

print("\\nFile size comparison:")

505

for config_name, options in export_configs.items():

506

filename = options['filename']

507

if os.path.exists(filename):

508

size_kb = os.path.getsize(filename) / 1024

509

print(f"{filename}: {size_kb:.1f} KB")

510

```