sane-figs 0.1.0__tar.gz

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 (33) hide show
  1. sane_figs-0.1.0/LICENSE +21 -0
  2. sane_figs-0.1.0/PKG-INFO +221 -0
  3. sane_figs-0.1.0/README.md +155 -0
  4. sane_figs-0.1.0/pyproject.toml +143 -0
  5. sane_figs-0.1.0/sane_figs/__init__.py +568 -0
  6. sane_figs-0.1.0/sane_figs/adapters/__init__.py +5 -0
  7. sane_figs-0.1.0/sane_figs/adapters/altair.py +458 -0
  8. sane_figs-0.1.0/sane_figs/adapters/base.py +120 -0
  9. sane_figs-0.1.0/sane_figs/adapters/matplotlib.py +344 -0
  10. sane_figs-0.1.0/sane_figs/adapters/plotly.py +444 -0
  11. sane_figs-0.1.0/sane_figs/adapters/seaborn.py +345 -0
  12. sane_figs-0.1.0/sane_figs/core/__init__.py +18 -0
  13. sane_figs-0.1.0/sane_figs/core/config_discovery.py +166 -0
  14. sane_figs-0.1.0/sane_figs/core/discovery.py +210 -0
  15. sane_figs-0.1.0/sane_figs/core/presets.py +339 -0
  16. sane_figs-0.1.0/sane_figs/core/registry.py +153 -0
  17. sane_figs-0.1.0/sane_figs/core/setup.py +268 -0
  18. sane_figs-0.1.0/sane_figs/core/validation.py +377 -0
  19. sane_figs-0.1.0/sane_figs/core/yaml_parser.py +649 -0
  20. sane_figs-0.1.0/sane_figs/styling/__init__.py +33 -0
  21. sane_figs-0.1.0/sane_figs/styling/colorways.py +512 -0
  22. sane_figs-0.1.0/sane_figs/styling/watermarks.py +211 -0
  23. sane_figs-0.1.0/sane_figs/utils/__init__.py +5 -0
  24. sane_figs-0.1.0/sane_figs/utils/version_utils.py +47 -0
  25. sane_figs-0.1.0/sane_figs.egg-info/PKG-INFO +221 -0
  26. sane_figs-0.1.0/sane_figs.egg-info/SOURCES.txt +31 -0
  27. sane_figs-0.1.0/sane_figs.egg-info/dependency_links.txt +1 -0
  28. sane_figs-0.1.0/sane_figs.egg-info/requires.txt +48 -0
  29. sane_figs-0.1.0/sane_figs.egg-info/top_level.txt +1 -0
  30. sane_figs-0.1.0/setup.cfg +4 -0
  31. sane_figs-0.1.0/tests/test_colorways.py +145 -0
  32. sane_figs-0.1.0/tests/test_presets.py +62 -0
  33. sane_figs-0.1.0/tests/test_watermarks.py +131 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Jean-David T.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,221 @@
1
+ Metadata-Version: 2.4
2
+ Name: sane-figs
3
+ Version: 0.1.0
4
+ Summary: Publication-ready figures for Matplotlib, Seaborn, Plotly, and Altair
5
+ Author-email: "Jean-David T." <jeandavid@example.com>
6
+ Maintainer-email: "Jean-David T." <jeandavid@example.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/jeandavidt/sane-figs
9
+ Project-URL: Documentation, https://sane-figs.readthedocs.io
10
+ Project-URL: Repository, https://github.com/jeandavidt/sane-figs
11
+ Project-URL: Issues, https://github.com/jeandavidt/sane-figs/issues
12
+ Keywords: visualization,matplotlib,seaborn,plotly,altair,publication,figures,plotting,scientific,research
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Intended Audience :: Education
16
+ Classifier: Topic :: Scientific/Engineering :: Visualization
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: importlib-metadata; python_version < "3.8"
28
+ Requires-Dist: Pillow>=9.0.0
29
+ Requires-Dist: PyYAML>=6.0
30
+ Provides-Extra: matplotlib
31
+ Requires-Dist: matplotlib>=2.0.0; extra == "matplotlib"
32
+ Provides-Extra: seaborn
33
+ Requires-Dist: seaborn>=0.9.0; extra == "seaborn"
34
+ Requires-Dist: matplotlib>=2.0.0; extra == "seaborn"
35
+ Provides-Extra: plotly
36
+ Requires-Dist: altair>=5.4.1; extra == "plotly"
37
+ Requires-Dist: pandas>=2.0.3; extra == "plotly"
38
+ Requires-Dist: plotly>=4.0.0; extra == "plotly"
39
+ Provides-Extra: altair
40
+ Requires-Dist: altair>=3.0.0; extra == "altair"
41
+ Provides-Extra: all
42
+ Requires-Dist: matplotlib>=2.0.0; extra == "all"
43
+ Requires-Dist: seaborn>=0.9.0; extra == "all"
44
+ Requires-Dist: plotly>=4.0.0; extra == "all"
45
+ Requires-Dist: altair>=3.0.0; extra == "all"
46
+ Provides-Extra: dev
47
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
48
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
49
+ Requires-Dist: pytest-regressions>=2.5.0; extra == "dev"
50
+ Requires-Dist: pytest-xdist>=3.0.0; extra == "dev"
51
+ Requires-Dist: packaging>=23.0.0; extra == "dev"
52
+ Requires-Dist: black>=23.0.0; extra == "dev"
53
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
54
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
55
+ Provides-Extra: test
56
+ Requires-Dist: pytest>=7.0.0; extra == "test"
57
+ Requires-Dist: pytest-cov>=4.0.0; extra == "test"
58
+ Requires-Dist: pytest-regressions>=2.5.0; extra == "test"
59
+ Requires-Dist: pytest-xdist>=3.0.0; extra == "test"
60
+ Requires-Dist: packaging>=23.0.0; extra == "test"
61
+ Requires-Dist: pandas>=1.0.0; extra == "test"
62
+ Provides-Extra: docs
63
+ Requires-Dist: mkdocs>=1.5.0; extra == "docs"
64
+ Requires-Dist: pymdown-extensions>=10.0; extra == "docs"
65
+ Dynamic: license-file
66
+
67
+ # Sane-Figs
68
+
69
+ Publication-ready figures for Matplotlib, Seaborn, Plotly, and Altair.
70
+
71
+ ## Overview
72
+
73
+ Sane-Figs is a Python package that automatically applies publication-ready styling to figures generated with popular Python visualization libraries. It solves the common problem of figures having text that is too small for articles and presentations.
74
+
75
+ ## Features
76
+
77
+ - **Automatic Styling**: Apply publication-ready defaults with a single function call
78
+ - **Multiple Libraries**: Support for Matplotlib, Seaborn, Plotly, and Altair
79
+ - **Version-Aware**: Automatically detects library versions and adapts to API changes
80
+ - **Two Usage Modes**: Global setup or context manager for scoped styling
81
+ - **Presets**: Built-in presets for articles and presentations
82
+ - **Colorways**: Publication-ready color palettes (default, nature, vibrant, pastel, colorblind-safe)
83
+ - **Watermarks**: Text and image watermark support
84
+
85
+ ## Installation
86
+
87
+ ```bash
88
+ pip install sane-figs
89
+ ```
90
+
91
+ For full library support:
92
+
93
+ ```bash
94
+ pip install sane-figs[all]
95
+ ```
96
+
97
+ Or install with specific libraries:
98
+
99
+ ```bash
100
+ pip install sane-figs[matplotlib,seaborn]
101
+ ```
102
+
103
+ ## Quick Start
104
+
105
+ ### Global Setup
106
+
107
+ ```python
108
+ import sane_figs
109
+ import matplotlib.pyplot as plt
110
+
111
+ # Apply publication defaults globally
112
+ sane_figs.setup(mode='article')
113
+
114
+ # Your existing code works as-is
115
+ plt.plot([1, 2, 3], [1, 4, 9])
116
+ plt.title('My Figure')
117
+ plt.xlabel('X Axis')
118
+ plt.ylabel('Y Axis')
119
+ plt.savefig('figure.png', dpi=300)
120
+ ```
121
+
122
+ ### Context Manager
123
+
124
+ ```python
125
+ import sane_figs
126
+ import matplotlib.pyplot as plt
127
+
128
+ # Scoped styling
129
+ with sane_figs.publication_style(mode='article'):
130
+ plt.plot([1, 2, 3], [1, 4, 9])
131
+ plt.title('My Figure')
132
+ plt.savefig('figure.png')
133
+
134
+ # Styling resets after context
135
+ plt.plot([1, 2, 3], [1, 4, 9]) # Back to default styling
136
+ ```
137
+
138
+ ### With Colorways
139
+
140
+ ```python
141
+ import sane_figs
142
+ import matplotlib.pyplot as plt
143
+
144
+ # Apply colorway
145
+ sane_figs.setup(mode='article', colorway='nature')
146
+
147
+ # List available colorways
148
+ print(sane_figs.list_colorways())
149
+ # ['default', 'nature', 'vibrant', 'pastel', 'colorblind-safe']
150
+ ```
151
+
152
+ ### With Watermarks
153
+
154
+ ```python
155
+ import sane_figs
156
+ import matplotlib.pyplot as plt
157
+
158
+ # Text watermark
159
+ sane_figs.setup(mode='article', watermark='© 2025 My Lab')
160
+
161
+ # Image watermark
162
+ sane_figs.setup(
163
+ mode='article',
164
+ watermark=sane_figs.create_image_watermark('logo.png', opacity=0.2)
165
+ )
166
+ ```
167
+
168
+ ## Presets
169
+
170
+ ### Article Mode
171
+
172
+ Optimized for print publication:
173
+ - Figure size: (6.4, 4.8) inches
174
+ - DPI: 300
175
+ - Title: 14pt
176
+ - Axis labels: 12pt
177
+ - Legend: 10pt
178
+ - Tick labels: 10pt
179
+
180
+ ### Presentation Mode
181
+
182
+ Optimized for slides:
183
+ - Figure size: (10, 7.5) inches
184
+ - DPI: 150
185
+ - Title: 24pt
186
+ - Axis labels: 20pt
187
+ - Legend: 16pt
188
+ - Tick labels: 16pt
189
+
190
+ ## Colorways
191
+
192
+ - **default**: Publication-ready palette optimized for print
193
+ - **nature**: Earth tones inspired by nature
194
+ - **vibrant**: High contrast colors for presentations
195
+ - **pastel**: Soft, professional colors
196
+ - **colorblind-safe**: Designed for colorblind accessibility
197
+
198
+ ## API Reference
199
+
200
+ ### Main Functions
201
+
202
+ - `setup(mode='article', libraries=None, colorway=None, watermark=None)` - Apply publication defaults globally
203
+ - `publication_style(mode='article', libraries=None, colorway=None, watermark=None)` - Context manager for scoped styling
204
+ - `list_colorways()` - List available colorways
205
+ - `create_text_watermark(text, **kwargs)` - Create a text watermark configuration
206
+ - `create_image_watermark(image_path, **kwargs)` - Create an image watermark configuration
207
+
208
+ ### Per-Library Functions
209
+
210
+ - `setup_matplotlib(mode='article', colorway=None, watermark=None)`
211
+ - `setup_seaborn(mode='article', colorway=None, watermark=None)`
212
+ - `setup_plotly(mode='article', colorway=None, watermark=None)`
213
+ - `setup_altair(mode='article', colorway=None, watermark=None)`
214
+
215
+ ## License
216
+
217
+ MIT License - see LICENSE file for details.
218
+
219
+ ## Contributing
220
+
221
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,155 @@
1
+ # Sane-Figs
2
+
3
+ Publication-ready figures for Matplotlib, Seaborn, Plotly, and Altair.
4
+
5
+ ## Overview
6
+
7
+ Sane-Figs is a Python package that automatically applies publication-ready styling to figures generated with popular Python visualization libraries. It solves the common problem of figures having text that is too small for articles and presentations.
8
+
9
+ ## Features
10
+
11
+ - **Automatic Styling**: Apply publication-ready defaults with a single function call
12
+ - **Multiple Libraries**: Support for Matplotlib, Seaborn, Plotly, and Altair
13
+ - **Version-Aware**: Automatically detects library versions and adapts to API changes
14
+ - **Two Usage Modes**: Global setup or context manager for scoped styling
15
+ - **Presets**: Built-in presets for articles and presentations
16
+ - **Colorways**: Publication-ready color palettes (default, nature, vibrant, pastel, colorblind-safe)
17
+ - **Watermarks**: Text and image watermark support
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pip install sane-figs
23
+ ```
24
+
25
+ For full library support:
26
+
27
+ ```bash
28
+ pip install sane-figs[all]
29
+ ```
30
+
31
+ Or install with specific libraries:
32
+
33
+ ```bash
34
+ pip install sane-figs[matplotlib,seaborn]
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ### Global Setup
40
+
41
+ ```python
42
+ import sane_figs
43
+ import matplotlib.pyplot as plt
44
+
45
+ # Apply publication defaults globally
46
+ sane_figs.setup(mode='article')
47
+
48
+ # Your existing code works as-is
49
+ plt.plot([1, 2, 3], [1, 4, 9])
50
+ plt.title('My Figure')
51
+ plt.xlabel('X Axis')
52
+ plt.ylabel('Y Axis')
53
+ plt.savefig('figure.png', dpi=300)
54
+ ```
55
+
56
+ ### Context Manager
57
+
58
+ ```python
59
+ import sane_figs
60
+ import matplotlib.pyplot as plt
61
+
62
+ # Scoped styling
63
+ with sane_figs.publication_style(mode='article'):
64
+ plt.plot([1, 2, 3], [1, 4, 9])
65
+ plt.title('My Figure')
66
+ plt.savefig('figure.png')
67
+
68
+ # Styling resets after context
69
+ plt.plot([1, 2, 3], [1, 4, 9]) # Back to default styling
70
+ ```
71
+
72
+ ### With Colorways
73
+
74
+ ```python
75
+ import sane_figs
76
+ import matplotlib.pyplot as plt
77
+
78
+ # Apply colorway
79
+ sane_figs.setup(mode='article', colorway='nature')
80
+
81
+ # List available colorways
82
+ print(sane_figs.list_colorways())
83
+ # ['default', 'nature', 'vibrant', 'pastel', 'colorblind-safe']
84
+ ```
85
+
86
+ ### With Watermarks
87
+
88
+ ```python
89
+ import sane_figs
90
+ import matplotlib.pyplot as plt
91
+
92
+ # Text watermark
93
+ sane_figs.setup(mode='article', watermark='© 2025 My Lab')
94
+
95
+ # Image watermark
96
+ sane_figs.setup(
97
+ mode='article',
98
+ watermark=sane_figs.create_image_watermark('logo.png', opacity=0.2)
99
+ )
100
+ ```
101
+
102
+ ## Presets
103
+
104
+ ### Article Mode
105
+
106
+ Optimized for print publication:
107
+ - Figure size: (6.4, 4.8) inches
108
+ - DPI: 300
109
+ - Title: 14pt
110
+ - Axis labels: 12pt
111
+ - Legend: 10pt
112
+ - Tick labels: 10pt
113
+
114
+ ### Presentation Mode
115
+
116
+ Optimized for slides:
117
+ - Figure size: (10, 7.5) inches
118
+ - DPI: 150
119
+ - Title: 24pt
120
+ - Axis labels: 20pt
121
+ - Legend: 16pt
122
+ - Tick labels: 16pt
123
+
124
+ ## Colorways
125
+
126
+ - **default**: Publication-ready palette optimized for print
127
+ - **nature**: Earth tones inspired by nature
128
+ - **vibrant**: High contrast colors for presentations
129
+ - **pastel**: Soft, professional colors
130
+ - **colorblind-safe**: Designed for colorblind accessibility
131
+
132
+ ## API Reference
133
+
134
+ ### Main Functions
135
+
136
+ - `setup(mode='article', libraries=None, colorway=None, watermark=None)` - Apply publication defaults globally
137
+ - `publication_style(mode='article', libraries=None, colorway=None, watermark=None)` - Context manager for scoped styling
138
+ - `list_colorways()` - List available colorways
139
+ - `create_text_watermark(text, **kwargs)` - Create a text watermark configuration
140
+ - `create_image_watermark(image_path, **kwargs)` - Create an image watermark configuration
141
+
142
+ ### Per-Library Functions
143
+
144
+ - `setup_matplotlib(mode='article', colorway=None, watermark=None)`
145
+ - `setup_seaborn(mode='article', colorway=None, watermark=None)`
146
+ - `setup_plotly(mode='article', colorway=None, watermark=None)`
147
+ - `setup_altair(mode='article', colorway=None, watermark=None)`
148
+
149
+ ## License
150
+
151
+ MIT License - see LICENSE file for details.
152
+
153
+ ## Contributing
154
+
155
+ Contributions are welcome! Please feel free to submit a Pull Request.
@@ -0,0 +1,143 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sane-figs"
7
+ version = "0.1.0"
8
+ description = "Publication-ready figures for Matplotlib, Seaborn, Plotly, and Altair"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ authors = [
12
+ {name = "Jean-David T.", email = "jeandavid@example.com"}
13
+ ]
14
+ maintainers = [
15
+ {name = "Jean-David T.", email = "jeandavid@example.com"}
16
+ ]
17
+ keywords = [
18
+ "visualization",
19
+ "matplotlib",
20
+ "seaborn",
21
+ "plotly",
22
+ "altair",
23
+ "publication",
24
+ "figures",
25
+ "plotting",
26
+ "scientific",
27
+ "research"
28
+ ]
29
+ classifiers = [
30
+ "Development Status :: 3 - Alpha",
31
+ "Intended Audience :: Science/Research",
32
+ "Intended Audience :: Education",
33
+ "Topic :: Scientific/Engineering :: Visualization",
34
+ "License :: OSI Approved :: MIT License",
35
+ "Programming Language :: Python :: 3",
36
+ "Programming Language :: Python :: 3.8",
37
+ "Programming Language :: Python :: 3.9",
38
+ "Programming Language :: Python :: 3.10",
39
+ "Programming Language :: Python :: 3.11",
40
+ "Programming Language :: Python :: 3.12",
41
+ ]
42
+ requires-python = ">=3.8"
43
+ dependencies = [
44
+ "importlib-metadata; python_version < '3.8'",
45
+ "Pillow>=9.0.0",
46
+ "PyYAML>=6.0",
47
+ ]
48
+
49
+ [project.optional-dependencies]
50
+ matplotlib = ["matplotlib>=2.0.0"]
51
+ seaborn = ["seaborn>=0.9.0", "matplotlib>=2.0.0"]
52
+ plotly = [
53
+ "altair>=5.4.1",
54
+ "pandas>=2.0.3",
55
+ "plotly>=4.0.0",
56
+ ]
57
+ altair = ["altair>=3.0.0"]
58
+ all = [
59
+ "matplotlib>=2.0.0",
60
+ "seaborn>=0.9.0",
61
+ "plotly>=4.0.0",
62
+ "altair>=3.0.0",
63
+ ]
64
+ dev = [
65
+ "pytest>=7.0.0",
66
+ "pytest-cov>=4.0.0",
67
+ "pytest-regressions>=2.5.0",
68
+ "pytest-xdist>=3.0.0",
69
+ "packaging>=23.0.0",
70
+ "black>=23.0.0",
71
+ "ruff>=0.1.0",
72
+ "mypy>=1.0.0",
73
+ ]
74
+ test = [
75
+ "pytest>=7.0.0",
76
+ "pytest-cov>=4.0.0",
77
+ "pytest-regressions>=2.5.0",
78
+ "pytest-xdist>=3.0.0",
79
+ "packaging>=23.0.0",
80
+ "pandas>=1.0.0",
81
+ ]
82
+ docs = [
83
+ "mkdocs>=1.5.0",
84
+ "pymdown-extensions>=10.0",
85
+ ]
86
+
87
+ [project.urls]
88
+ Homepage = "https://github.com/jeandavidt/sane-figs"
89
+ Documentation = "https://sane-figs.readthedocs.io"
90
+ Repository = "https://github.com/jeandavidt/sane-figs"
91
+ Issues = "https://github.com/jeandavidt/sane-figs/issues"
92
+
93
+ [tool.setuptools.packages.find]
94
+ where = ["."]
95
+ include = ["sane_figs*"]
96
+
97
+ [tool.black]
98
+ line-length = 100
99
+ target-version = ['py38', 'py39', 'py310', 'py311', 'py312']
100
+
101
+ [tool.ruff]
102
+ line-length = 100
103
+ select = ["E", "F", "I", "N", "W", "UP"]
104
+ ignore = ["E501"]
105
+
106
+ [tool.mypy]
107
+ python_version = "3.8"
108
+ warn_return_any = true
109
+ warn_unused_configs = true
110
+ disallow_untyped_defs = false
111
+
112
+ [tool.pytest.ini_options]
113
+ testpaths = ["tests"]
114
+ python_files = ["test_*.py"]
115
+ python_classes = ["Test*"]
116
+ python_functions = ["test_*"]
117
+ addopts = "-v --cov=sane_figs --cov-report=term-missing --strict-markers"
118
+ markers = [
119
+ "visual: marks tests as visual regression tests",
120
+ "matplotlib_min: tests for matplotlib minimum version (2.0.x)",
121
+ "matplotlib_3_0: tests for matplotlib 3.0+",
122
+ "matplotlib_3_5: tests for matplotlib 3.5+",
123
+ "seaborn_0_11: tests for seaborn 0.11+",
124
+ "seaborn_0_12: tests for seaborn 0.12+",
125
+ "plotly_5_0: tests for plotly 5.0+",
126
+ "altair_5_0: tests for altair 5.0+",
127
+ "matplotlib: tests requiring matplotlib",
128
+ "seaborn: tests requiring seaborn",
129
+ "plotly: tests requiring plotly",
130
+ "altair: tests requiring altair",
131
+ ]
132
+
133
+ [tool.uv.sources]
134
+ sane-figs = { workspace = true }
135
+
136
+ [dependency-groups]
137
+ dev = [
138
+ "marimo>=0.8.22",
139
+ "mkdocs>=1.6.1",
140
+ "plotly>=6.5.2",
141
+ "pymdown-extensions>=10.0",
142
+ "sane-figs",
143
+ ]