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.
- figrecipe/__init__.py +361 -93
- figrecipe/_dev/__init__.py +120 -0
- figrecipe/_dev/demo_plotters/__init__.py +195 -0
- figrecipe/_dev/demo_plotters/plot_acorr.py +24 -0
- figrecipe/_dev/demo_plotters/plot_angle_spectrum.py +28 -0
- figrecipe/_dev/demo_plotters/plot_bar.py +25 -0
- figrecipe/_dev/demo_plotters/plot_barbs.py +30 -0
- figrecipe/_dev/demo_plotters/plot_barh.py +25 -0
- figrecipe/_dev/demo_plotters/plot_boxplot.py +24 -0
- figrecipe/_dev/demo_plotters/plot_cohere.py +29 -0
- figrecipe/_dev/demo_plotters/plot_contour.py +30 -0
- figrecipe/_dev/demo_plotters/plot_contourf.py +29 -0
- figrecipe/_dev/demo_plotters/plot_csd.py +29 -0
- figrecipe/_dev/demo_plotters/plot_ecdf.py +24 -0
- figrecipe/_dev/demo_plotters/plot_errorbar.py +28 -0
- figrecipe/_dev/demo_plotters/plot_eventplot.py +25 -0
- figrecipe/_dev/demo_plotters/plot_fill.py +29 -0
- figrecipe/_dev/demo_plotters/plot_fill_between.py +30 -0
- figrecipe/_dev/demo_plotters/plot_fill_betweenx.py +28 -0
- figrecipe/_dev/demo_plotters/plot_hexbin.py +25 -0
- figrecipe/_dev/demo_plotters/plot_hist.py +24 -0
- figrecipe/_dev/demo_plotters/plot_hist2d.py +25 -0
- figrecipe/_dev/demo_plotters/plot_imshow.py +23 -0
- figrecipe/_dev/demo_plotters/plot_loglog.py +27 -0
- figrecipe/_dev/demo_plotters/plot_magnitude_spectrum.py +28 -0
- figrecipe/_dev/demo_plotters/plot_matshow.py +23 -0
- figrecipe/_dev/demo_plotters/plot_pcolor.py +29 -0
- figrecipe/_dev/demo_plotters/plot_pcolormesh.py +29 -0
- figrecipe/_dev/demo_plotters/plot_phase_spectrum.py +28 -0
- figrecipe/_dev/demo_plotters/plot_pie.py +23 -0
- figrecipe/_dev/demo_plotters/plot_plot.py +27 -0
- figrecipe/_dev/demo_plotters/plot_psd.py +29 -0
- figrecipe/_dev/demo_plotters/plot_quiver.py +30 -0
- figrecipe/_dev/demo_plotters/plot_scatter.py +24 -0
- figrecipe/_dev/demo_plotters/plot_semilogx.py +27 -0
- figrecipe/_dev/demo_plotters/plot_semilogy.py +27 -0
- figrecipe/_dev/demo_plotters/plot_specgram.py +30 -0
- figrecipe/_dev/demo_plotters/plot_spy.py +29 -0
- figrecipe/_dev/demo_plotters/plot_stackplot.py +29 -0
- figrecipe/_dev/demo_plotters/plot_stairs.py +27 -0
- figrecipe/_dev/demo_plotters/plot_stem.py +27 -0
- figrecipe/_dev/demo_plotters/plot_step.py +27 -0
- figrecipe/_dev/demo_plotters/plot_streamplot.py +30 -0
- figrecipe/_dev/demo_plotters/plot_tricontour.py +28 -0
- figrecipe/_dev/demo_plotters/plot_tricontourf.py +28 -0
- figrecipe/_dev/demo_plotters/plot_tripcolor.py +29 -0
- figrecipe/_dev/demo_plotters/plot_triplot.py +25 -0
- figrecipe/_dev/demo_plotters/plot_violinplot.py +25 -0
- figrecipe/_dev/demo_plotters/plot_xcorr.py +25 -0
- figrecipe/_editor/__init__.py +230 -0
- figrecipe/_editor/_bbox.py +978 -0
- figrecipe/_editor/_flask_app.py +1229 -0
- figrecipe/_editor/_hitmap.py +937 -0
- figrecipe/_editor/_overrides.py +318 -0
- figrecipe/_editor/_renderer.py +349 -0
- figrecipe/_editor/_templates/__init__.py +75 -0
- figrecipe/_editor/_templates/_html.py +406 -0
- figrecipe/_editor/_templates/_scripts.py +2778 -0
- figrecipe/_editor/_templates/_styles.py +1326 -0
- figrecipe/_params/_DECORATION_METHODS.py +27 -0
- figrecipe/_params/_PLOTTING_METHODS.py +58 -0
- figrecipe/_params/__init__.py +9 -0
- figrecipe/_recorder.py +126 -73
- figrecipe/_reproducer.py +658 -41
- figrecipe/_seaborn.py +14 -9
- figrecipe/_serializer.py +2 -2
- figrecipe/_signatures/README.md +68 -0
- figrecipe/_signatures/__init__.py +12 -2
- figrecipe/_signatures/_loader.py +515 -56
- figrecipe/_utils/__init__.py +6 -4
- figrecipe/_utils/_crop.py +10 -4
- figrecipe/_utils/_image_diff.py +37 -33
- figrecipe/_utils/_numpy_io.py +0 -1
- figrecipe/_utils/_units.py +11 -3
- figrecipe/_validator.py +12 -3
- figrecipe/_wrappers/_axes.py +860 -46
- figrecipe/_wrappers/_figure.py +115 -18
- figrecipe/plt.py +0 -1
- figrecipe/pyplot.py +2 -1
- figrecipe/styles/__init__.py +9 -10
- figrecipe/styles/_style_applier.py +332 -28
- figrecipe/styles/_style_loader.py +172 -44
- figrecipe/styles/presets/MATPLOTLIB.yaml +94 -0
- figrecipe/styles/presets/SCITEX.yaml +176 -0
- figrecipe-0.6.0.dist-info/METADATA +394 -0
- figrecipe-0.6.0.dist-info/RECORD +90 -0
- figrecipe-0.5.0.dist-info/METADATA +0 -336
- figrecipe-0.5.0.dist-info/RECORD +0 -26
- {figrecipe-0.5.0.dist-info → figrecipe-0.6.0.dist-info}/WHEEL +0 -0
- {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
|