figrecipe 0.5.0__py3-none-any.whl → 0.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. figrecipe/__init__.py +361 -93
  2. figrecipe/_dev/__init__.py +120 -0
  3. figrecipe/_dev/demo_plotters/__init__.py +195 -0
  4. figrecipe/_dev/demo_plotters/plot_acorr.py +24 -0
  5. figrecipe/_dev/demo_plotters/plot_angle_spectrum.py +28 -0
  6. figrecipe/_dev/demo_plotters/plot_bar.py +25 -0
  7. figrecipe/_dev/demo_plotters/plot_barbs.py +30 -0
  8. figrecipe/_dev/demo_plotters/plot_barh.py +25 -0
  9. figrecipe/_dev/demo_plotters/plot_boxplot.py +24 -0
  10. figrecipe/_dev/demo_plotters/plot_cohere.py +29 -0
  11. figrecipe/_dev/demo_plotters/plot_contour.py +30 -0
  12. figrecipe/_dev/demo_plotters/plot_contourf.py +29 -0
  13. figrecipe/_dev/demo_plotters/plot_csd.py +29 -0
  14. figrecipe/_dev/demo_plotters/plot_ecdf.py +24 -0
  15. figrecipe/_dev/demo_plotters/plot_errorbar.py +28 -0
  16. figrecipe/_dev/demo_plotters/plot_eventplot.py +25 -0
  17. figrecipe/_dev/demo_plotters/plot_fill.py +29 -0
  18. figrecipe/_dev/demo_plotters/plot_fill_between.py +30 -0
  19. figrecipe/_dev/demo_plotters/plot_fill_betweenx.py +28 -0
  20. figrecipe/_dev/demo_plotters/plot_hexbin.py +25 -0
  21. figrecipe/_dev/demo_plotters/plot_hist.py +24 -0
  22. figrecipe/_dev/demo_plotters/plot_hist2d.py +25 -0
  23. figrecipe/_dev/demo_plotters/plot_imshow.py +23 -0
  24. figrecipe/_dev/demo_plotters/plot_loglog.py +27 -0
  25. figrecipe/_dev/demo_plotters/plot_magnitude_spectrum.py +28 -0
  26. figrecipe/_dev/demo_plotters/plot_matshow.py +23 -0
  27. figrecipe/_dev/demo_plotters/plot_pcolor.py +29 -0
  28. figrecipe/_dev/demo_plotters/plot_pcolormesh.py +29 -0
  29. figrecipe/_dev/demo_plotters/plot_phase_spectrum.py +28 -0
  30. figrecipe/_dev/demo_plotters/plot_pie.py +23 -0
  31. figrecipe/_dev/demo_plotters/plot_plot.py +27 -0
  32. figrecipe/_dev/demo_plotters/plot_psd.py +29 -0
  33. figrecipe/_dev/demo_plotters/plot_quiver.py +30 -0
  34. figrecipe/_dev/demo_plotters/plot_scatter.py +24 -0
  35. figrecipe/_dev/demo_plotters/plot_semilogx.py +27 -0
  36. figrecipe/_dev/demo_plotters/plot_semilogy.py +27 -0
  37. figrecipe/_dev/demo_plotters/plot_specgram.py +30 -0
  38. figrecipe/_dev/demo_plotters/plot_spy.py +29 -0
  39. figrecipe/_dev/demo_plotters/plot_stackplot.py +29 -0
  40. figrecipe/_dev/demo_plotters/plot_stairs.py +27 -0
  41. figrecipe/_dev/demo_plotters/plot_stem.py +27 -0
  42. figrecipe/_dev/demo_plotters/plot_step.py +27 -0
  43. figrecipe/_dev/demo_plotters/plot_streamplot.py +30 -0
  44. figrecipe/_dev/demo_plotters/plot_tricontour.py +28 -0
  45. figrecipe/_dev/demo_plotters/plot_tricontourf.py +28 -0
  46. figrecipe/_dev/demo_plotters/plot_tripcolor.py +29 -0
  47. figrecipe/_dev/demo_plotters/plot_triplot.py +25 -0
  48. figrecipe/_dev/demo_plotters/plot_violinplot.py +25 -0
  49. figrecipe/_dev/demo_plotters/plot_xcorr.py +25 -0
  50. figrecipe/_editor/__init__.py +230 -0
  51. figrecipe/_editor/_bbox.py +978 -0
  52. figrecipe/_editor/_flask_app.py +1229 -0
  53. figrecipe/_editor/_hitmap.py +937 -0
  54. figrecipe/_editor/_overrides.py +318 -0
  55. figrecipe/_editor/_renderer.py +349 -0
  56. figrecipe/_editor/_templates/__init__.py +75 -0
  57. figrecipe/_editor/_templates/_html.py +406 -0
  58. figrecipe/_editor/_templates/_scripts.py +2778 -0
  59. figrecipe/_editor/_templates/_styles.py +1326 -0
  60. figrecipe/_params/_DECORATION_METHODS.py +27 -0
  61. figrecipe/_params/_PLOTTING_METHODS.py +58 -0
  62. figrecipe/_params/__init__.py +9 -0
  63. figrecipe/_recorder.py +126 -73
  64. figrecipe/_reproducer.py +658 -41
  65. figrecipe/_seaborn.py +14 -9
  66. figrecipe/_serializer.py +2 -2
  67. figrecipe/_signatures/README.md +68 -0
  68. figrecipe/_signatures/__init__.py +12 -2
  69. figrecipe/_signatures/_loader.py +515 -56
  70. figrecipe/_utils/__init__.py +6 -4
  71. figrecipe/_utils/_crop.py +10 -4
  72. figrecipe/_utils/_image_diff.py +37 -33
  73. figrecipe/_utils/_numpy_io.py +0 -1
  74. figrecipe/_utils/_units.py +11 -3
  75. figrecipe/_validator.py +12 -3
  76. figrecipe/_wrappers/_axes.py +860 -46
  77. figrecipe/_wrappers/_figure.py +115 -18
  78. figrecipe/plt.py +0 -1
  79. figrecipe/pyplot.py +2 -1
  80. figrecipe/styles/__init__.py +9 -10
  81. figrecipe/styles/_style_applier.py +332 -28
  82. figrecipe/styles/_style_loader.py +172 -44
  83. figrecipe/styles/presets/MATPLOTLIB.yaml +94 -0
  84. figrecipe/styles/presets/SCITEX.yaml +176 -0
  85. figrecipe-0.6.0.dist-info/METADATA +394 -0
  86. figrecipe-0.6.0.dist-info/RECORD +90 -0
  87. figrecipe-0.5.0.dist-info/METADATA +0 -336
  88. figrecipe-0.5.0.dist-info/RECORD +0 -26
  89. {figrecipe-0.5.0.dist-info → figrecipe-0.6.0.dist-info}/WHEEL +0 -0
  90. {figrecipe-0.5.0.dist-info → figrecipe-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Development utilities for figrecipe.
4
+
5
+ Provides demo plotters for all supported matplotlib plotting methods.
6
+ All plotters follow signature: (plt, rng, ax=None) -> (fig, ax)
7
+
8
+ Usage:
9
+ import figrecipe as fr
10
+ from figrecipe._dev import PLOTTERS, run_all_demos
11
+
12
+ # Run a single demo
13
+ fig, ax = PLOTTERS["plot"](fr, np.random.default_rng(42))
14
+
15
+ # Run all demos
16
+ results = run_all_demos(fr, output_dir="./outputs")
17
+ """
18
+
19
+ import importlib
20
+ from pathlib import Path
21
+
22
+ from .._params import PLOTTING_METHODS
23
+
24
+ # Auto-import plotters from demo_plotters directory
25
+ _demo_dir = Path(__file__).parent / "demo_plotters"
26
+ PLOTTERS = {}
27
+
28
+ for method_name in sorted(PLOTTING_METHODS):
29
+ module_name = f"plot_{method_name}"
30
+ func_name = f"plot_{method_name}"
31
+ module_path = _demo_dir / f"{module_name}.py"
32
+
33
+ if module_path.exists():
34
+ try:
35
+ module = importlib.import_module(
36
+ f".demo_plotters.{module_name}", package="figrecipe._dev"
37
+ )
38
+ if hasattr(module, func_name):
39
+ PLOTTERS[method_name] = getattr(module, func_name)
40
+ except ImportError:
41
+ pass
42
+
43
+
44
+ def list_plotters():
45
+ """List all available plotter names."""
46
+ return list(PLOTTERS.keys())
47
+
48
+
49
+ def get_plotter(name):
50
+ """Get a plotter function by name.
51
+
52
+ Parameters
53
+ ----------
54
+ name : str
55
+ Name of the plotting method (e.g., 'plot', 'scatter').
56
+
57
+ Returns
58
+ -------
59
+ callable
60
+ The plotter function with signature (plt, rng, ax=None) -> (fig, ax).
61
+ """
62
+ if name in PLOTTERS:
63
+ return PLOTTERS[name]
64
+ raise KeyError(f"Unknown plotter: {name}. Available: {list(PLOTTERS.keys())}")
65
+
66
+
67
+ def run_all_demos(plt, output_dir=None, show=False):
68
+ """Run all demo plotters and optionally save outputs.
69
+
70
+ Parameters
71
+ ----------
72
+ plt : module
73
+ figrecipe module (e.g., `import figrecipe as fr`).
74
+ output_dir : Path or str, optional
75
+ Directory to save output images.
76
+ show : bool
77
+ Whether to show figures interactively.
78
+
79
+ Returns
80
+ -------
81
+ dict
82
+ Results for each demo: {name: {'success': bool, 'error': str or None}}
83
+ """
84
+ import matplotlib.pyplot as _plt
85
+ import numpy as np
86
+
87
+ rng = np.random.default_rng(42)
88
+ results = {}
89
+
90
+ if output_dir:
91
+ output_dir = Path(output_dir)
92
+ output_dir.mkdir(parents=True, exist_ok=True)
93
+
94
+ for name, func in PLOTTERS.items():
95
+ try:
96
+ fig, ax = func(plt, rng)
97
+ if output_dir:
98
+ out_path = output_dir / f"plot_{name}.png"
99
+ mpl_fig = fig.fig if hasattr(fig, "fig") else fig
100
+ mpl_fig.savefig(out_path, dpi=100, bbox_inches="tight")
101
+ if show:
102
+ _plt.show()
103
+ else:
104
+ mpl_fig = fig.fig if hasattr(fig, "fig") else fig
105
+ _plt.close(mpl_fig)
106
+ results[name] = {"success": True, "error": None}
107
+ except Exception as e:
108
+ results[name] = {"success": False, "error": str(e)}
109
+
110
+ return results
111
+
112
+
113
+ __all__ = [
114
+ "PLOTTERS",
115
+ "list_plotters",
116
+ "get_plotter",
117
+ "run_all_demos",
118
+ ]
119
+
120
+ # EOF
@@ -0,0 +1,195 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Demo plotters registry for all supported figrecipe plotting methods.
4
+
5
+ Usage
6
+ -----
7
+ >>> from figrecipe._dev.demo_plotters import REGISTRY, create_all_plots_figure
8
+ >>>
9
+ >>> # List all available plot types
10
+ >>> print(list(REGISTRY.keys()))
11
+ >>>
12
+ >>> # Create a single figure with all plot types
13
+ >>> fig, axes = create_all_plots_figure(fr)
14
+ >>>
15
+ >>> # Run individual plotter
16
+ >>> fig, ax = REGISTRY['plot'](fr, rng, ax)
17
+ """
18
+
19
+ import importlib
20
+ import math
21
+ from pathlib import Path
22
+ from typing import Callable, Dict, Optional, Tuple
23
+
24
+ import numpy as np
25
+
26
+ # Registry: plot_name -> plotter function
27
+ REGISTRY: Dict[str, Callable] = {}
28
+
29
+ # Get all plot_*.py files in this directory
30
+ _demo_dir = Path(__file__).parent
31
+ _demo_files = sorted(_demo_dir.glob("plot_*.py"))
32
+
33
+ # Import all demo functions into registry
34
+ for _file in _demo_files:
35
+ _module_name = _file.stem # e.g., plot_scatter
36
+ _plot_name = _module_name.replace("plot_", "") # e.g., scatter
37
+ _func_name = _module_name # e.g., plot_scatter
38
+ try:
39
+ _module = importlib.import_module(f".{_module_name}", package=__name__)
40
+ if hasattr(_module, _func_name):
41
+ REGISTRY[_plot_name] = getattr(_module, _func_name)
42
+ except ImportError as e:
43
+ print(f"Warning: Could not import {_module_name}: {e}")
44
+
45
+
46
+ def list_plots():
47
+ """List all available plot types.
48
+
49
+ Returns
50
+ -------
51
+ list of str
52
+ Names of available plot types.
53
+ """
54
+ return list(REGISTRY.keys())
55
+
56
+
57
+ def get_plotter(name: str) -> Optional[Callable]:
58
+ """Get plotter function by name.
59
+
60
+ Parameters
61
+ ----------
62
+ name : str
63
+ Plot type name (e.g., 'scatter', 'bar', 'hist').
64
+
65
+ Returns
66
+ -------
67
+ callable or None
68
+ Plotter function or None if not found.
69
+ """
70
+ return REGISTRY.get(name)
71
+
72
+
73
+ def create_all_plots_figure(plt, seed: int = 42) -> Tuple:
74
+ """Create a single figure with all supported plot types.
75
+
76
+ Parameters
77
+ ----------
78
+ plt : module
79
+ figrecipe module (import figrecipe as fr).
80
+ seed : int
81
+ Random seed for reproducibility.
82
+
83
+ Returns
84
+ -------
85
+ tuple
86
+ (fig, axes) where fig is RecordingFigure and axes is array of RecordingAxes.
87
+ """
88
+ rng = np.random.default_rng(seed)
89
+
90
+ n_plots = len(REGISTRY)
91
+ ncols = 7
92
+ nrows = math.ceil(n_plots / ncols)
93
+
94
+ fig, axes = plt.subplots(nrows=nrows, ncols=ncols)
95
+ axes_flat = axes.flatten()
96
+
97
+ results = {}
98
+ for i, (name, plotter) in enumerate(REGISTRY.items()):
99
+ ax = axes_flat[i]
100
+ try:
101
+ plotter(plt, rng, ax=ax)
102
+ results[name] = {"success": True, "error": None}
103
+ except Exception as e:
104
+ ax.set_title(f"{name}\n(ERROR)")
105
+ ax.text(
106
+ 0.5,
107
+ 0.5,
108
+ str(e)[:50],
109
+ ha="center",
110
+ va="center",
111
+ transform=ax.transAxes,
112
+ fontsize=6,
113
+ wrap=True,
114
+ )
115
+ results[name] = {"success": False, "error": str(e)}
116
+
117
+ # Hide unused axes
118
+ for i in range(n_plots, len(axes_flat)):
119
+ axes_flat[i].set_visible(False)
120
+
121
+ # Add panel labels
122
+ panel_labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" * 2 # 52 labels
123
+ for i, ax in enumerate(axes_flat[:n_plots]):
124
+ if i < len(panel_labels):
125
+ plt.panel_label(ax, panel_labels[i])
126
+
127
+ fig.suptitle(f"All {n_plots} Supported Plot Types")
128
+
129
+ return fig, axes, results
130
+
131
+
132
+ def run_individual_demos(plt, output_dir=None, show=False):
133
+ """Run all demo plotters individually and optionally save outputs.
134
+
135
+ Parameters
136
+ ----------
137
+ plt : module
138
+ figrecipe or matplotlib.pyplot module.
139
+ output_dir : Path, optional
140
+ Directory to save output images.
141
+ show : bool
142
+ Whether to show figures.
143
+
144
+ Returns
145
+ -------
146
+ dict
147
+ Results for each demo: {name: {'success': bool, 'error': str or None}}
148
+ """
149
+ rng = np.random.default_rng(42)
150
+ results = {}
151
+
152
+ if output_dir:
153
+ output_dir = Path(output_dir)
154
+ output_dir.mkdir(parents=True, exist_ok=True)
155
+
156
+ for name, plotter in REGISTRY.items():
157
+ try:
158
+ fig, ax = plotter(plt, rng)
159
+ if output_dir:
160
+ out_path = output_dir / f"plot_{name}.png"
161
+ if hasattr(fig, "fig"):
162
+ fig.fig.savefig(out_path, dpi=100, bbox_inches="tight")
163
+ else:
164
+ fig.savefig(out_path, dpi=100, bbox_inches="tight")
165
+ if show:
166
+ plt.show()
167
+ else:
168
+ if hasattr(fig, "fig"):
169
+ plt.close(fig.fig)
170
+ else:
171
+ plt.close(fig)
172
+ results[name] = {"success": True, "error": None}
173
+ except Exception as e:
174
+ results[name] = {"success": False, "error": str(e)}
175
+
176
+ return results
177
+
178
+
179
+ # Legacy exports for backwards compatibility
180
+ __all__ = [f"plot_{name}" for name in REGISTRY.keys()]
181
+ for _name, _func in REGISTRY.items():
182
+ globals()[f"plot_{_name}"] = _func
183
+
184
+
185
+ def list_demos():
186
+ """Legacy: List all available demo functions."""
187
+ return __all__
188
+
189
+
190
+ def run_all_demos(plt, output_dir=None, show=False):
191
+ """Legacy: Alias for run_individual_demos."""
192
+ return run_individual_demos(plt, output_dir, show)
193
+
194
+
195
+ # EOF
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """acorr: autocorrelation demo."""
4
+
5
+
6
+ def plot_acorr(plt, rng, ax=None):
7
+ """Autocorrelation demo.
8
+
9
+ Demonstrates: ax.acorr()
10
+ """
11
+ if ax is None:
12
+ fig, ax = plt.subplots()
13
+ else:
14
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
15
+
16
+ x = rng.normal(0, 1, 100)
17
+ ax.acorr(x, maxlags=50, id="acorr")
18
+ ax.set_xlabel("Lag")
19
+ ax.set_ylabel("Autocorrelation")
20
+ ax.set_title("acorr")
21
+ return fig, ax
22
+
23
+
24
+ # EOF
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """angle_spectrum: phase angle spectrum demo."""
4
+
5
+ import numpy as np
6
+
7
+
8
+ def plot_angle_spectrum(plt, rng, ax=None):
9
+ """Phase angle spectrum demo.
10
+
11
+ Demonstrates: ax.angle_spectrum()
12
+ """
13
+ if ax is None:
14
+ fig, ax = plt.subplots()
15
+ else:
16
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
17
+
18
+ fs = 1000
19
+ t = np.linspace(0, 1, fs)
20
+ signal = np.sin(2 * np.pi * 50 * t) + 0.5 * np.sin(2 * np.pi * 120 * t + np.pi / 3)
21
+ ax.angle_spectrum(signal, Fs=fs, id="angle_spectrum")
22
+ ax.set_xlabel("Frequency")
23
+ ax.set_ylabel("Phase (radians)")
24
+ ax.set_title("angle_spectrum")
25
+ return fig, ax
26
+
27
+
28
+ # EOF
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """bar: bar chart demo."""
4
+
5
+
6
+ def plot_bar(plt, rng, ax=None):
7
+ """Bar chart demo.
8
+
9
+ Demonstrates: ax.bar()
10
+ """
11
+ if ax is None:
12
+ fig, ax = plt.subplots()
13
+ else:
14
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
15
+
16
+ categories = ["A", "B", "C", "D", "E"]
17
+ values = rng.integers(1, 10, 5)
18
+ ax.bar(categories, values, id="bar")
19
+ ax.set_xlabel("Category")
20
+ ax.set_ylabel("Value")
21
+ ax.set_title("bar")
22
+ return fig, ax
23
+
24
+
25
+ # EOF
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """barbs: wind barbs demo."""
4
+
5
+ import numpy as np
6
+
7
+
8
+ def plot_barbs(plt, rng, ax=None):
9
+ """Wind barbs demo.
10
+
11
+ Demonstrates: ax.barbs()
12
+ """
13
+ if ax is None:
14
+ fig, ax = plt.subplots()
15
+ else:
16
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
17
+
18
+ x = np.arange(0, 5, 1)
19
+ y = np.arange(0, 5, 1)
20
+ X, Y = np.meshgrid(x, y)
21
+ U = rng.uniform(-10, 10, X.shape)
22
+ V = rng.uniform(-10, 10, Y.shape)
23
+ ax.barbs(X, Y, U, V, id="barbs")
24
+ ax.set_xlabel("X")
25
+ ax.set_ylabel("Y")
26
+ ax.set_title("barbs")
27
+ return fig, ax
28
+
29
+
30
+ # EOF
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """barh: horizontal bar chart demo."""
4
+
5
+
6
+ def plot_barh(plt, rng, ax=None):
7
+ """Horizontal bar chart demo.
8
+
9
+ Demonstrates: ax.barh()
10
+ """
11
+ if ax is None:
12
+ fig, ax = plt.subplots()
13
+ else:
14
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
15
+
16
+ categories = ["A", "B", "C", "D", "E"]
17
+ values = rng.integers(1, 10, 5)
18
+ ax.barh(categories, values, id="barh")
19
+ ax.set_xlabel("Value")
20
+ ax.set_ylabel("Category")
21
+ ax.set_title("barh")
22
+ return fig, ax
23
+
24
+
25
+ # EOF
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """boxplot: box plot demo."""
4
+
5
+
6
+ def plot_boxplot(plt, rng, ax=None):
7
+ """Box plot demo.
8
+
9
+ Demonstrates: ax.boxplot()
10
+ """
11
+ if ax is None:
12
+ fig, ax = plt.subplots()
13
+ else:
14
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
15
+
16
+ data = [rng.normal(i, 1, 100) for i in range(4)]
17
+ ax.boxplot(data, tick_labels=["A", "B", "C", "D"], id="boxplot")
18
+ ax.set_xlabel("Group")
19
+ ax.set_ylabel("Value")
20
+ ax.set_title("boxplot")
21
+ return fig, ax
22
+
23
+
24
+ # EOF
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """cohere: coherence demo."""
4
+
5
+ import numpy as np
6
+
7
+
8
+ def plot_cohere(plt, rng, ax=None):
9
+ """Coherence demo.
10
+
11
+ Demonstrates: ax.cohere()
12
+ """
13
+ if ax is None:
14
+ fig, ax = plt.subplots()
15
+ else:
16
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
17
+
18
+ fs = 1000
19
+ t = np.linspace(0, 1, fs)
20
+ x = np.sin(2 * np.pi * 50 * t) + rng.normal(0, 0.3, len(t))
21
+ y = np.sin(2 * np.pi * 50 * t + np.pi / 4) + rng.normal(0, 0.3, len(t))
22
+ ax.cohere(x, y, Fs=fs, id="cohere")
23
+ ax.set_xlabel("Frequency")
24
+ ax.set_ylabel("Coherence")
25
+ ax.set_title("cohere")
26
+ return fig, ax
27
+
28
+
29
+ # EOF
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """contour: contour plot demo."""
4
+
5
+ import numpy as np
6
+
7
+
8
+ def plot_contour(plt, rng, ax=None):
9
+ """Contour plot demo.
10
+
11
+ Demonstrates: ax.contour()
12
+ """
13
+ if ax is None:
14
+ fig, ax = plt.subplots()
15
+ else:
16
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
17
+
18
+ x = np.linspace(-3, 3, 50)
19
+ y = np.linspace(-3, 3, 50)
20
+ X, Y = np.meshgrid(x, y)
21
+ Z = np.exp(-(X**2 + Y**2))
22
+ cs = ax.contour(X, Y, Z, id="contour")
23
+ ax.clabel(cs)
24
+ ax.set_xlabel("X")
25
+ ax.set_ylabel("Y")
26
+ ax.set_title("contour")
27
+ return fig, ax
28
+
29
+
30
+ # EOF
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """contourf: filled contour plot demo."""
4
+
5
+ import numpy as np
6
+
7
+
8
+ def plot_contourf(plt, rng, ax=None):
9
+ """Filled contour plot demo.
10
+
11
+ Demonstrates: ax.contourf()
12
+ """
13
+ if ax is None:
14
+ fig, ax = plt.subplots()
15
+ else:
16
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
17
+
18
+ x = np.linspace(-3, 3, 50)
19
+ y = np.linspace(-3, 3, 50)
20
+ X, Y = np.meshgrid(x, y)
21
+ Z = np.exp(-(X**2 + Y**2))
22
+ ax.contourf(X, Y, Z, id="contourf")
23
+ ax.set_xlabel("X")
24
+ ax.set_ylabel("Y")
25
+ ax.set_title("contourf")
26
+ return fig, ax
27
+
28
+
29
+ # EOF
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """csd: cross spectral density demo."""
4
+
5
+ import numpy as np
6
+
7
+
8
+ def plot_csd(plt, rng, ax=None):
9
+ """Cross spectral density demo.
10
+
11
+ Demonstrates: ax.csd()
12
+ """
13
+ if ax is None:
14
+ fig, ax = plt.subplots()
15
+ else:
16
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
17
+
18
+ fs = 1000
19
+ t = np.linspace(0, 1, fs)
20
+ x = np.sin(2 * np.pi * 50 * t) + rng.normal(0, 0.3, len(t))
21
+ y = np.sin(2 * np.pi * 50 * t + np.pi / 4) + rng.normal(0, 0.3, len(t))
22
+ ax.csd(x, y, Fs=fs, id="csd")
23
+ ax.set_xlabel("Frequency")
24
+ ax.set_ylabel("CSD")
25
+ ax.set_title("csd")
26
+ return fig, ax
27
+
28
+
29
+ # EOF
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """ecdf: empirical CDF demo."""
4
+
5
+
6
+ def plot_ecdf(plt, rng, ax=None):
7
+ """Empirical CDF demo.
8
+
9
+ Demonstrates: ax.ecdf()
10
+ """
11
+ if ax is None:
12
+ fig, ax = plt.subplots()
13
+ else:
14
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
15
+
16
+ data = rng.normal(0, 1, 100)
17
+ ax.ecdf(data, id="ecdf")
18
+ ax.set_xlabel("Value")
19
+ ax.set_ylabel("Cumulative Probability")
20
+ ax.set_title("ecdf")
21
+ return fig, ax
22
+
23
+
24
+ # EOF
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """errorbar: error bar plot demo."""
4
+
5
+ import numpy as np
6
+
7
+
8
+ def plot_errorbar(plt, rng, ax=None):
9
+ """Error bar plot demo.
10
+
11
+ Demonstrates: ax.errorbar()
12
+ """
13
+ if ax is None:
14
+ fig, ax = plt.subplots()
15
+ else:
16
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
17
+
18
+ x = np.arange(5)
19
+ y = rng.uniform(2, 8, 5)
20
+ yerr = rng.uniform(0.3, 0.8, 5)
21
+ ax.errorbar(x, y, yerr=yerr, id="errorbar")
22
+ ax.set_xlabel("X")
23
+ ax.set_ylabel("Y")
24
+ ax.set_title("errorbar")
25
+ return fig, ax
26
+
27
+
28
+ # EOF
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """eventplot: event/spike raster demo."""
4
+
5
+
6
+ def plot_eventplot(plt, rng, ax=None):
7
+ """Event/spike raster demo.
8
+
9
+ Demonstrates: ax.eventplot()
10
+ """
11
+ if ax is None:
12
+ fig, ax = plt.subplots()
13
+ else:
14
+ fig = ax.get_figure() if hasattr(ax, "get_figure") else ax.fig
15
+
16
+ # Multiple event sequences
17
+ events = [rng.uniform(0, 10, 20) for _ in range(5)]
18
+ ax.eventplot(events, id="eventplot")
19
+ ax.set_xlabel("Time")
20
+ ax.set_ylabel("Channel")
21
+ ax.set_title("eventplot")
22
+ return fig, ax
23
+
24
+
25
+ # EOF