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

shapes.mddocs/

0

# Geometric Shapes

1

2

Drawing primitive shapes and complex geometric objects. Matplotlib provides extensive patch classes for creating rectangles, circles, polygons, arrows, and custom geometric shapes with full styling control.

3

4

## Capabilities

5

6

### Basic Shapes

7

8

Fundamental geometric shapes for annotations and custom graphics.

9

10

```python { .api }

11

import matplotlib.patches as mpatches

12

13

class Rectangle:

14

def __init__(self, xy, width, height, *, angle=0.0, **kwargs):

15

"""Rectangle patch with bottom-left corner at xy."""

16

17

def get_x(self) -> float:

18

"""Return the left coordinate of the rectangle."""

19

20

def get_y(self) -> float:

21

"""Return the bottom coordinate of the rectangle."""

22

23

def get_width(self) -> float:

24

"""Return the width of the rectangle."""

25

26

def get_height(self) -> float:

27

"""Return the height of the rectangle."""

28

29

def set_x(self, x) -> None:

30

"""Set the left coordinate of the rectangle."""

31

32

def set_y(self, y) -> None:

33

"""Set the bottom coordinate of the rectangle."""

34

35

def set_width(self, w) -> None:

36

"""Set the width of the rectangle."""

37

38

def set_height(self, h) -> None:

39

"""Set the height of the rectangle."""

40

41

class Circle:

42

def __init__(self, xy, radius, **kwargs):

43

"""Circle patch centered at xy."""

44

45

def get_radius(self) -> float:

46

"""Return the radius of the circle."""

47

48

def set_radius(self, radius) -> None:

49

"""Set the radius of the circle."""

50

51

class Ellipse:

52

def __init__(self, xy, width, height, *, angle=0, **kwargs):

53

"""Ellipse patch centered at xy."""

54

55

def get_width(self) -> float:

56

"""Return the width of the ellipse."""

57

58

def get_height(self) -> float:

59

"""Return the height of the ellipse."""

60

61

class Polygon:

62

def __init__(self, xy, *, closed=True, **kwargs):

63

"""General polygon patch from sequence of xy coordinates."""

64

65

def get_xy(self) -> np.ndarray:

66

"""Get the vertices of the polygon."""

67

68

def set_xy(self, xy) -> None:

69

"""Set the vertices of the polygon."""

70

71

class RegularPolygon:

72

def __init__(self, xy, numVertices, radius=5, *, orientation=0, **kwargs):

73

"""Regular polygon with numVertices sides."""

74

75

def get_numVertices(self) -> int:

76

"""Return the number of vertices."""

77

78

def get_radius(self) -> float:

79

"""Return the radius of the polygon."""

80

81

def get_orientation(self) -> float:

82

"""Return the orientation of the polygon."""

83

```

84

85

### Specialized Shapes

86

87

More complex geometric shapes for specific use cases.

88

89

```python { .api }

90

class Wedge:

91

def __init__(self, center, r, theta1, theta2, *, width=None, **kwargs):

92

"""Wedge-shaped patch from center with angular range."""

93

94

def get_center(self) -> tuple:

95

"""Return the center of the wedge."""

96

97

def get_radius(self) -> float:

98

"""Return the radius of the wedge."""

99

100

def get_theta1(self) -> float:

101

"""Return the start angle of the wedge."""

102

103

def get_theta2(self) -> float:

104

"""Return the end angle of the wedge."""

105

106

class Arc:

107

def __init__(self, xy, width, height, *, angle=0, theta1=0, theta2=360, **kwargs):

108

"""Elliptical arc patch."""

109

110

def get_theta1(self) -> float:

111

"""Return the start angle of the arc."""

112

113

def get_theta2(self) -> float:

114

"""Return the end angle of the arc."""

115

116

class PathPatch:

117

def __init__(self, path, **kwargs):

118

"""Patch from a matplotlib Path object."""

119

120

def get_path(self) -> Path:

121

"""Return the path of the patch."""

122

123

def set_path(self, path) -> None:

124

"""Set the path of the patch."""

125

```

126

127

### Arrow Shapes

128

129

Arrows and directional indicators with customizable styling.

130

131

```python { .api }

132

class Arrow:

133

def __init__(self, x, y, dx, dy, *, width=1.0, **kwargs):

134

"""Simple arrow patch from (x,y) with displacement (dx,dy)."""

135

136

def get_x(self) -> float:

137

"""Return the x coordinate of the arrow base."""

138

139

def get_y(self) -> float:

140

"""Return the y coordinate of the arrow base."""

141

142

class FancyArrow:

143

def __init__(self, x, y, dx, dy, *, width=0.001, length_includes_head=False,

144

head_width=None, head_length=None, shape='full', overhang=0,

145

head_starts_at_zero=False, **kwargs):

146

"""Fancy arrow with customizable head and tail."""

147

148

def get_dxy(self) -> tuple:

149

"""Return the displacement (dx, dy) of the arrow."""

150

151

class FancyArrowPatch:

152

def __init__(self, posA=None, posB=None, *, path=None, arrowstyle='->',

153

connectionstyle='arc3', patchA=None, patchB=None,

154

shrinkA=2, shrinkB=2, mutation_scale=20, mutation_aspect=1,

155

**kwargs):

156

"""Fancy arrow patch connecting two points with custom styling."""

157

158

def set_positions(self, posA, posB) -> None:

159

"""Set the start and end positions of the arrow."""

160

161

def set_arrowstyle(self, arrowstyle=None, **kwargs) -> None:

162

"""Set the arrow style."""

163

164

def set_connectionstyle(self, connectionstyle, **kwargs) -> None:

165

"""Set the connection style."""

166

```

167

168

### Advanced Patches

169

170

Complex patch types for specialized graphics.

171

172

```python { .api }

173

class FancyBboxPatch:

174

def __init__(self, xy, width, height, *, boxstyle='round', **kwargs):

175

"""Fancy bounding box with various border styles."""

176

177

def set_boxstyle(self, boxstyle=None, **kwargs) -> None:

178

"""Set the box style."""

179

180

def get_boxstyle(self) -> BoxStyle:

181

"""Return the box style."""

182

183

class ConnectionPatch:

184

def __init__(self, xyA, xyB, coordsA, coordsB=None, *,

185

axesA=None, axesB=None, arrowstyle='-', shrinkA=0, shrinkB=0,

186

**kwargs):

187

"""Patch to connect two points, possibly in different coordinate systems."""

188

189

def set_xyA(self, xy) -> None:

190

"""Set the starting point A."""

191

192

def set_xyB(self, xy) -> None:

193

"""Set the ending point B."""

194

195

class Shadow:

196

def __init__(self, patch, ox, oy, *, props=None, **kwargs):

197

"""Create a shadow effect for another patch."""

198

```

199

200

### Style Classes

201

202

Style specifications for complex patches.

203

204

```python { .api }

205

class BoxStyle:

206

"""Box styling options for FancyBboxPatch."""

207

208

@staticmethod

209

def Round(pad=0.3, rounding_size=None) -> BoxStyle:

210

"""Rounded corner box style."""

211

212

@staticmethod

213

def Square(pad=0.3) -> BoxStyle:

214

"""Square corner box style."""

215

216

@staticmethod

217

def Sawtooth(pad=0.3, tooth_size=None) -> BoxStyle:

218

"""Sawtooth edge box style."""

219

220

@staticmethod

221

def Circle(pad=0.3) -> BoxStyle:

222

"""Circular box style."""

223

224

class ArrowStyle:

225

"""Arrow styling options for FancyArrowPatch."""

226

227

@staticmethod

228

def Simple(head_length=0.5, head_width=0.5, tail_width=0.2) -> ArrowStyle:

229

"""Simple arrow style."""

230

231

@staticmethod

232

def Fancy(head_length=0.4, head_width=0.4, tail_width=0.4) -> ArrowStyle:

233

"""Fancy arrow style."""

234

235

@staticmethod

236

def Wedge(tail_width=0.3, shrink_factor=0.5) -> ArrowStyle:

237

"""Wedge arrow style."""

238

239

class ConnectionStyle:

240

"""Connection styling options for connecting patches."""

241

242

@staticmethod

243

def Arc3(rad=0.0) -> ConnectionStyle:

244

"""Arc connection with specified radius."""

245

246

@staticmethod

247

def Angle3(angleA=90, angleB=0) -> ConnectionStyle:

248

"""Angle connection with specified angles."""

249

250

@staticmethod

251

def Bar(armA=0.0, armB=0.0, fraction=0.3, angle=None) -> ConnectionStyle:

252

"""Bar connection style."""

253

```

254

255

## Usage Examples

256

257

### Basic Shapes

258

259

```python

260

import matplotlib.pyplot as plt

261

import matplotlib.patches as mpatches

262

import numpy as np

263

264

fig, ax = plt.subplots(figsize=(12, 8))

265

266

# Rectangle

267

rect = mpatches.Rectangle((0.1, 0.1), 0.3, 0.2,

268

facecolor='lightblue', edgecolor='blue', linewidth=2)

269

ax.add_patch(rect)

270

271

# Circle

272

circle = mpatches.Circle((0.6, 0.2), 0.1,

273

facecolor='lightcoral', edgecolor='red', linewidth=2)

274

ax.add_patch(circle)

275

276

# Ellipse

277

ellipse = mpatches.Ellipse((0.2, 0.6), 0.2, 0.1, angle=45,

278

facecolor='lightgreen', edgecolor='green', linewidth=2)

279

ax.add_patch(ellipse)

280

281

# Polygon (triangle)

282

triangle = mpatches.Polygon([(0.5, 0.5), (0.7, 0.5), (0.6, 0.7)],

283

facecolor='yellow', edgecolor='orange', linewidth=2)

284

ax.add_patch(triangle)

285

286

# Regular polygon (hexagon)

287

hexagon = mpatches.RegularPolygon((0.8, 0.7), 6, radius=0.08,

288

facecolor='plum', edgecolor='purple', linewidth=2)

289

ax.add_patch(hexagon)

290

291

ax.set_xlim(0, 1)

292

ax.set_ylim(0, 1)

293

ax.set_aspect('equal')

294

ax.set_title('Basic Shapes')

295

ax.grid(True, alpha=0.3)

296

plt.show()

297

```

298

299

### Arrows and Directional Graphics

300

301

```python

302

import matplotlib.pyplot as plt

303

import matplotlib.patches as mpatches

304

305

fig, ax = plt.subplots(figsize=(12, 8))

306

307

# Simple arrow

308

arrow1 = mpatches.Arrow(0.1, 0.1, 0.2, 0.1, width=0.05, color='red')

309

ax.add_patch(arrow1)

310

311

# Fancy arrow

312

arrow2 = mpatches.FancyArrow(0.1, 0.3, 0.3, 0.0, width=0.02, head_width=0.05,

313

head_length=0.03, fc='blue', ec='darkblue')

314

ax.add_patch(arrow2)

315

316

# Fancy arrow patch with custom styling

317

arrow3 = mpatches.FancyArrowPatch((0.1, 0.5), (0.4, 0.7),

318

arrowstyle='->', mutation_scale=20,

319

color='green', linewidth=2)

320

ax.add_patch(arrow3)

321

322

# Curved arrow

323

arrow4 = mpatches.FancyArrowPatch((0.6, 0.2), (0.8, 0.6),

324

connectionstyle='arc3,rad=0.3',

325

arrowstyle='-|>', mutation_scale=20,

326

color='purple', linewidth=2)

327

ax.add_patch(arrow4)

328

329

# Bidirectional arrow

330

arrow5 = mpatches.FancyArrowPatch((0.5, 0.8), (0.9, 0.8),

331

arrowstyle='<->', mutation_scale=20,

332

color='orange', linewidth=2)

333

ax.add_patch(arrow5)

334

335

ax.set_xlim(0, 1)

336

ax.set_ylim(0, 1)

337

ax.set_aspect('equal')

338

ax.set_title('Arrow Examples')

339

ax.grid(True, alpha=0.3)

340

plt.show()

341

```

342

343

### Advanced Patch Styling

344

345

```python

346

import matplotlib.pyplot as plt

347

import matplotlib.patches as mpatches

348

349

fig, ax = plt.subplots(figsize=(12, 8))

350

351

# Fancy bounding boxes with different styles

352

styles = ['round', 'square', 'sawtooth', 'circle']

353

colors = ['lightblue', 'lightcoral', 'lightgreen', 'lightyellow']

354

355

for i, (style, color) in enumerate(zip(styles, colors)):

356

x = 0.1 + (i % 2) * 0.4

357

y = 0.6 - (i // 2) * 0.3

358

359

bbox = mpatches.FancyBboxPatch((x, y), 0.25, 0.15,

360

boxstyle=f"{style},pad=0.02",

361

facecolor=color, edgecolor='black',

362

linewidth=1.5)

363

ax.add_patch(bbox)

364

365

# Add text label

366

ax.text(x + 0.125, y + 0.075, style.capitalize(),

367

ha='center', va='center', fontsize=12, weight='bold')

368

369

# Wedge (pie slice)

370

wedge = mpatches.Wedge((0.8, 0.3), 0.15, 30, 120,

371

facecolor='gold', edgecolor='orange', linewidth=2)

372

ax.add_patch(wedge)

373

374

# Arc

375

arc = mpatches.Arc((0.8, 0.3), 0.3, 0.3, angle=0, theta1=150, theta2=390,

376

edgecolor='red', linewidth=3)

377

ax.add_patch(arc)

378

379

ax.set_xlim(0, 1)

380

ax.set_ylim(0, 1)

381

ax.set_aspect('equal')

382

ax.set_title('Advanced Patch Styling')

383

ax.grid(True, alpha=0.3)

384

plt.show()

385

```

386

387

### Interactive Shape Creation

388

389

```python

390

import matplotlib.pyplot as plt

391

import matplotlib.patches as mpatches

392

import numpy as np

393

394

def create_flowchart():

395

"""Create a simple flowchart using patches."""

396

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

397

398

# Define positions and sizes

399

boxes = [

400

{'xy': (0.2, 0.8), 'size': (0.15, 0.08), 'text': 'Start', 'style': 'round'},

401

{'xy': (0.2, 0.6), 'size': (0.15, 0.08), 'text': 'Process', 'style': 'square'},

402

{'xy': (0.2, 0.4), 'size': (0.15, 0.08), 'text': 'Decision', 'style': 'round'},

403

{'xy': (0.5, 0.4), 'size': (0.15, 0.08), 'text': 'Yes Branch', 'style': 'square'},

404

{'xy': (0.2, 0.2), 'size': (0.15, 0.08), 'text': 'No Branch', 'style': 'square'},

405

{'xy': (0.5, 0.2), 'size': (0.15, 0.08), 'text': 'End', 'style': 'round'}

406

]

407

408

# Create boxes

409

for box in boxes:

410

patch = mpatches.FancyBboxPatch(

411

box['xy'], box['size'][0], box['size'][1],

412

boxstyle=f"{box['style']},pad=0.01",

413

facecolor='lightblue', edgecolor='navy', linewidth=2

414

)

415

ax.add_patch(patch)

416

417

# Add text

418

center_x = box['xy'][0] + box['size'][0]/2

419

center_y = box['xy'][1] + box['size'][1]/2

420

ax.text(center_x, center_y, box['text'],

421

ha='center', va='center', fontsize=10, weight='bold')

422

423

# Add connecting arrows

424

arrows = [

425

((0.275, 0.8), (0.275, 0.68)), # Start to Process

426

((0.275, 0.6), (0.275, 0.48)), # Process to Decision

427

((0.35, 0.44), (0.5, 0.44)), # Decision to Yes

428

((0.275, 0.4), (0.275, 0.28)), # Decision to No

429

((0.575, 0.4), (0.575, 0.28)) # Yes to End

430

]

431

432

for start, end in arrows:

433

arrow = mpatches.FancyArrowPatch(start, end,

434

arrowstyle='->', mutation_scale=15,

435

color='darkblue', linewidth=2)

436

ax.add_patch(arrow)

437

438

# Add labels for decision branches

439

ax.text(0.42, 0.46, 'Yes', ha='center', va='center', fontsize=9,

440

bbox=dict(boxstyle='round,pad=0.3', facecolor='white', alpha=0.8))

441

ax.text(0.3, 0.32, 'No', ha='center', va='center', fontsize=9,

442

bbox=dict(boxstyle='round,pad=0.3', facecolor='white', alpha=0.8))

443

444

ax.set_xlim(0, 0.8)

445

ax.set_ylim(0, 1)

446

ax.set_aspect('equal')

447

ax.set_title('Flowchart Example using Patches')

448

ax.axis('off')

449

plt.show()

450

451

create_flowchart()

452

```

453

454

### Custom Shape Creation

455

456

```python

457

import matplotlib.pyplot as plt

458

import matplotlib.patches as mpatches

459

from matplotlib.path import Path

460

import numpy as np

461

462

# Create custom star shape using Path

463

def create_star(center, radius, n_points=5):

464

"""Create a star shape path."""

465

angles = np.linspace(0, 2*np.pi, n_points*2, endpoint=False)

466

radii = np.array([radius, radius*0.4] * n_points)

467

468

x = center[0] + radii * np.cos(angles)

469

y = center[1] + radii * np.sin(angles)

470

471

vertices = list(zip(x, y))

472

codes = [Path.MOVETO] + [Path.LINETO] * (len(vertices)-2) + [Path.CLOSEPOLY]

473

474

return Path(vertices, codes)

475

476

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

477

478

# Create multiple custom stars

479

centers = [(0.2, 0.3), (0.5, 0.7), (0.8, 0.4)]

480

radii = [0.08, 0.12, 0.06]

481

colors = ['gold', 'orange', 'yellow']

482

483

for center, radius, color in zip(centers, radii, colors):

484

star_path = create_star(center, radius)

485

star_patch = mpatches.PathPatch(star_path, facecolor=color,

486

edgecolor='darkorange', linewidth=2)

487

ax.add_patch(star_patch)

488

489

# Add some decorative circles

490

for i in range(8):

491

angle = i * np.pi / 4

492

x = 0.5 + 0.3 * np.cos(angle)

493

y = 0.5 + 0.3 * np.sin(angle)

494

circle = mpatches.Circle((x, y), 0.02, facecolor='lightblue',

495

edgecolor='blue', alpha=0.7)

496

ax.add_patch(circle)

497

498

ax.set_xlim(0, 1)

499

ax.set_ylim(0, 1)

500

ax.set_aspect('equal')

501

ax.set_title('Custom Shapes with Paths')

502

ax.set_facecolor('lightgray')

503

ax.grid(True, alpha=0.3)

504

plt.show()

505

```