figrecipe 0.5.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 +1090 -0
- figrecipe/_recorder.py +435 -0
- figrecipe/_reproducer.py +358 -0
- figrecipe/_seaborn.py +305 -0
- figrecipe/_serializer.py +227 -0
- figrecipe/_signatures/__init__.py +7 -0
- figrecipe/_signatures/_loader.py +186 -0
- figrecipe/_utils/__init__.py +32 -0
- figrecipe/_utils/_crop.py +261 -0
- figrecipe/_utils/_diff.py +98 -0
- figrecipe/_utils/_image_diff.py +204 -0
- figrecipe/_utils/_numpy_io.py +204 -0
- figrecipe/_utils/_units.py +200 -0
- figrecipe/_validator.py +186 -0
- figrecipe/_wrappers/__init__.py +8 -0
- figrecipe/_wrappers/_axes.py +327 -0
- figrecipe/_wrappers/_figure.py +227 -0
- figrecipe/plt.py +12 -0
- figrecipe/pyplot.py +264 -0
- figrecipe/styles/__init__.py +50 -0
- figrecipe/styles/_style_applier.py +412 -0
- figrecipe/styles/_style_loader.py +450 -0
- figrecipe-0.5.0.dist-info/METADATA +336 -0
- figrecipe-0.5.0.dist-info/RECORD +26 -0
- figrecipe-0.5.0.dist-info/WHEEL +4 -0
- figrecipe-0.5.0.dist-info/licenses/LICENSE +661 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Wrapped Figure that manages recording."""
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, List, Literal, Optional, Tuple, Union, TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
import matplotlib.pyplot as plt
|
|
9
|
+
from matplotlib.figure import Figure
|
|
10
|
+
|
|
11
|
+
from ._axes import RecordingAxes
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from .._recorder import Recorder, FigureRecord
|
|
15
|
+
from .._utils._numpy_io import DataFormat
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class RecordingFigure:
|
|
19
|
+
"""Wrapper around matplotlib Figure that manages recording.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
fig : matplotlib.figure.Figure
|
|
24
|
+
The underlying matplotlib figure.
|
|
25
|
+
recorder : Recorder
|
|
26
|
+
The recorder instance.
|
|
27
|
+
axes : list of RecordingAxes
|
|
28
|
+
Wrapped axes objects.
|
|
29
|
+
|
|
30
|
+
Examples
|
|
31
|
+
--------
|
|
32
|
+
>>> import figrecipe as ps
|
|
33
|
+
>>> fig, ax = ps.subplots()
|
|
34
|
+
>>> ax.plot([1, 2, 3], [4, 5, 6])
|
|
35
|
+
>>> ps.save(fig, "my_figure.yaml")
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
fig: Figure,
|
|
41
|
+
recorder: "Recorder",
|
|
42
|
+
axes: Union[RecordingAxes, List[RecordingAxes]],
|
|
43
|
+
):
|
|
44
|
+
self._fig = fig
|
|
45
|
+
self._recorder = recorder
|
|
46
|
+
|
|
47
|
+
# Normalize axes to list
|
|
48
|
+
if isinstance(axes, RecordingAxes):
|
|
49
|
+
self._axes = [[axes]]
|
|
50
|
+
elif isinstance(axes, list):
|
|
51
|
+
if axes and isinstance(axes[0], list):
|
|
52
|
+
self._axes = axes
|
|
53
|
+
else:
|
|
54
|
+
self._axes = [axes]
|
|
55
|
+
else:
|
|
56
|
+
self._axes = [[axes]]
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def fig(self) -> Figure:
|
|
60
|
+
"""Get the underlying matplotlib figure."""
|
|
61
|
+
return self._fig
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def axes(self) -> List[List[RecordingAxes]]:
|
|
65
|
+
"""Get axes as 2D array."""
|
|
66
|
+
return self._axes
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def flat(self) -> List[RecordingAxes]:
|
|
70
|
+
"""Get flattened list of all axes."""
|
|
71
|
+
result = []
|
|
72
|
+
for row in self._axes:
|
|
73
|
+
for ax in row:
|
|
74
|
+
result.append(ax)
|
|
75
|
+
return result
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def record(self) -> "FigureRecord":
|
|
79
|
+
"""Get the figure record."""
|
|
80
|
+
return self._recorder.figure_record
|
|
81
|
+
|
|
82
|
+
def __getattr__(self, name: str) -> Any:
|
|
83
|
+
"""Delegate attribute access to underlying figure."""
|
|
84
|
+
return getattr(self._fig, name)
|
|
85
|
+
|
|
86
|
+
def savefig(
|
|
87
|
+
self,
|
|
88
|
+
fname,
|
|
89
|
+
save_recipe: bool = True,
|
|
90
|
+
recipe_format: Literal["csv", "npz", "inline"] = "csv",
|
|
91
|
+
**kwargs,
|
|
92
|
+
):
|
|
93
|
+
"""Save the figure image and optionally the recipe.
|
|
94
|
+
|
|
95
|
+
Parameters
|
|
96
|
+
----------
|
|
97
|
+
fname : str or Path
|
|
98
|
+
Output path for the image file.
|
|
99
|
+
save_recipe : bool
|
|
100
|
+
If True (default), also save a YAML recipe alongside the image.
|
|
101
|
+
Recipe will be saved with same name but .yaml extension.
|
|
102
|
+
recipe_format : str
|
|
103
|
+
Format for data in recipe: 'csv' (default), 'npz', or 'inline'.
|
|
104
|
+
**kwargs
|
|
105
|
+
Passed to matplotlib's savefig().
|
|
106
|
+
|
|
107
|
+
Returns
|
|
108
|
+
-------
|
|
109
|
+
Path or tuple
|
|
110
|
+
If save_recipe=False: image path.
|
|
111
|
+
If save_recipe=True: (image_path, recipe_path) tuple.
|
|
112
|
+
|
|
113
|
+
Examples
|
|
114
|
+
--------
|
|
115
|
+
>>> fig, ax = ps.subplots()
|
|
116
|
+
>>> ax.plot(x, y, id='data')
|
|
117
|
+
>>> fig.savefig('figure.png') # Saves both figure.png and figure.yaml
|
|
118
|
+
>>> fig.savefig('figure.png', save_recipe=False) # Image only
|
|
119
|
+
"""
|
|
120
|
+
# Handle file-like objects (BytesIO, etc.) - just pass through
|
|
121
|
+
if hasattr(fname, 'write'):
|
|
122
|
+
self._fig.savefig(fname, **kwargs)
|
|
123
|
+
return fname
|
|
124
|
+
|
|
125
|
+
fname = Path(fname)
|
|
126
|
+
self._fig.savefig(fname, **kwargs)
|
|
127
|
+
|
|
128
|
+
if save_recipe:
|
|
129
|
+
recipe_path = fname.with_suffix(".yaml")
|
|
130
|
+
self.save_recipe(recipe_path, include_data=True, data_format=recipe_format)
|
|
131
|
+
return fname, recipe_path
|
|
132
|
+
|
|
133
|
+
return fname
|
|
134
|
+
|
|
135
|
+
def save_recipe(
|
|
136
|
+
self,
|
|
137
|
+
path: Union[str, Path],
|
|
138
|
+
include_data: bool = True,
|
|
139
|
+
data_format: Literal["csv", "npz", "inline"] = "csv",
|
|
140
|
+
) -> Path:
|
|
141
|
+
"""Save the recording recipe to YAML.
|
|
142
|
+
|
|
143
|
+
Parameters
|
|
144
|
+
----------
|
|
145
|
+
path : str or Path
|
|
146
|
+
Output path for the recipe file.
|
|
147
|
+
include_data : bool
|
|
148
|
+
If True, save array data alongside recipe.
|
|
149
|
+
data_format : str
|
|
150
|
+
Format for data files: 'csv' (default), 'npz', or 'inline'.
|
|
151
|
+
|
|
152
|
+
Returns
|
|
153
|
+
-------
|
|
154
|
+
Path
|
|
155
|
+
Path to saved recipe file.
|
|
156
|
+
"""
|
|
157
|
+
from .._serializer import save_recipe
|
|
158
|
+
return save_recipe(self._recorder.figure_record, path, include_data, data_format)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def create_recording_subplots(
|
|
162
|
+
nrows: int = 1,
|
|
163
|
+
ncols: int = 1,
|
|
164
|
+
recorder: Optional["Recorder"] = None,
|
|
165
|
+
**kwargs,
|
|
166
|
+
) -> Tuple[RecordingFigure, Union[RecordingAxes, List[RecordingAxes]]]:
|
|
167
|
+
"""Create a figure with recording-enabled axes.
|
|
168
|
+
|
|
169
|
+
Parameters
|
|
170
|
+
----------
|
|
171
|
+
nrows : int
|
|
172
|
+
Number of rows.
|
|
173
|
+
ncols : int
|
|
174
|
+
Number of columns.
|
|
175
|
+
recorder : Recorder, optional
|
|
176
|
+
Recorder instance. Created if not provided.
|
|
177
|
+
**kwargs
|
|
178
|
+
Passed to plt.subplots().
|
|
179
|
+
|
|
180
|
+
Returns
|
|
181
|
+
-------
|
|
182
|
+
fig : RecordingFigure
|
|
183
|
+
Wrapped figure.
|
|
184
|
+
axes : RecordingAxes or list
|
|
185
|
+
Wrapped axes (single if 1x1, otherwise 2D array).
|
|
186
|
+
"""
|
|
187
|
+
from .._recorder import Recorder
|
|
188
|
+
|
|
189
|
+
if recorder is None:
|
|
190
|
+
recorder = Recorder()
|
|
191
|
+
|
|
192
|
+
# Create matplotlib figure
|
|
193
|
+
fig, mpl_axes = plt.subplots(nrows, ncols, **kwargs)
|
|
194
|
+
|
|
195
|
+
# Get figsize and dpi
|
|
196
|
+
figsize = kwargs.get("figsize", fig.get_size_inches())
|
|
197
|
+
dpi = kwargs.get("dpi", fig.dpi)
|
|
198
|
+
|
|
199
|
+
# Start recording
|
|
200
|
+
recorder.start_figure(figsize=tuple(figsize), dpi=int(dpi))
|
|
201
|
+
|
|
202
|
+
# Wrap axes
|
|
203
|
+
if nrows == 1 and ncols == 1:
|
|
204
|
+
wrapped_ax = RecordingAxes(mpl_axes, recorder, position=(0, 0))
|
|
205
|
+
wrapped_fig = RecordingFigure(fig, recorder, wrapped_ax)
|
|
206
|
+
return wrapped_fig, wrapped_ax
|
|
207
|
+
|
|
208
|
+
# Handle 1D or 2D arrays
|
|
209
|
+
import numpy as np
|
|
210
|
+
mpl_axes = np.atleast_2d(mpl_axes)
|
|
211
|
+
|
|
212
|
+
wrapped_axes = []
|
|
213
|
+
for i in range(mpl_axes.shape[0]):
|
|
214
|
+
row = []
|
|
215
|
+
for j in range(mpl_axes.shape[1]):
|
|
216
|
+
row.append(RecordingAxes(mpl_axes[i, j], recorder, position=(i, j)))
|
|
217
|
+
wrapped_axes.append(row)
|
|
218
|
+
|
|
219
|
+
wrapped_fig = RecordingFigure(fig, recorder, wrapped_axes)
|
|
220
|
+
|
|
221
|
+
# Return in same shape as matplotlib
|
|
222
|
+
if nrows == 1:
|
|
223
|
+
return wrapped_fig, wrapped_axes[0]
|
|
224
|
+
elif ncols == 1:
|
|
225
|
+
return wrapped_fig, [row[0] for row in wrapped_axes]
|
|
226
|
+
else:
|
|
227
|
+
return wrapped_fig, wrapped_axes
|
figrecipe/plt.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Alias for figrecipe.pyplot - drop-in replacement for matplotlib.pyplot.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
import figrecipe.plt as plt # Short form
|
|
7
|
+
# or
|
|
8
|
+
import figrecipe.pyplot as plt # Full form
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from .pyplot import * # noqa: F401, F403
|
|
12
|
+
from .pyplot import __all__
|
figrecipe/pyplot.py
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Drop-in replacement for matplotlib.pyplot with recording capabilities.
|
|
4
|
+
|
|
5
|
+
This module provides a convenient way to use figrecipe as a direct replacement
|
|
6
|
+
for matplotlib.pyplot. Simply change your import statement:
|
|
7
|
+
|
|
8
|
+
# Before (standard matplotlib)
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
|
|
11
|
+
# After (figrecipe with recording)
|
|
12
|
+
import figrecipe.pyplot as plt
|
|
13
|
+
|
|
14
|
+
All your existing code will work unchanged, but figures created with
|
|
15
|
+
plt.subplots() will automatically have recording capabilities.
|
|
16
|
+
|
|
17
|
+
Examples
|
|
18
|
+
--------
|
|
19
|
+
>>> import figrecipe.pyplot as plt
|
|
20
|
+
>>> import numpy as np
|
|
21
|
+
>>>
|
|
22
|
+
>>> x = np.linspace(0, 10, 100)
|
|
23
|
+
>>> y = np.sin(x)
|
|
24
|
+
>>>
|
|
25
|
+
>>> fig, ax = plt.subplots() # Recording-enabled
|
|
26
|
+
>>> ax.plot(x, y, color='red', id='sine_wave')
|
|
27
|
+
>>> fig.save_recipe('my_figure.yaml') # Save as recipe
|
|
28
|
+
>>>
|
|
29
|
+
>>> # All other pyplot functions work as usual
|
|
30
|
+
>>> plt.show()
|
|
31
|
+
>>> plt.savefig('output.png')
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
import matplotlib.pyplot as _plt
|
|
35
|
+
from matplotlib.pyplot import * # noqa: F401, F403
|
|
36
|
+
|
|
37
|
+
# Import figrecipe functionality
|
|
38
|
+
from . import subplots as _ps_subplots
|
|
39
|
+
from . import save as _ps_save
|
|
40
|
+
from ._wrappers import RecordingFigure
|
|
41
|
+
|
|
42
|
+
# Override subplots with recording-enabled version
|
|
43
|
+
subplots = _ps_subplots
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def figure(*args, **kwargs):
|
|
47
|
+
"""Create a new figure with optional recording support.
|
|
48
|
+
|
|
49
|
+
This is a pass-through to matplotlib.pyplot.figure().
|
|
50
|
+
For recording support, use subplots() instead.
|
|
51
|
+
|
|
52
|
+
Parameters
|
|
53
|
+
----------
|
|
54
|
+
*args, **kwargs
|
|
55
|
+
Arguments passed to matplotlib.pyplot.figure().
|
|
56
|
+
|
|
57
|
+
Returns
|
|
58
|
+
-------
|
|
59
|
+
matplotlib.figure.Figure
|
|
60
|
+
The created figure.
|
|
61
|
+
"""
|
|
62
|
+
return _plt.figure(*args, **kwargs)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def save(fig, path, **kwargs):
|
|
66
|
+
"""Save a figure (recipe for RecordingFigure, or standard save).
|
|
67
|
+
|
|
68
|
+
Parameters
|
|
69
|
+
----------
|
|
70
|
+
fig : RecordingFigure or Figure
|
|
71
|
+
Figure to save. If RecordingFigure, saves as recipe.
|
|
72
|
+
Otherwise, saves as image using savefig().
|
|
73
|
+
path : str or Path
|
|
74
|
+
Output path. Use .yaml for recipe format.
|
|
75
|
+
**kwargs
|
|
76
|
+
Additional arguments for save.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
Path or tuple
|
|
81
|
+
Saved path (and ValidationResult if validate=True).
|
|
82
|
+
"""
|
|
83
|
+
if isinstance(fig, RecordingFigure):
|
|
84
|
+
return _ps_save(fig, path, **kwargs)
|
|
85
|
+
else:
|
|
86
|
+
fig.savefig(path, **kwargs)
|
|
87
|
+
return path
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# Expose commonly used functions explicitly for IDE support
|
|
91
|
+
show = _plt.show
|
|
92
|
+
savefig = _plt.savefig
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def close(fig=None):
|
|
96
|
+
"""Close a figure window.
|
|
97
|
+
|
|
98
|
+
Parameters
|
|
99
|
+
----------
|
|
100
|
+
fig : None, int, str, Figure, or RecordingFigure
|
|
101
|
+
The figure to close. See matplotlib.pyplot.close() for details.
|
|
102
|
+
RecordingFigure is automatically unwrapped to the underlying Figure.
|
|
103
|
+
"""
|
|
104
|
+
if isinstance(fig, RecordingFigure):
|
|
105
|
+
_plt.close(fig.fig)
|
|
106
|
+
else:
|
|
107
|
+
_plt.close(fig)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
clf = _plt.clf
|
|
111
|
+
cla = _plt.cla
|
|
112
|
+
gcf = _plt.gcf
|
|
113
|
+
gca = _plt.gca
|
|
114
|
+
subplot = _plt.subplot
|
|
115
|
+
tight_layout = _plt.tight_layout
|
|
116
|
+
suptitle = _plt.suptitle
|
|
117
|
+
xlabel = _plt.xlabel
|
|
118
|
+
ylabel = _plt.ylabel
|
|
119
|
+
title = _plt.title
|
|
120
|
+
legend = _plt.legend
|
|
121
|
+
xlim = _plt.xlim
|
|
122
|
+
ylim = _plt.ylim
|
|
123
|
+
grid = _plt.grid
|
|
124
|
+
plot = _plt.plot
|
|
125
|
+
scatter = _plt.scatter
|
|
126
|
+
bar = _plt.bar
|
|
127
|
+
hist = _plt.hist
|
|
128
|
+
imshow = _plt.imshow
|
|
129
|
+
contour = _plt.contour
|
|
130
|
+
contourf = _plt.contourf
|
|
131
|
+
colorbar = _plt.colorbar
|
|
132
|
+
axhline = _plt.axhline
|
|
133
|
+
axvline = _plt.axvline
|
|
134
|
+
text = _plt.text
|
|
135
|
+
annotate = _plt.annotate
|
|
136
|
+
fill_between = _plt.fill_between
|
|
137
|
+
errorbar = _plt.errorbar
|
|
138
|
+
boxplot = _plt.boxplot
|
|
139
|
+
violinplot = _plt.violinplot
|
|
140
|
+
pie = _plt.pie
|
|
141
|
+
stem = _plt.stem
|
|
142
|
+
step = _plt.step
|
|
143
|
+
stackplot = _plt.stackplot
|
|
144
|
+
streamplot = _plt.streamplot
|
|
145
|
+
quiver = _plt.quiver
|
|
146
|
+
barbs = _plt.barbs
|
|
147
|
+
hexbin = _plt.hexbin
|
|
148
|
+
pcolormesh = _plt.pcolormesh
|
|
149
|
+
tripcolor = _plt.tripcolor
|
|
150
|
+
tricontour = _plt.tricontour
|
|
151
|
+
tricontourf = _plt.tricontourf
|
|
152
|
+
spy = _plt.spy
|
|
153
|
+
matshow = _plt.matshow
|
|
154
|
+
specgram = _plt.specgram
|
|
155
|
+
psd = _plt.psd
|
|
156
|
+
csd = _plt.csd
|
|
157
|
+
cohere = _plt.cohere
|
|
158
|
+
magnitude_spectrum = _plt.magnitude_spectrum
|
|
159
|
+
angle_spectrum = _plt.angle_spectrum
|
|
160
|
+
phase_spectrum = _plt.phase_spectrum
|
|
161
|
+
xcorr = _plt.xcorr
|
|
162
|
+
acorr = _plt.acorr
|
|
163
|
+
semilogy = _plt.semilogy
|
|
164
|
+
semilogx = _plt.semilogx
|
|
165
|
+
loglog = _plt.loglog
|
|
166
|
+
polar = _plt.polar
|
|
167
|
+
subplot2grid = _plt.subplot2grid
|
|
168
|
+
subplot_mosaic = _plt.subplot_mosaic
|
|
169
|
+
subplots_adjust = _plt.subplots_adjust
|
|
170
|
+
rc = _plt.rc
|
|
171
|
+
rcdefaults = _plt.rcdefaults
|
|
172
|
+
rcParams = _plt.rcParams
|
|
173
|
+
style = _plt.style
|
|
174
|
+
cm = _plt.cm
|
|
175
|
+
get_cmap = _plt.get_cmap
|
|
176
|
+
colormaps = _plt.colormaps
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
__all__ = [
|
|
180
|
+
# Core functions (recording-enabled)
|
|
181
|
+
"subplots",
|
|
182
|
+
"figure",
|
|
183
|
+
"save",
|
|
184
|
+
# Display
|
|
185
|
+
"show",
|
|
186
|
+
"savefig",
|
|
187
|
+
"close",
|
|
188
|
+
"clf",
|
|
189
|
+
"cla",
|
|
190
|
+
# Getters
|
|
191
|
+
"gcf",
|
|
192
|
+
"gca",
|
|
193
|
+
# Layout
|
|
194
|
+
"subplot",
|
|
195
|
+
"subplot2grid",
|
|
196
|
+
"subplot_mosaic",
|
|
197
|
+
"subplots_adjust",
|
|
198
|
+
"tight_layout",
|
|
199
|
+
# Labels and titles
|
|
200
|
+
"suptitle",
|
|
201
|
+
"xlabel",
|
|
202
|
+
"ylabel",
|
|
203
|
+
"title",
|
|
204
|
+
"legend",
|
|
205
|
+
# Limits
|
|
206
|
+
"xlim",
|
|
207
|
+
"ylim",
|
|
208
|
+
# Grid
|
|
209
|
+
"grid",
|
|
210
|
+
# Plot types
|
|
211
|
+
"plot",
|
|
212
|
+
"scatter",
|
|
213
|
+
"bar",
|
|
214
|
+
"hist",
|
|
215
|
+
"imshow",
|
|
216
|
+
"contour",
|
|
217
|
+
"contourf",
|
|
218
|
+
"colorbar",
|
|
219
|
+
"axhline",
|
|
220
|
+
"axvline",
|
|
221
|
+
"text",
|
|
222
|
+
"annotate",
|
|
223
|
+
"fill_between",
|
|
224
|
+
"errorbar",
|
|
225
|
+
"boxplot",
|
|
226
|
+
"violinplot",
|
|
227
|
+
"pie",
|
|
228
|
+
"stem",
|
|
229
|
+
"step",
|
|
230
|
+
"stackplot",
|
|
231
|
+
"streamplot",
|
|
232
|
+
"quiver",
|
|
233
|
+
"barbs",
|
|
234
|
+
"hexbin",
|
|
235
|
+
"pcolormesh",
|
|
236
|
+
"tripcolor",
|
|
237
|
+
"tricontour",
|
|
238
|
+
"tricontourf",
|
|
239
|
+
"spy",
|
|
240
|
+
"matshow",
|
|
241
|
+
"specgram",
|
|
242
|
+
"psd",
|
|
243
|
+
"csd",
|
|
244
|
+
"cohere",
|
|
245
|
+
"magnitude_spectrum",
|
|
246
|
+
"angle_spectrum",
|
|
247
|
+
"phase_spectrum",
|
|
248
|
+
"xcorr",
|
|
249
|
+
"acorr",
|
|
250
|
+
# Log scale
|
|
251
|
+
"semilogy",
|
|
252
|
+
"semilogx",
|
|
253
|
+
"loglog",
|
|
254
|
+
"polar",
|
|
255
|
+
# Configuration
|
|
256
|
+
"rc",
|
|
257
|
+
"rcdefaults",
|
|
258
|
+
"rcParams",
|
|
259
|
+
"style",
|
|
260
|
+
# Colormaps
|
|
261
|
+
"cm",
|
|
262
|
+
"get_cmap",
|
|
263
|
+
"colormaps",
|
|
264
|
+
]
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Style management for figrecipe.
|
|
4
|
+
|
|
5
|
+
Provides style loading, application, and management for publication-quality figures.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
from figrecipe.styles import load_style, STYLE
|
|
9
|
+
|
|
10
|
+
# Load default style
|
|
11
|
+
style = load_style()
|
|
12
|
+
|
|
13
|
+
# Access style parameters
|
|
14
|
+
print(style.axes.width_mm)
|
|
15
|
+
print(style.fonts.axis_label_pt)
|
|
16
|
+
|
|
17
|
+
# Use with subplots
|
|
18
|
+
fig, ax = ps.subplots(**style.to_subplots_kwargs())
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from ._style_loader import (
|
|
22
|
+
load_style,
|
|
23
|
+
unload_style,
|
|
24
|
+
get_style,
|
|
25
|
+
reload_style,
|
|
26
|
+
list_presets,
|
|
27
|
+
STYLE,
|
|
28
|
+
to_subplots_kwargs,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
from ._style_applier import (
|
|
32
|
+
apply_style_mm,
|
|
33
|
+
apply_theme_colors,
|
|
34
|
+
check_font,
|
|
35
|
+
list_available_fonts,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"load_style",
|
|
40
|
+
"unload_style",
|
|
41
|
+
"get_style",
|
|
42
|
+
"reload_style",
|
|
43
|
+
"list_presets",
|
|
44
|
+
"STYLE",
|
|
45
|
+
"to_subplots_kwargs",
|
|
46
|
+
"apply_style_mm",
|
|
47
|
+
"apply_theme_colors",
|
|
48
|
+
"check_font",
|
|
49
|
+
"list_available_fonts",
|
|
50
|
+
]
|