0
# Gallery Sorting
1
2
Flexible sorting system for organizing galleries and examples within galleries. Sphinx-Gallery provides built-in sorting functions and supports custom sorting logic for complete control over gallery organization.
3
4
## Capabilities
5
6
### Explicit Ordering
7
8
Sort key class for explicit ordering of gallery subsections.
9
10
```python { .api }
11
class ExplicitOrder:
12
"""
13
Sorting key for explicit ordering of gallery subsections.
14
15
Allows you to specify the exact order of gallery subsections
16
by providing a list of subsection names. Subsections not in
17
the list appear after ordered ones in alphabetical order.
18
"""
19
20
def __init__(self, ordered_list):
21
"""
22
Parameters:
23
- ordered_list: list, explicit order of subsection names
24
"""
25
26
def __call__(self, item):
27
"""
28
Sorting key function.
29
30
Parameters:
31
- item: str, subsection name to sort
32
33
Returns:
34
tuple: Sort key for the item
35
"""
36
```
37
38
#### Usage Example
39
40
```python
41
from sphinx_gallery.sorting import ExplicitOrder
42
43
sphinx_gallery_conf = {
44
'subsection_order': ExplicitOrder([
45
'basic_examples',
46
'intermediate_examples',
47
'advanced_examples',
48
'expert_examples'
49
]),
50
}
51
```
52
53
### Built-in Sorting Functions
54
55
#### File Size Sorting
56
57
```python { .api }
58
def FileSizeKey(filename):
59
"""
60
Sort examples by file size.
61
62
Parameters:
63
- filename: str, path to the example file
64
65
Returns:
66
int: File size in bytes for sorting
67
"""
68
```
69
70
#### Code Lines Sorting
71
72
```python { .api }
73
def NumberOfCodeLinesSortKey(filename):
74
"""
75
Sort examples by number of lines of code.
76
77
Parameters:
78
- filename: str, path to the example file
79
80
Returns:
81
int: Number of lines of code for sorting
82
"""
83
```
84
85
#### Filename Sorting
86
87
```python { .api }
88
def FileNameSortKey(filename):
89
"""
90
Sort examples alphabetically by filename.
91
92
Parameters:
93
- filename: str, path to the example file
94
95
Returns:
96
str: Filename for alphabetical sorting
97
"""
98
```
99
100
#### Example Date Sorting
101
102
```python { .api }
103
def ExampleTitleSortKey(filename):
104
"""
105
Sort examples by title extracted from docstring.
106
107
Parameters:
108
- filename: str, path to the example file
109
110
Returns:
111
str: Example title for sorting
112
"""
113
```
114
115
## Configuration
116
117
### Subsection Ordering
118
119
Control the order of gallery subsections (directories):
120
121
```python
122
from sphinx_gallery.sorting import ExplicitOrder
123
124
sphinx_gallery_conf = {
125
# Use explicit ordering
126
'subsection_order': ExplicitOrder(['basic', 'advanced', 'expert']),
127
128
# Or use a custom function
129
'subsection_order': lambda x: x.lower(), # Alphabetical, case-insensitive
130
}
131
```
132
133
### Within-Subsection Ordering
134
135
Control the order of examples within each subsection:
136
137
```python
138
from sphinx_gallery.sorting import NumberOfCodeLinesSortKey, FileSizeKey
139
140
sphinx_gallery_conf = {
141
# Sort by number of code lines (default)
142
'within_subsection_order': NumberOfCodeLinesSortKey,
143
144
# Sort by file size
145
'within_subsection_order': FileSizeKey,
146
147
# Sort alphabetically by filename
148
'within_subsection_order': lambda filename: os.path.basename(filename),
149
}
150
```
151
152
## Custom Sorting Functions
153
154
### Creating Custom Sort Functions
155
156
```python
157
def custom_sort_key(filename):
158
"""
159
Custom sorting function example.
160
161
Sort by complexity level indicated in filename prefix.
162
"""
163
basename = os.path.basename(filename)
164
165
# Extract complexity level from filename
166
if basename.startswith('beginner_'):
167
return (1, basename)
168
elif basename.startswith('intermediate_'):
169
return (2, basename)
170
elif basename.startswith('advanced_'):
171
return (3, basename)
172
else:
173
return (4, basename) # Unknown complexity last
174
175
# Usage
176
sphinx_gallery_conf = {
177
'within_subsection_order': custom_sort_key,
178
}
179
```
180
181
### Multi-Level Sorting
182
183
```python
184
def multi_level_sort(filename):
185
"""
186
Multi-level sorting by category and then alphabetically.
187
"""
188
import os
189
import re
190
191
basename = os.path.basename(filename)
192
193
# Primary sort by category prefix
194
category_order = {
195
'plot_': 1,
196
'example_': 2,
197
'tutorial_': 3,
198
}
199
200
category = 999 # Default for unknown categories
201
for prefix, order in category_order.items():
202
if basename.startswith(prefix):
203
category = order
204
break
205
206
# Secondary sort alphabetically
207
return (category, basename.lower())
208
209
sphinx_gallery_conf = {
210
'within_subsection_order': multi_level_sort,
211
}
212
```
213
214
### Time-Based Sorting
215
216
```python
217
def modification_time_sort(filename):
218
"""
219
Sort by file modification time (newest first).
220
"""
221
import os
222
return -os.path.getmtime(filename) # Negative for reverse order
223
224
sphinx_gallery_conf = {
225
'within_subsection_order': modification_time_sort,
226
}
227
```
228
229
## Advanced Sorting Patterns
230
231
### Directory-Based Subsection Ordering
232
233
```python
234
def directory_priority_sort(subsection_dir):
235
"""
236
Sort subsections by directory name with priorities.
237
"""
238
priority_dirs = {
239
'getting_started': 1,
240
'basic_usage': 2,
241
'advanced_features': 3,
242
'tutorials': 4,
243
'examples': 5,
244
}
245
246
dir_name = os.path.basename(subsection_dir)
247
return priority_dirs.get(dir_name, 999), dir_name
248
249
sphinx_gallery_conf = {
250
'subsection_order': directory_priority_sort,
251
}
252
```
253
254
### Content-Based Sorting
255
256
```python
257
def docstring_complexity_sort(filename):
258
"""
259
Sort by complexity indicated in docstring.
260
"""
261
try:
262
with open(filename, 'r') as f:
263
content = f.read()
264
265
# Extract docstring
266
import ast
267
tree = ast.parse(content)
268
docstring = ast.get_docstring(tree)
269
270
if docstring:
271
# Look for complexity indicators
272
complexity_words = ['basic', 'simple', 'introduction']
273
advanced_words = ['advanced', 'complex', 'expert']
274
275
docstring_lower = docstring.lower()
276
277
if any(word in docstring_lower for word in complexity_words):
278
return (1, filename)
279
elif any(word in docstring_lower for word in advanced_words):
280
return (3, filename)
281
else:
282
return (2, filename)
283
except:
284
pass
285
286
return (2, filename) # Default to middle complexity
287
288
sphinx_gallery_conf = {
289
'within_subsection_order': docstring_complexity_sort,
290
}
291
```
292
293
## Integration Examples
294
295
### Complete Sorting Configuration
296
297
```python
298
from sphinx_gallery.sorting import ExplicitOrder, NumberOfCodeLinesSortKey
299
300
# Custom subsection order
301
tutorial_order = ExplicitOrder([
302
'01_introduction',
303
'02_basic_usage',
304
'03_advanced_features',
305
'04_customization',
306
'05_integration',
307
])
308
309
# Custom example sorting within subsections
310
def example_sort(filename):
311
"""Sort examples by number in filename, then alphabetically."""
312
import re
313
basename = os.path.basename(filename)
314
315
# Extract number from filename like "plot_001_example.py"
316
match = re.search(r'(\d+)', basename)
317
if match:
318
number = int(match.group(1))
319
return (number, basename)
320
return (999, basename) # Files without numbers last
321
322
sphinx_gallery_conf = {
323
'subsection_order': tutorial_order,
324
'within_subsection_order': example_sort,
325
}
326
```
327
328
### Conditional Sorting
329
330
```python
331
def conditional_sort(filename):
332
"""
333
Apply different sorting logic based on directory.
334
"""
335
dir_name = os.path.dirname(filename)
336
basename = os.path.basename(filename)
337
338
if 'tutorials' in dir_name:
339
# Sort tutorials by number prefix
340
import re
341
match = re.search(r'(\d+)', basename)
342
return int(match.group(1)) if match else 999
343
elif 'examples' in dir_name:
344
# Sort examples by complexity
345
if 'simple' in basename or 'basic' in basename:
346
return (1, basename)
347
elif 'advanced' in basename:
348
return (3, basename)
349
else:
350
return (2, basename)
351
else:
352
# Default alphabetical
353
return basename
354
355
sphinx_gallery_conf = {
356
'within_subsection_order': conditional_sort,
357
}
358
```
359
360
## Best Practices
361
362
### Naming Conventions
363
364
Use consistent filename prefixes for easier sorting:
365
366
```
367
basic_examples/
368
├── plot_001_simple_line.py
369
├── plot_002_bar_chart.py
370
└── plot_003_scatter_plot.py
371
372
advanced_examples/
373
├── plot_101_custom_colors.py
374
├── plot_102_animations.py
375
└── plot_103_interactive.py
376
```
377
378
### Progressive Complexity
379
380
Organize examples from simple to complex:
381
382
```python
383
complexity_order = ExplicitOrder([
384
'getting_started', # Basic concepts
385
'common_tasks', # Everyday usage
386
'advanced_features', # Power user features
387
'customization', # Theming and styling
388
'integration', # With other tools
389
])
390
```
391
392
### Topic-Based Organization
393
394
Group related functionality:
395
396
```python
397
topic_order = ExplicitOrder([
398
'data_visualization', # Core plotting
399
'statistical_plots', # Stats and analysis
400
'geographic_maps', # Geospatial data
401
'time_series', # Temporal data
402
'interactive_plots', # User interaction
403
])
404
```
405
406
## Troubleshooting
407
408
### Common Issues
409
410
- **Inconsistent Ordering**: Ensure sort functions return consistent types
411
- **Missing Examples**: Check that all examples are in expected directories
412
- **Unicode Issues**: Handle non-ASCII filenames in sort functions
413
- **Performance**: Simple sort functions work better with large galleries
414
415
### Debugging Sorting
416
417
```python
418
def debug_sort(filename):
419
"""Sort function with debugging output."""
420
key = NumberOfCodeLinesSortKey(filename)
421
print(f"Sorting {filename}: key={key}")
422
return key
423
424
sphinx_gallery_conf = {
425
'within_subsection_order': debug_sort,
426
'log_level': {'examples_log_level': 'DEBUG'},
427
}
428
```