or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

3d-objects.mdadvanced-animations.mdanimation-system.mdboolean-operations.mdcoordinate-systems.mdindex.mdinteractive-controls.mdmathematical-objects.mdmatrix-visualization.mdprobability-stats.mdscene-framework.mdtext-and-latex.mdutilities-and-constants.mdvalue-tracking.mdvector-fields.md

probability-stats.mddocs/

0

# Probability and Statistics

1

2

ManimGL provides specialized tools for creating probability and statistical visualizations through the probability module. These components enable interactive probability demonstrations, statistical data visualization, and educational content around probability theory with sample spaces and customizable charts.

3

4

## Capabilities

5

6

### Sample Space Visualization

7

8

Create visual representations of probability sample spaces as colored rectangles that can be subdivided to show probability distributions and conditional probabilities.

9

10

```python { .api }

11

class SampleSpace(Rectangle):

12

def __init__(

13

self,

14

width: float = 3,

15

height: float = 3,

16

fill_color: ManimColor = GREY_D,

17

fill_opacity: float = 1,

18

stroke_width: float = 0.5,

19

stroke_color: ManimColor = GREY_B,

20

default_label_scale_val: float = 1,

21

**kwargs

22

):

23

"""

24

Create a visual sample space for probability demonstrations.

25

26

Parameters:

27

- width: Width of the sample space rectangle

28

- height: Height of the sample space rectangle

29

- fill_color: Base color for the sample space

30

- fill_opacity: Opacity of the filled region

31

- stroke_width: Border thickness

32

- stroke_color: Border color

33

- default_label_scale_val: Scale factor for labels

34

"""

35

36

def add_title(self, title: str = "Sample space", buff: float = MED_SMALL_BUFF) -> None:

37

"""Add a title above the sample space."""

38

39

def add_label(self, label: str) -> None:

40

"""Add a label to the sample space."""

41

42

def complete_p_list(self, p_list: list[float]) -> list[float]:

43

"""

44

Ensure probability list sums to 1 by adding remainder.

45

46

Parameters:

47

- p_list: List of probability values

48

49

Returns:

50

Completed probability list that sums to 1

51

"""

52

53

def get_horizontal_division(

54

self,

55

p_list,

56

colors=[GREEN_E, BLUE_E],

57

vect=DOWN

58

) -> VGroup:

59

"""

60

Create horizontal subdivision of sample space.

61

62

Parameters:

63

- p_list: List of probability values for division

64

- colors: Colors for each subdivision

65

- vect: Direction vector for subdivision

66

67

Returns:

68

VGroup of divided regions

69

"""

70

71

def get_vertical_division(

72

self,

73

p_list,

74

colors=[MAROON_B, YELLOW],

75

vect=RIGHT

76

) -> VGroup:

77

"""

78

Create vertical subdivision of sample space.

79

80

Parameters:

81

- p_list: List of probability values for division

82

- colors: Colors for each subdivision

83

- vect: Direction vector for subdivision

84

85

Returns:

86

VGroup of divided regions

87

"""

88

89

def divide_horizontally(self, *args, **kwargs) -> None:

90

"""Divide the sample space horizontally and add to scene."""

91

92

def divide_vertically(self, *args, **kwargs) -> None:

93

"""Divide the sample space vertically and add to scene."""

94

95

def get_subdivision_braces_and_labels(

96

self,

97

parts,

98

labels,

99

direction,

100

buff=SMALL_BUFF

101

) -> VGroup:

102

"""

103

Create braces and labels for subdivisions.

104

105

Parameters:

106

- parts: List of subdivision parts

107

- labels: List of label strings

108

- direction: Direction for brace placement

109

- buff: Buffer distance from subdivision

110

111

Returns:

112

VGroup containing braces and labels

113

"""

114

115

def get_side_braces_and_labels(

116

self,

117

labels,

118

direction=LEFT,

119

**kwargs

120

) -> VGroup:

121

"""Create side braces and labels for sample space."""

122

123

def get_top_braces_and_labels(self, labels, **kwargs) -> VGroup:

124

"""Create top braces and labels for sample space."""

125

126

def get_bottom_braces_and_labels(self, labels, **kwargs) -> VGroup:

127

"""Create bottom braces and labels for sample space."""

128

129

def __getitem__(self, index: int | slice) -> VGroup:

130

"""Access subdivisions by index."""

131

```

132

133

### Statistical Charts

134

135

Create customizable bar charts for displaying discrete probability distributions and statistical data with axes, labels, and styling.

136

137

```python { .api }

138

class BarChart(VGroup):

139

def __init__(

140

self,

141

values: Iterable[float],

142

height: float = 4,

143

width: float = 6,

144

n_ticks: int = 4,

145

include_x_ticks: bool = False,

146

tick_width: float = 0.2,

147

tick_height: float = 0.15,

148

label_y_axis: bool = True,

149

y_axis_label_height: float = 0.25,

150

max_value: float = 1,

151

bar_colors: list[ManimColor] = [BLUE, YELLOW],

152

bar_fill_opacity: float = 0.8,

153

bar_stroke_width: float = 3,

154

bar_names: list[str] = [],

155

bar_label_scale_val: float = 0.75,

156

**kwargs

157

):

158

"""

159

Create a statistical bar chart with axes and labels.

160

161

Parameters:

162

- values: Iterable of numeric values for bar heights

163

- height: Total height of the chart

164

- width: Total width of the chart

165

- n_ticks: Number of tick marks on y-axis

166

- include_x_ticks: Whether to include x-axis tick marks

167

- tick_width: Width of tick marks

168

- tick_height: Height of tick marks

169

- label_y_axis: Whether to label the y-axis

170

- y_axis_label_height: Height of y-axis labels

171

- max_value: Maximum value for scaling bars

172

- bar_colors: Colors for bars (gradient applied)

173

- bar_fill_opacity: Opacity of bar fills

174

- bar_stroke_width: Width of bar borders

175

- bar_names: Labels for individual bars

176

- bar_label_scale_val: Scale factor for bar labels

177

"""

178

179

def add_axes(self) -> None:

180

"""Create and add x and y axes with tick marks."""

181

182

def add_bars(self, values: Iterable[float]) -> None:

183

"""

184

Create bars proportional to input values.

185

186

Parameters:

187

- values: Numeric values determining bar heights

188

"""

189

190

def change_bar_values(self, values: Iterable[float]) -> None:

191

"""

192

Update bar heights dynamically while maintaining positions.

193

194

Parameters:

195

- values: New values for bar heights

196

"""

197

```

198

199

## Usage Examples

200

201

### Basic Probability Space Demonstration

202

203

```python

204

from manimlib import *

205

206

class BasicProbability(Scene):

207

def construct(self):

208

# Create a sample space

209

sample_space = SampleSpace(width=4, height=3)

210

sample_space.add_title("Rolling a Die")

211

sample_space.set_fill(BLUE_E, opacity=0.3)

212

213

self.play(ShowCreation(sample_space))

214

self.wait()

215

216

# Show equally likely outcomes

217

probabilities = [1/6] * 6

218

horizontal_div = sample_space.get_horizontal_division(

219

probabilities,

220

colors=[RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE]

221

)

222

223

self.play(ShowCreation(horizontal_div))

224

225

# Add labels for outcomes

226

outcome_labels = ["1", "2", "3", "4", "5", "6"]

227

braces_and_labels = sample_space.get_bottom_braces_and_labels(

228

outcome_labels

229

)

230

231

self.play(Write(braces_and_labels))

232

self.wait()

233

```

234

235

### Conditional Probability Visualization

236

237

```python

238

class ConditionalProbability(Scene):

239

def construct(self):

240

# Create sample space for conditional probability

241

sample_space = SampleSpace(width=5, height=4)

242

sample_space.add_title("P(B|A) - Conditional Probability")

243

244

self.add(sample_space)

245

246

# First division: P(A) and P(A')

247

sample_space.divide_horizontally([0.4, 0.6])

248

249

# Add horizontal labels

250

h_labels = sample_space.get_side_braces_and_labels(["A", "A'"])

251

self.play(Write(h_labels))

252

self.wait()

253

254

# Second division: P(B|A) and P(B'|A) within each region

255

sample_space.divide_vertically([0.7, 0.3])

256

257

# Add vertical labels

258

v_labels = sample_space.get_top_braces_and_labels(["B", "B'"])

259

self.play(Write(v_labels))

260

self.wait()

261

262

# Highlight the intersection P(A ∩ B)

263

intersection = sample_space[0][0] # Top-left region

264

intersection.set_fill(YELLOW, opacity=0.8)

265

266

# Add calculation text

267

calc_text = TexText(

268

"P(A ∩ B) = P(A) × P(B|A) = 0.4 × 0.7 = 0.28",

269

font_size=36

270

).to_edge(DOWN)

271

272

self.play(

273

intersection.animate.set_fill(YELLOW, opacity=0.8),

274

Write(calc_text)

275

)

276

self.wait()

277

```

278

279

### Probability Mass Function Visualization

280

281

```python

282

class ProbabilityDistribution(Scene):

283

def construct(self):

284

# Binomial distribution example

285

n, p = 4, 0.3

286

287

# Calculate binomial probabilities

288

from math import comb

289

values = []

290

labels = []

291

292

for k in range(n + 1):

293

prob = comb(n, k) * (p ** k) * ((1 - p) ** (n - k))

294

values.append(prob)

295

labels.append(f"X = {k}")

296

297

# Create bar chart

298

chart = BarChart(

299

values,

300

height=4,

301

width=8,

302

max_value=0.5,

303

bar_names=labels,

304

bar_colors=[BLUE, RED],

305

include_x_ticks=True

306

)

307

308

# Add title and axis labels

309

title = Text("Binomial Distribution: n=4, p=0.3", font_size=32)

310

title.to_edge(UP)

311

312

y_label = Text("P(X = k)", font_size=24)

313

y_label.rotate(PI/2)

314

y_label.next_to(chart, LEFT)

315

316

x_label = Text("Number of Successes (k)", font_size=24)

317

x_label.next_to(chart, DOWN)

318

319

self.play(ShowCreation(chart))

320

self.play(Write(title), Write(x_label), Write(y_label))

321

322

# Animate probability calculation

323

for i, (val, label) in enumerate(zip(values, labels)):

324

prob_text = Text(f"P({label.split()[-1]}) = {val:.3f}", font_size=20)

325

prob_text.next_to(chart[1][i], UP, buff=0.1)

326

327

self.play(Write(prob_text), run_time=0.5)

328

329

self.wait()

330

```

331

332

### Interactive Statistical Comparison

333

334

```python

335

from manimlib.mobject.interactive import LinearNumberSlider

336

337

class InteractiveStats(Scene):

338

def setup(self):

339

# Create sliders for parameters

340

self.n_slider = LinearNumberSlider(

341

value=10, min_value=5, max_value=50, step=1

342

)

343

self.p_slider = LinearNumberSlider(

344

value=0.5, min_value=0.1, max_value=0.9, step=0.05

345

)

346

347

self.n_slider.to_edge(DOWN).shift(UP * 0.5)

348

self.p_slider.to_edge(DOWN)

349

350

self.add(self.n_slider, self.p_slider)

351

352

def construct(self):

353

# Create responsive chart

354

def get_binomial_chart():

355

n = int(self.n_slider.get_value())

356

p = self.p_slider.get_value()

357

358

# Calculate probabilities

359

from math import comb

360

values = []

361

for k in range(min(n + 1, 20)): # Limit for display

362

prob = comb(n, k) * (p ** k) * ((1 - p) ** (n - k))

363

values.append(prob)

364

365

return BarChart(

366

values,

367

height=3,

368

width=6,

369

max_value=0.4,

370

bar_colors=[BLUE, YELLOW]

371

)

372

373

chart = get_binomial_chart()

374

chart.to_edge(UP)

375

376

# Add updater

377

def update_chart(c):

378

new_chart = get_binomial_chart()

379

new_chart.to_edge(UP)

380

c.become(new_chart)

381

382

chart.add_updater(update_chart)

383

384

# Add parameter labels

385

n_label = Text("n (trials)", font_size=20).next_to(self.n_slider, LEFT)

386

p_label = Text("p (success prob)", font_size=20).next_to(self.p_slider, LEFT)

387

388

# Dynamic title

389

title = Text("Interactive Binomial Distribution", font_size=28)

390

title.to_edge(UP).shift(DOWN * 0.5)

391

392

def update_title(t):

393

n = int(self.n_slider.get_value())

394

p = self.p_slider.get_value()

395

new_title = Text(

396

f"Binomial Distribution: n={n}, p={p:.2f}",

397

font_size=28

398

)

399

new_title.to_edge(UP).shift(DOWN * 0.5)

400

t.become(new_title)

401

402

title.add_updater(update_title)

403

404

self.add(chart, n_label, p_label, title)

405

self.wait(15) # Interactive exploration time

406

```

407

408

### Monte Carlo Simulation

409

410

```python

411

class MonteCarloDemo(Scene):

412

def construct(self):

413

# Set up sample space for coin flips

414

sample_space = SampleSpace(width=3, height=2)

415

sample_space.add_title("Coin Flip Outcomes")

416

sample_space.to_edge(LEFT)

417

418

# Divide for heads/tails

419

sample_space.divide_horizontally([0.5, 0.5])

420

sample_space[0].set_fill(GREEN, opacity=0.7)

421

sample_space[1].set_fill(RED, opacity=0.7)

422

423

labels = sample_space.get_side_braces_and_labels(["H", "T"])

424

425

# Results chart

426

chart = BarChart(

427

[0, 0], # Start with no results

428

height=3,

429

width=4,

430

max_value=1,

431

bar_names=["Heads", "Tails"],

432

bar_colors=[GREEN, RED]

433

)

434

chart.to_edge(RIGHT)

435

436

self.add(sample_space, labels, chart)

437

438

# Simulate coin flips

439

import random

440

heads_count = 0

441

total_flips = 0

442

443

counter_text = Text("Flips: 0", font_size=24).to_edge(UP)

444

self.add(counter_text)

445

446

for flip in range(100):

447

total_flips += 1

448

result = random.choice([0, 1]) # 0 = heads, 1 = tails

449

450

if result == 0:

451

heads_count += 1

452

453

# Update proportions

454

heads_prop = heads_count / total_flips

455

tails_prop = 1 - heads_prop

456

457

# Update chart

458

chart.change_bar_values([heads_prop, tails_prop])

459

460

# Update counter

461

counter_text.become(

462

Text(f"Flips: {total_flips}", font_size=24).to_edge(UP)

463

)

464

465

if flip % 10 == 0: # Update every 10 flips for animation

466

self.wait(0.1)

467

468

# Final result

469

final_text = Text(

470

f"Final: {heads_count}/{total_flips} = {heads_prop:.3f}",

471

font_size=24

472

).to_edge(DOWN)

473

474

self.play(Write(final_text))

475

self.wait()

476

```

477

478

### Statistical Test Visualization

479

480

```python

481

class HypothesisTest(Scene):

482

def construct(self):

483

# Set up hypothesis testing scenario

484

title = Text("Hypothesis Testing", font_size=36).to_edge(UP)

485

486

# Null and alternative hypotheses

487

h0 = TexText("H₀: p = 0.5 (fair coin)", font_size=24)

488

h1 = TexText("H₁: p ≠ 0.5 (biased coin)", font_size=24)

489

490

hypotheses = VGroup(h0, h1).arrange(DOWN, buff=0.3)

491

hypotheses.to_edge(LEFT).shift(UP)

492

493

# Sample space showing expected vs observed

494

expected_space = SampleSpace(width=2.5, height=1.5)

495

expected_space.add_title("Expected (H₀)")

496

expected_space.divide_horizontally([0.5, 0.5])

497

expected_space[0].set_fill(BLUE, opacity=0.6)

498

expected_space[1].set_fill(RED, opacity=0.6)

499

500

observed_space = SampleSpace(width=2.5, height=1.5)

501

observed_space.add_title("Observed")

502

observed_space.divide_horizontally([0.3, 0.7]) # Biased result

503

observed_space[0].set_fill(BLUE, opacity=0.6)

504

observed_space[1].set_fill(RED, opacity=0.6)

505

506

spaces = VGroup(expected_space, observed_space)

507

spaces.arrange(RIGHT, buff=1).to_edge(DOWN).shift(UP * 0.5)

508

509

# Statistical analysis

510

analysis = VGroup(

511

Text("Sample size: n = 100", font_size=20),

512

Text("Observed heads: 30", font_size=20),

513

Text("Expected heads: 50", font_size=20),

514

Text("Test statistic: z = -4.0", font_size=20),

515

Text("p-value < 0.001", font_size=20),

516

).arrange(DOWN, aligned_edge=LEFT, buff=0.2)

517

analysis.to_edge(RIGHT)

518

519

# Animate the analysis

520

self.play(Write(title))

521

self.play(Write(hypotheses))

522

self.play(ShowCreation(spaces))

523

524

for line in analysis:

525

self.play(Write(line), run_time=0.8)

526

527

# Conclusion

528

conclusion = Text("Reject H₀: Strong evidence of bias",

529

font_size=24, color=YELLOW)

530

conclusion.to_edge(DOWN)

531

532

self.play(Write(conclusion))

533

self.wait()

534

```

535

536

## Advanced Features

537

538

### Custom Probability Distributions

539

540

```python

541

# Create custom sample space divisions

542

def create_custom_distribution(probabilities, colors):

543

space = SampleSpace()

544

division = space.get_horizontal_division(probabilities, colors)

545

return space, division

546

547

# Multi-level conditioning

548

def create_tree_diagram(space, levels):

549

for level in levels:

550

# Recursive subdivision logic

551

pass

552

```

553

554

### Dynamic Chart Updates

555

556

```python

557

# Smooth transitions between data sets

558

def animate_data_change(chart, old_values, new_values, run_time=2):

559

# Custom animation for smooth bar transitions

560

pass

561

562

# Real-time data streaming

563

def add_streaming_updater(chart, data_source):

564

def updater(c):

565

new_data = data_source.get_latest()

566

c.change_bar_values(new_data)

567

chart.add_updater(updater)

568

```

569

570

The probability and statistics module in ManimGL provides powerful tools for creating educational content around probability theory and statistical analysis, with particular strengths in visual probability demonstrations and interactive statistical visualizations.