@@ -283,122 +283,239 @@ fig.title("Annotated Graph")
283283
284284## 🎬 Animation
285285
286- Pythonic provides two powerful animation functions: `animate()` and `animate_plots()` .
286+ Pythonic provides a unified `animate()` function for creating beautiful terminal animations .
287287
288- ### Simple Animation (`animate`)
288+ ### AnimateConfig - Configuration Struct
289289
290- Animate a time-varying function with a single call:
290+ The `AnimateConfig` struct lets you configure all animation parameters:
291+
292+ ```cpp
293+ #include <pythonic/pythonic.hpp>
294+ using namespace pythonic::plot;
295+
296+ // Create config with fluent builder pattern
297+ auto cfg = AnimateConfig()
298+ .x_range(-PI, PI) // X axis range
299+ .time(20.0) // Duration in seconds
300+ .framerate(30) // FPS
301+ .size(120, 35) // Size in characters (width, height)
302+ // OR
303+ .size_px(240, 140) // Size in pixels (auto-converts to chars)
304+ .labels("cyan") // Color for X/Y axis labels
305+ .ranges("magenta") // Color for min/max range values
306+ .set_title("My Animation");
307+ ```
308+
309+ ** Available configuration methods:**
310+
311+ | Method | Description | Default |
312+ | -------------------- | ------------------------------------------ | --------- |
313+ | ` .x_range(min, max) ` | X axis range | -10 to 10 |
314+ | ` .time(seconds) ` | Animation duration | 10.0 |
315+ | ` .framerate(fps) ` | Frames per second | 30 |
316+ | ` .size(w, h) ` | Size in terminal characters | 80×24 |
317+ | ` .size_px(w, h) ` | Size in pixels (Braille converts to chars) | - |
318+ | ` .labels(color) ` | Color for X/Y axis labels | "cyan" |
319+ | ` .ranges(color) ` | Color for min/max values | "magenta" |
320+ | ` .set_title(text) ` | Plot title | "" |
321+
322+ ---
323+
324+ ### Simple Single-Plot Animation
291325
292326``` cpp
293327#include < pythonic/pythonic.hpp>
294328using namespace pythonic ::plot;
295329
296330int main() {
297- // animate(f, x_min, x_max, duration, fps, width, height)
331+ // Simplest form: function, x_range
332+ animate(
333+ [ ] (double t, double x) { return sin(x + t); },
334+ -PI, PI // x range
335+ );
336+
337+ // With more options (positional arguments)
298338 animate(
299- [](double t, double x) { return sin(x + t); }, // f(t, x)
300- -PI, PI, // x range
301- 10.0, // duration in seconds
302- 30, // frames per second
303- 80, 24 // figure dimensions
339+ [](double t, double x) { return sin(x + t); },
340+ -PI, PI, // x range
341+ 10.0, // duration
342+ 30, // fps
343+ 80, 24, // width, height
344+ "cyan", // color
345+ "sin(x+t)" // legend label
304346 );
305347
306348 return 0;
307349}
308350```
309351
310- ** Parameters:**
311-
312- - ` f ` - Function ` f(t, x) ` where ` t ` is time and ` x ` is the variable
313- - ` x_min, x_max ` - X axis range
314- - ` duration ` - Animation duration in seconds (default: 10.0)
315- - ` fps ` - Frames per second (default: 30)
316- - ` width, height ` - Figure dimensions in characters (default: 80, 24)
317-
318- ** Features:**
319-
320- - Auto-scales Y axis by sampling over time
321- - Loops automatically when duration is exceeded
322- - Hides cursor during animation for clean display
323- - Press Ctrl+C to stop
324-
325352---
326353
327- ### Complex Animation with Dependencies ( ` animate ` )
354+ ### Multi-Plot Animation with Config
328355
329- The same ` animate ` function also supports functions with time-varying parameters :
356+ For multiple plots with full control :
330357
331358```cpp
332359#include <pythonic/pythonic.hpp>
333360using namespace pythonic::plot;
334361
335362int main() {
336- // f(t, x, a, b) = a * sin(x) + b * cos(t)
337- // where 'a' and 'b' are provided by dependency functions
338-
339- animate(
340- // Main function: receives t, x, and values from dependency functions
341- [](double t, double x, double a, double b) {
342- return a * sin(x) + b * cos(t);
343- },
344- -PI, PI, // x range
345- 10.0, 30, // duration, fps
346- 80, 24, // width, height
347- // Dependency functions - each takes t and returns a value
348- [](double t) { return 1.0 + 0.5 * sin(t); }, // -> a
349- [](double t) { return cos(2 * t); } // -> b
363+ // Configure the animation
364+ auto cfg = AnimateConfig()
365+ .x_range(-2 * M_PI, 2 * M_PI)
366+ .time(20.0)
367+ .framerate(24)
368+ .size_px(240, 140) // Pixel dimensions (converted to chars)
369+ .labels("cyan")
370+ .ranges("magenta")
371+ .set_title("Frequency Modulation Demo");
372+
373+ // Animate with multiple plots
374+ animate(cfg,
375+ // Each plot is a tuple: (function, color, label)
376+ std::make_tuple(
377+ [](double t, double x) {
378+ double w = 1.0 + 0.5 * std::sin(0.5 * t); // Varying frequency
379+ double amp = 1.0 + 0.3 * std::cos(0.8 * t); // Varying amplitude
380+ return amp * std::sin(w * t + x);
381+ },
382+ "red",
383+ "sin(w*t+x)*A"
384+ ),
385+ std::make_tuple(
386+ [](double t, double x) {
387+ double w = 1.0 + 0.5 * std::sin(0.5 * t);
388+ return std::cos(w * t + x);
389+ },
390+ "cyan",
391+ "cos(w*t+x)"
392+ ),
393+ std::make_tuple(
394+ [](double t, double x) {
395+ (void)x; // Envelope - doesn't depend on x
396+ return 1.0 + 0.3 * std::cos(0.8 * t);
397+ },
398+ "yellow",
399+ "envelope"
400+ )
350401 );
351402
352403 return 0;
353404}
354405```
355406
356- **Use cases :**
407+ ** Plot tuple format :**
357408
358- - Amplitude modulation: `a(t) * sin(x)` where `a` varies with time
359- - Frequency modulation: `sin(f(t) * x)` where frequency varies
360- - Multiple coupled oscillations
361- - Physics simulations with time-varying parameters
409+ - 2 elements: ` (function, color) `
410+ - 3 elements: ` (function, color, label) ` - label appears in legend
362411
363412---
364413
365- ### Multi-Plot Animation (`animate_plots`)
414+ ### Complete Animation Example
366415
367- Animate multiple functions simultaneously, each with its own color :
416+ Here's a comprehensive example demonstrating all features :
368417
369418``` cpp
370419#include < pythonic/pythonic.hpp>
420+ using namespace Pythonic ;
371421using namespace pythonic ::plot;
372422
373423int main() {
374- animate_plots(
375- -PI, PI, // x range
376- 10.0, 30, // duration, fps
377- 80, 24, // width, height
378- // Plot entries: std::make_tuple(function, color)
424+ print("=== Animated Plot Demo ===");
425+ print("Press Ctrl+C to stop");
426+
427+ // Configure with fluent API
428+ auto cfg = AnimateConfig()
429+ .x_range(-2 * M_PI, 2 * M_PI)
430+ .time(20.0)
431+ .framerate(24)
432+ .size_px(240, 140)
433+ .labels("cyan")
434+ .ranges("magenta")
435+ .set_title("Frequency Modulated Waves");
436+
437+ animate(cfg,
438+ // Amplitude-modulated sine wave
439+ std::make_tuple(
440+ [](double t, double x) -> double {
441+ double w = 1.0 + 0.5 * std::sin(0.5 * t);
442+ double amp = 1.0 + 0.3 * std::cos(0.8 * t);
443+ double phi = 0.1 * x * x; // Position-dependent phase
444+ return amp * std::sin(w * t + x + phi);
445+ },
446+ "red", "sin(w*t+x+φ)*A"
447+ ),
448+ // Cosine wave
379449 std::make_tuple(
380- [](double t, double x) { return sin(x + t); },
381- "cyan"
450+ [](double t, double x) -> double {
451+ double w = 1.0 + 0.5 * std::sin(0.5 * t);
452+ return std::cos(w * t + x);
453+ },
454+ "cyan", "cos(w*t+x)"
382455 ),
456+ // Upper envelope
383457 std::make_tuple(
384- [](double t, double x) { return cos(x - t); },
385- "yellow"
458+ [](double t, double x) -> double {
459+ (void)x;
460+ return 1.0 + 0.3 * std::cos(0.8 * t);
461+ },
462+ "yellow", "±Amplitude"
386463 ),
464+ // Lower envelope (no label)
387465 std::make_tuple(
388- [](double t, double x) { return sin(2*x + t) * 0.5; },
389- "magenta"
466+ [](double t, double x) -> double {
467+ (void)x;
468+ return -(1.0 + 0.3 * std::cos(0.8 * t));
469+ },
470+ "yellow", ""
390471 )
391472 );
392473
474+ print("Animation finished!");
393475 return 0;
394476}
395477```
396478
397- ** Features:**
479+ ---
480+
481+ ### Figure Class - Pixel Dimensions
482+
483+ You can also create figures with pixel dimensions:
484+
485+ ```cpp
486+ // Method 1: Factory function
487+ auto fig = Figure::from_pixels(320, 160); // 160×40 characters
488+
489+ // Method 2: Standard constructor (character dimensions)
490+ Figure fig(120, 35); // 120×35 characters = 240×140 pixels
491+ ```
492+
493+ ---
494+
495+ ### Animation Features
496+
497+ - ** Auto Y-scaling** : Y axis is automatically computed from function range
498+ - ** Looping** : Animation loops when duration is exceeded
499+ - ** Clean display** : Cursor is hidden during animation
500+ - ** Multi-color** : Each plot can have its own color and legend
501+ - ** Legends** : Labels appear in the legend area above the plot
502+ - ** Configurable colors** : Axis labels and range values can be customized
503+
504+ ---
505+
506+ ### Legacy Functions (Backward Compatibility)
507+
508+ For backward compatibility, these functions are still available:
509+
510+ ``` cpp
511+ // Legacy single-plot with dependency functions
512+ animate_legacy (f, x_min, x_max, duration, fps, width, height, deps...);
513+
514+ // Legacy multi-plot (still works)
515+ animate_plots(x_min, x_max, duration, fps, width, height, plots...);
516+ ```
398517
399- - Variadic - add as many plot functions as you want
400- - Each function gets its own color
401- - All share the same Y-axis scale (auto-computed)
518+ However, we recommend using the unified `animate()` function with `AnimateConfig` for new code.
402519
403520---
404521
0 commit comments