batplot 1.8.45__tar.gz → 1.8.46__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.
- {batplot-1.8.45 → batplot-1.8.46}/DEVELOPING.md +15 -1
- batplot-1.8.46/MANIFEST.in +4 -0
- {batplot-1.8.45 → batplot-1.8.46}/PKG-INFO +87 -5
- {batplot-1.8.45 → batplot-1.8.46}/README.md +86 -4
- {batplot-1.8.45 → batplot-1.8.46}/batplot/__init__.py +1 -1
- {batplot-1.8.45 → batplot-1.8.46}/batplot/_mpl_backend.py +90 -41
- {batplot-1.8.45 → batplot-1.8.46}/batplot/args.py +73 -5
- {batplot-1.8.45 → batplot-1.8.46}/batplot/batch.py +245 -1
- {batplot-1.8.45 → batplot-1.8.46}/batplot/batplot.py +29 -12
- {batplot-1.8.45 → batplot-1.8.46}/batplot/canvas_interactive.py +2 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/cli.py +10 -0
- batplot-1.8.46/batplot/cli_save.py +375 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/data/CHANGELOG.md +4 -0
- batplot-1.8.46/batplot/data/latest_release_notes.json +7 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/dev_upgrade.py +457 -142
- batplot-1.8.46/batplot/plot_modes/batch_session/__init__.py +5 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/batch_commands.py +128 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/batch_io.py +178 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/common.py +139 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/kinds.py +45 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/load.py +204 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/menu_cpc.py +291 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/menu_ec.py +318 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/menu_histo.py +407 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/menu_operando.py +292 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/menu_xy.py +429 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/routing.py +77 -0
- batplot-1.8.46/batplot/plot_modes/batch_session/xy_batch_helpers.py +171 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/spines.py +7 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/cpc/routing.py +50 -11
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/routing.py +99 -31
- batplot-1.8.46/batplot/plot_modes/histo/__init__.py +5 -0
- batplot-1.8.46/batplot/plot_modes/histo/actions.py +436 -0
- batplot-1.8.46/batplot/plot_modes/histo/colors.py +200 -0
- batplot-1.8.46/batplot/plot_modes/histo/density_curve.py +152 -0
- batplot-1.8.46/batplot/plot_modes/histo/fonts.py +77 -0
- batplot-1.8.46/batplot/plot_modes/histo/interactive.py +502 -0
- batplot-1.8.46/batplot/plot_modes/histo/labels.py +101 -0
- batplot-1.8.46/batplot/plot_modes/histo/load.py +208 -0
- batplot-1.8.46/batplot/plot_modes/histo/plot.py +239 -0
- batplot-1.8.46/batplot/plot_modes/histo/routing.py +353 -0
- batplot-1.8.46/batplot/plot_modes/histo/session.py +61 -0
- batplot-1.8.46/batplot/plot_modes/histo/spines.py +291 -0
- batplot-1.8.46/batplot/plot_modes/histo/toggles.py +174 -0
- batplot-1.8.46/batplot/plot_modes/histo/wizard.py +188 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/plot.py +12 -3
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/routing.py +40 -11
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/session_routing.py +59 -55
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/pipeline.py +47 -17
- {batplot-1.8.45 → batplot-1.8.46}/batplot/readers.py +24 -5
- {batplot-1.8.45 → batplot-1.8.46}/batplot/version_check.py +8 -7
- {batplot-1.8.45 → batplot-1.8.46}/batplot.egg-info/PKG-INFO +87 -5
- {batplot-1.8.45 → batplot-1.8.46}/batplot.egg-info/SOURCES.txt +33 -0
- {batplot-1.8.45 → batplot-1.8.46}/pyproject.toml +2 -2
- batplot-1.8.46/tests/test_batch_session.py +241 -0
- batplot-1.8.46/tests/test_bruker_intensity.py +25 -0
- batplot-1.8.46/tests/test_cli_save.py +72 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_cli_smoke.py +42 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_dev_upgrade.py +108 -0
- batplot-1.8.46/tests/test_histo.py +598 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_mpl_backend.py +39 -0
- batplot-1.8.45/MANIFEST.in +0 -3
- {batplot-1.8.45 → batplot-1.8.46}/LICENSE +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/NOTICE +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/cif.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/color_utils.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/config.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/converters.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/ec_common.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/modes.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/__init__.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/__init__.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/axis_state.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/files.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/fonts.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/interactive_state.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/menu_rendering.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/menus.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/palettes.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/smoothing.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/sources.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/terminal.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/common/title_offsets.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/cpc/__init__.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/cpc/actions.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/cpc/colors.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/cpc/interactive.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/cpc/labels.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/cpc/legend.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/cpc/menu.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/cpc/session.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/cpc/snapshots.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/__init__.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/actions.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/colors.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/dqdv_2d.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/export.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/interactive.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/labels.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/legend.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/legend_order.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/line_style.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/menu.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/session.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/spine_colors.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/electrochem/style.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/__init__.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/actions.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/colors.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/grid.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/interactive.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/ions_axis.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/labels.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/layout.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/line_style.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/menu.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/peaks.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/session.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/style.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/operando/visibility.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/__init__.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/actions.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/arrange.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/axis_range.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/cif.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/colors.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/data_ops.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/derivative.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/game.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/interactive.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/labels.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/line_style.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/menu.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/peaks.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/session.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/smoothing.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plot_modes/xy/style.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/plotting.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/session.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/showcol.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/style.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/ui.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot/utils.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot.egg-info/dependency_links.txt +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot.egg-info/entry_points.txt +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot.egg-info/requires.txt +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/batplot.egg-info/top_level.txt +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/setup.cfg +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/setup.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_color_utils.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_common_files.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_common_palettes.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_contracts.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_cpc_roundtrip.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_csv_readers.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_ec_roundtrip.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_interactive_menu_smoke.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_interactive_state.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_operando_roundtrip.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_xy_modules.py +0 -0
- {batplot-1.8.45 → batplot-1.8.46}/tests/test_xy_roundtrip.py +0 -0
|
@@ -429,9 +429,23 @@ Before changing release behavior:
|
|
|
429
429
|
|
|
430
430
|
1. Read `batplot/dev_upgrade.py`.
|
|
431
431
|
2. Add or update tests in `tests/test_dev_upgrade.py`.
|
|
432
|
-
3. Confirm future files are included
|
|
432
|
+
3. Confirm future files are included automatically:
|
|
433
|
+
- Python modules: `packages.find include = ["batplot*"]` plus
|
|
434
|
+
`validate_distribution_contents()` (every `batplot/**/*.py` must be in the wheel).
|
|
435
|
+
- Package data: drop files into `batplot/data/` (except `USER_MANUAL.md`);
|
|
436
|
+
`--dev-upgrade` runs `sync_pyproject_package_data()` to refresh
|
|
437
|
+
`[tool.setuptools.package-data]`.
|
|
438
|
+
- Git: `_git_stage_release_snapshot()` stages tracked updates and all untracked
|
|
439
|
+
non-ignored paths (no hand-maintained file list).
|
|
433
440
|
4. Keep GitHub/PyPI conflict handling explicit and testable.
|
|
434
441
|
|
|
442
|
+
Canonical version files checked on every release:
|
|
443
|
+
|
|
444
|
+
- `batplot/__init__.py` (`__version__`)
|
|
445
|
+
- `pyproject.toml` (`[project] version`)
|
|
446
|
+
- `CITATION.cff` (`version: v…`)
|
|
447
|
+
- `batplot/data/latest_release_notes.json` (`version` field)
|
|
448
|
+
|
|
435
449
|
## Cross-Platform Checklist
|
|
436
450
|
|
|
437
451
|
Use this checklist before finishing code changes:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: batplot
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.46
|
|
4
4
|
Summary: Interactive plotting tool for material science (1D plot) and electrochemistry (GC, CV, dQ/dV, CPC, operando) with batch processing
|
|
5
5
|
Author-email: Tian Dai <tianda@uio.no>
|
|
6
6
|
License: MIT License
|
|
@@ -64,9 +64,10 @@ With a single line of command to easily plot publication-ready plots with custom
|
|
|
64
64
|
- **Electrochemistry Plot**: Galvanostatic cycling (GC), cyclic voltammetry (CV), differential capacity (dQdV), capacity per cycle (CPC) with multi-file support
|
|
65
65
|
- **1D XY plot**: Designed for XRD, PDF, XAS (XANES/EXAFS) but also support other types
|
|
66
66
|
- **Operando Contour plot**: Correlate in-situ characterizations (XRD/PDF/XAS) with electrochemical data
|
|
67
|
+
- **Histogram mode**: Column histograms from tabular `.csv`/`.txt` data (e.g. particle-size lists)
|
|
67
68
|
- **Interactive plotting**: Real-time editing customized for each type of plottings
|
|
68
69
|
- **Session Persistence**: Save and reload complete plot states with `.pkl` files
|
|
69
|
-
- **Style Management**: Import/export plot styles as `.bps`/`.bpsg` files
|
|
70
|
+
- **Style Management**: Import/export plot styles as `.bps`/`.bpsg` files (histogram: `.bpsh`)
|
|
70
71
|
- **Batch Processing**: Export each file separately with `--all`
|
|
71
72
|
- **Column preview**: `--showcol` prints numbered columns, header names when found, and the first 10 values per column (CSV, Excel, text, .mpt, .brml, Bruker .raw, etc.)
|
|
72
73
|
|
|
@@ -190,6 +191,21 @@ batplot file1.xy file2.xy --stack --i
|
|
|
190
191
|
batplot allfiles --xaxis 2theta --xrange 15 75 --i
|
|
191
192
|
```
|
|
192
193
|
|
|
194
|
+
### Session save without interactive menu (`--save`)
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Single file: default .pkl name = data file stem; choose save folder when prompted
|
|
198
|
+
batplot pattern.xye --xaxis 2theta --save
|
|
199
|
+
|
|
200
|
+
# Batch: one session per file (default names), folder chosen once
|
|
201
|
+
batplot --all --xaxis 2theta --xrange 10 80 --save
|
|
202
|
+
|
|
203
|
+
# Combined plot (allfiles, operando, multi-file GC/CPC): you must name the session
|
|
204
|
+
batplot allfiles --xaxis q --save
|
|
205
|
+
batplot --operando --wl 0.25 --save
|
|
206
|
+
batplot file1.csv file2.csv --gc --save
|
|
207
|
+
```
|
|
208
|
+
|
|
193
209
|
---
|
|
194
210
|
|
|
195
211
|
## Electrochemistry Mode
|
|
@@ -296,16 +312,80 @@ Operando column selection:
|
|
|
296
312
|
|
|
297
313
|
---
|
|
298
314
|
|
|
315
|
+
## Histogram Mode
|
|
316
|
+
|
|
317
|
+
Histogram mode plots a single numeric column from tabular `.csv` or `.txt` files. It is designed for particle-size distributions and similar column data exported from spreadsheets or image-analysis tools.
|
|
318
|
+
|
|
319
|
+
### Basic usage
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
# Interactive wizard + styling menu
|
|
323
|
+
batplot sizes.csv --histo --i
|
|
324
|
+
|
|
325
|
+
# Non-interactive: column, range, bins, save figure
|
|
326
|
+
batplot data.txt --histo --histocol Length --xrange 0 16 --binwidth 1 --out hist.png
|
|
327
|
+
|
|
328
|
+
# Preview columns before choosing
|
|
329
|
+
batplot --showcol sizes.csv
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Startup wizard (`--i`)
|
|
333
|
+
|
|
334
|
+
1. Choose the column to histogram (numbered list with preview)
|
|
335
|
+
2. Set histogram range (`xmin xmax` or `auto`)
|
|
336
|
+
3. Set bin width or `bins=N`
|
|
337
|
+
|
|
338
|
+
### Batch export
|
|
339
|
+
|
|
340
|
+
Export each CSV/TXT file in the folder as a separate figure under `Figures/`:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
batplot --all --histo --histocol Length
|
|
344
|
+
batplot allfiles --histo --histocol 7 --binwidth 1
|
|
345
|
+
batplot histo_folder/ --histo --histocol Length
|
|
346
|
+
|
|
347
|
+
# Apply a shared histogram style (.bpsh)
|
|
348
|
+
batplot --all mystyle.bpsh --histo --histocol Length
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
`--histocol` is required for batch export (column number or header name).
|
|
352
|
+
|
|
353
|
+
### Batch interactive editing
|
|
354
|
+
|
|
355
|
+
Edit two or more histograms together (sync colors, fonts, export):
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
batplot allfiles --histo --i
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
If `--histocol` is omitted, the wizard runs on the first file and the same column/bin layout is reused for the rest.
|
|
362
|
+
|
|
363
|
+
### Flags
|
|
364
|
+
|
|
365
|
+
| Flag | Description |
|
|
366
|
+
|------|-------------|
|
|
367
|
+
| `--histo` | Launch histogram mode |
|
|
368
|
+
| `--histocol N` | Column to histogram (1-indexed or header name) |
|
|
369
|
+
| `--xrange A B` | Histogram display range |
|
|
370
|
+
| `--binwidth W` | Width of each bin |
|
|
371
|
+
| `--bins N` | Number of equal-width bins |
|
|
372
|
+
| `--all` | Batch export each CSV/TXT file (requires `--histocol`) |
|
|
373
|
+
| `allfiles` | Expand all CSV/TXT in folder (batch export or `--i` batch edit) |
|
|
374
|
+
|
|
375
|
+
Style files: `.bpsh` (export with `p` in the interactive menu).
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
299
379
|
## Plotting multiple files
|
|
300
380
|
|
|
301
381
|
```bash
|
|
302
382
|
# All XY files in current directory on same figure
|
|
303
|
-
batplot allfiles
|
|
304
|
-
batplot allfiles --stack --i
|
|
383
|
+
batplot allfiles --xaxis 2theta --i
|
|
384
|
+
batplot allfiles --stack --gc --i
|
|
305
385
|
|
|
306
386
|
# Only specific extension (natural-sorted)
|
|
307
387
|
batplot allxyfiles
|
|
308
|
-
batplot "/path/to/data" allnorfiles --i
|
|
388
|
+
batplot "/path/to/data" allnorfiles --xaxis energy --i
|
|
309
389
|
|
|
310
390
|
# Explicit file list
|
|
311
391
|
batplot file1.xye file2.qye structure.cif:1.54 --stack --i
|
|
@@ -351,6 +431,7 @@ With `--interactive`:
|
|
|
351
431
|
- **Styling**: Line widths, markers, fonts
|
|
352
432
|
- **Axes**: Labels, limits, ticks, spine styles
|
|
353
433
|
- **Export**: Sessions (`.pkl`), styles (`.bps`/`.bpsg`), high-res images. Colors persist via `p` (print style), `i` (import), `s` (save session), `b` (undo)
|
|
434
|
+
- **Non-interactive session save**: `--save` (without `--i`) prompts for folder and filename—the same `.pkl` sessions as interactive `s`, with default names for single-file and `--all` batch runs
|
|
354
435
|
- **Live Preview**: All changes update in real-time
|
|
355
436
|
|
|
356
437
|
---
|
|
@@ -362,6 +443,7 @@ batplot --h # General help
|
|
|
362
443
|
batplot --h xy # XY mode guide
|
|
363
444
|
batplot --h ec # Electrochemistry guide
|
|
364
445
|
batplot --h op # Operando guide
|
|
446
|
+
batplot --h histo # Histogram mode guide
|
|
365
447
|
batplot --v # Version and release notes
|
|
366
448
|
batplot --m # Open illustrated manual
|
|
367
449
|
```
|
|
@@ -10,9 +10,10 @@ With a single line of command to easily plot publication-ready plots with custom
|
|
|
10
10
|
- **Electrochemistry Plot**: Galvanostatic cycling (GC), cyclic voltammetry (CV), differential capacity (dQdV), capacity per cycle (CPC) with multi-file support
|
|
11
11
|
- **1D XY plot**: Designed for XRD, PDF, XAS (XANES/EXAFS) but also support other types
|
|
12
12
|
- **Operando Contour plot**: Correlate in-situ characterizations (XRD/PDF/XAS) with electrochemical data
|
|
13
|
+
- **Histogram mode**: Column histograms from tabular `.csv`/`.txt` data (e.g. particle-size lists)
|
|
13
14
|
- **Interactive plotting**: Real-time editing customized for each type of plottings
|
|
14
15
|
- **Session Persistence**: Save and reload complete plot states with `.pkl` files
|
|
15
|
-
- **Style Management**: Import/export plot styles as `.bps`/`.bpsg` files
|
|
16
|
+
- **Style Management**: Import/export plot styles as `.bps`/`.bpsg` files (histogram: `.bpsh`)
|
|
16
17
|
- **Batch Processing**: Export each file separately with `--all`
|
|
17
18
|
- **Column preview**: `--showcol` prints numbered columns, header names when found, and the first 10 values per column (CSV, Excel, text, .mpt, .brml, Bruker .raw, etc.)
|
|
18
19
|
|
|
@@ -136,6 +137,21 @@ batplot file1.xy file2.xy --stack --i
|
|
|
136
137
|
batplot allfiles --xaxis 2theta --xrange 15 75 --i
|
|
137
138
|
```
|
|
138
139
|
|
|
140
|
+
### Session save without interactive menu (`--save`)
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Single file: default .pkl name = data file stem; choose save folder when prompted
|
|
144
|
+
batplot pattern.xye --xaxis 2theta --save
|
|
145
|
+
|
|
146
|
+
# Batch: one session per file (default names), folder chosen once
|
|
147
|
+
batplot --all --xaxis 2theta --xrange 10 80 --save
|
|
148
|
+
|
|
149
|
+
# Combined plot (allfiles, operando, multi-file GC/CPC): you must name the session
|
|
150
|
+
batplot allfiles --xaxis q --save
|
|
151
|
+
batplot --operando --wl 0.25 --save
|
|
152
|
+
batplot file1.csv file2.csv --gc --save
|
|
153
|
+
```
|
|
154
|
+
|
|
139
155
|
---
|
|
140
156
|
|
|
141
157
|
## Electrochemistry Mode
|
|
@@ -242,16 +258,80 @@ Operando column selection:
|
|
|
242
258
|
|
|
243
259
|
---
|
|
244
260
|
|
|
261
|
+
## Histogram Mode
|
|
262
|
+
|
|
263
|
+
Histogram mode plots a single numeric column from tabular `.csv` or `.txt` files. It is designed for particle-size distributions and similar column data exported from spreadsheets or image-analysis tools.
|
|
264
|
+
|
|
265
|
+
### Basic usage
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
# Interactive wizard + styling menu
|
|
269
|
+
batplot sizes.csv --histo --i
|
|
270
|
+
|
|
271
|
+
# Non-interactive: column, range, bins, save figure
|
|
272
|
+
batplot data.txt --histo --histocol Length --xrange 0 16 --binwidth 1 --out hist.png
|
|
273
|
+
|
|
274
|
+
# Preview columns before choosing
|
|
275
|
+
batplot --showcol sizes.csv
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Startup wizard (`--i`)
|
|
279
|
+
|
|
280
|
+
1. Choose the column to histogram (numbered list with preview)
|
|
281
|
+
2. Set histogram range (`xmin xmax` or `auto`)
|
|
282
|
+
3. Set bin width or `bins=N`
|
|
283
|
+
|
|
284
|
+
### Batch export
|
|
285
|
+
|
|
286
|
+
Export each CSV/TXT file in the folder as a separate figure under `Figures/`:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
batplot --all --histo --histocol Length
|
|
290
|
+
batplot allfiles --histo --histocol 7 --binwidth 1
|
|
291
|
+
batplot histo_folder/ --histo --histocol Length
|
|
292
|
+
|
|
293
|
+
# Apply a shared histogram style (.bpsh)
|
|
294
|
+
batplot --all mystyle.bpsh --histo --histocol Length
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
`--histocol` is required for batch export (column number or header name).
|
|
298
|
+
|
|
299
|
+
### Batch interactive editing
|
|
300
|
+
|
|
301
|
+
Edit two or more histograms together (sync colors, fonts, export):
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
batplot allfiles --histo --i
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
If `--histocol` is omitted, the wizard runs on the first file and the same column/bin layout is reused for the rest.
|
|
308
|
+
|
|
309
|
+
### Flags
|
|
310
|
+
|
|
311
|
+
| Flag | Description |
|
|
312
|
+
|------|-------------|
|
|
313
|
+
| `--histo` | Launch histogram mode |
|
|
314
|
+
| `--histocol N` | Column to histogram (1-indexed or header name) |
|
|
315
|
+
| `--xrange A B` | Histogram display range |
|
|
316
|
+
| `--binwidth W` | Width of each bin |
|
|
317
|
+
| `--bins N` | Number of equal-width bins |
|
|
318
|
+
| `--all` | Batch export each CSV/TXT file (requires `--histocol`) |
|
|
319
|
+
| `allfiles` | Expand all CSV/TXT in folder (batch export or `--i` batch edit) |
|
|
320
|
+
|
|
321
|
+
Style files: `.bpsh` (export with `p` in the interactive menu).
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
245
325
|
## Plotting multiple files
|
|
246
326
|
|
|
247
327
|
```bash
|
|
248
328
|
# All XY files in current directory on same figure
|
|
249
|
-
batplot allfiles
|
|
250
|
-
batplot allfiles --stack --i
|
|
329
|
+
batplot allfiles --xaxis 2theta --i
|
|
330
|
+
batplot allfiles --stack --gc --i
|
|
251
331
|
|
|
252
332
|
# Only specific extension (natural-sorted)
|
|
253
333
|
batplot allxyfiles
|
|
254
|
-
batplot "/path/to/data" allnorfiles --i
|
|
334
|
+
batplot "/path/to/data" allnorfiles --xaxis energy --i
|
|
255
335
|
|
|
256
336
|
# Explicit file list
|
|
257
337
|
batplot file1.xye file2.qye structure.cif:1.54 --stack --i
|
|
@@ -297,6 +377,7 @@ With `--interactive`:
|
|
|
297
377
|
- **Styling**: Line widths, markers, fonts
|
|
298
378
|
- **Axes**: Labels, limits, ticks, spine styles
|
|
299
379
|
- **Export**: Sessions (`.pkl`), styles (`.bps`/`.bpsg`), high-res images. Colors persist via `p` (print style), `i` (import), `s` (save session), `b` (undo)
|
|
380
|
+
- **Non-interactive session save**: `--save` (without `--i`) prompts for folder and filename—the same `.pkl` sessions as interactive `s`, with default names for single-file and `--all` batch runs
|
|
300
381
|
- **Live Preview**: All changes update in real-time
|
|
301
382
|
|
|
302
383
|
---
|
|
@@ -308,6 +389,7 @@ batplot --h # General help
|
|
|
308
389
|
batplot --h xy # XY mode guide
|
|
309
390
|
batplot --h ec # Electrochemistry guide
|
|
310
391
|
batplot --h op # Operando guide
|
|
392
|
+
batplot --h histo # Histogram mode guide
|
|
311
393
|
batplot --v # Version and release notes
|
|
312
394
|
batplot --m # Open illustrated manual
|
|
313
395
|
```
|
|
@@ -77,6 +77,8 @@ def running_headless() -> bool:
|
|
|
77
77
|
|
|
78
78
|
def wants_interactive_window(args) -> bool:
|
|
79
79
|
"""Return True when this CLI invocation should open an interactive figure."""
|
|
80
|
+
if args is None:
|
|
81
|
+
return False
|
|
80
82
|
if getattr(args, "all", None) is not None:
|
|
81
83
|
return False
|
|
82
84
|
files = getattr(args, "files", None) or []
|
|
@@ -86,12 +88,17 @@ def wants_interactive_window(args) -> bool:
|
|
|
86
88
|
return True
|
|
87
89
|
if getattr(args, "interactive", False):
|
|
88
90
|
return True
|
|
89
|
-
# Headless export
|
|
91
|
+
# Headless export / session save: --out, --savefig, or --save (without --i).
|
|
90
92
|
if getattr(args, "savefig", False) or getattr(args, "out", None):
|
|
91
93
|
return False
|
|
92
|
-
|
|
94
|
+
if getattr(args, "save", False) and not getattr(args, "interactive", False):
|
|
95
|
+
return False
|
|
96
|
+
for attr in ("operando", "contour", "gc", "cv", "dqdv", "cpc", "epc", "histo"):
|
|
93
97
|
if getattr(args, attr, False):
|
|
94
98
|
return True
|
|
99
|
+
# Default XY / multi-file diffraction view (no --out, no --all).
|
|
100
|
+
if files:
|
|
101
|
+
return True
|
|
95
102
|
return False
|
|
96
103
|
|
|
97
104
|
|
|
@@ -128,26 +135,6 @@ def _backend_can_be_tried(name: str) -> bool:
|
|
|
128
135
|
return True
|
|
129
136
|
|
|
130
137
|
|
|
131
|
-
def _backend_setup_tips() -> list[str]:
|
|
132
|
-
if sys.platform == "darwin":
|
|
133
|
-
return [
|
|
134
|
-
" export MPLBACKEND=MacOSX # built-in macOS backend",
|
|
135
|
-
" export MPLBACKEND=TkAgg # if Tk is available",
|
|
136
|
-
" export MPLBACKEND=QtAgg # if PyQt/PySide is installed",
|
|
137
|
-
]
|
|
138
|
-
if sys.platform.startswith("win"):
|
|
139
|
-
return [
|
|
140
|
-
" set MPLBACKEND=TkAgg # cmd, if Tk is available",
|
|
141
|
-
' $env:MPLBACKEND="TkAgg" # PowerShell',
|
|
142
|
-
" set MPLBACKEND=QtAgg # if PyQt/PySide is installed",
|
|
143
|
-
]
|
|
144
|
-
return [
|
|
145
|
-
" export MPLBACKEND=TkAgg # if python3-tk is installed",
|
|
146
|
-
" export MPLBACKEND=QtAgg # if PyQt/PySide is installed",
|
|
147
|
-
" export MPLBACKEND=Gtk3Agg # if GTK3 bindings are installed",
|
|
148
|
-
]
|
|
149
|
-
|
|
150
|
-
|
|
151
138
|
def ensure_gui_backend(args=None) -> bool:
|
|
152
139
|
"""Switch from Agg to a GUI backend when an interactive window is expected.
|
|
153
140
|
|
|
@@ -181,20 +168,51 @@ def ensure_gui_backend(args=None) -> bool:
|
|
|
181
168
|
return False
|
|
182
169
|
|
|
183
170
|
|
|
184
|
-
def
|
|
185
|
-
"""
|
|
186
|
-
if
|
|
187
|
-
return
|
|
171
|
+
def _one_line_backend_workaround() -> str:
|
|
172
|
+
"""Return a copy-paste command prefix for the current platform."""
|
|
173
|
+
if sys.platform == "darwin":
|
|
174
|
+
return "MPLBACKEND=MacOSX batplot ..."
|
|
175
|
+
if sys.platform.startswith("win"):
|
|
176
|
+
return 'set MPLBACKEND=TkAgg (cmd) or $env:MPLBACKEND="TkAgg" (PowerShell), then batplot ...'
|
|
177
|
+
return "MPLBACKEND=TkAgg batplot ..."
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _print_interactive_backend_help(context: str = "interactive menu") -> None:
|
|
181
|
+
"""User-facing recovery steps when no GUI window can be opened."""
|
|
188
182
|
try:
|
|
189
183
|
backend = _mpl.get_backend()
|
|
190
184
|
except Exception:
|
|
191
185
|
backend = "unknown"
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
186
|
+
try:
|
|
187
|
+
from . import __version__ as _bp_version
|
|
188
|
+
except Exception:
|
|
189
|
+
_bp_version = "latest"
|
|
190
|
+
|
|
191
|
+
print()
|
|
192
|
+
print("Interactive plotting needs a display window, but batplot could not open one.")
|
|
193
|
+
print(f"(Matplotlib backend: {backend})")
|
|
196
194
|
if context:
|
|
197
|
-
print(f"
|
|
195
|
+
print(f"This affects: {context}.")
|
|
196
|
+
print()
|
|
197
|
+
print("Try these steps, in order:")
|
|
198
|
+
print(" 1. Upgrade batplot (fixes most cases):")
|
|
199
|
+
print(" pip install --upgrade batplot")
|
|
200
|
+
print(f" You need the latest batplot release (installed: {_bp_version}).")
|
|
201
|
+
print(" 2. If you cannot upgrade yet, force a GUI backend for this session:")
|
|
202
|
+
print(f" {_one_line_backend_workaround()}")
|
|
203
|
+
print(" 3. To save a figure without the interactive menu:")
|
|
204
|
+
print(" batplot ... --out figure.png (omit --i)")
|
|
205
|
+
print()
|
|
206
|
+
print("Advanced: if MPLBACKEND=Agg is set in your shell or conda env, unset it or override")
|
|
207
|
+
print("as in step 2. On headless servers (SSH with no display), use --out instead of --i.")
|
|
208
|
+
print()
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def warn_if_noninteractive(context: str = "interactive menu") -> bool:
|
|
212
|
+
"""Print a helpful message when the backend cannot show a window."""
|
|
213
|
+
if is_interactive_backend():
|
|
214
|
+
return True
|
|
215
|
+
_print_interactive_backend_help(context)
|
|
198
216
|
return False
|
|
199
217
|
|
|
200
218
|
|
|
@@ -202,30 +220,61 @@ def require_interactive_display(
|
|
|
202
220
|
args=None,
|
|
203
221
|
*,
|
|
204
222
|
context: str = "interactive menu",
|
|
205
|
-
export_hint: str | None =
|
|
223
|
+
export_hint: str | None = None,
|
|
206
224
|
) -> bool:
|
|
207
225
|
"""Ensure a GUI backend, warn if unavailable, return True when display is possible."""
|
|
208
226
|
ensure_gui_backend(args)
|
|
209
227
|
if is_interactive_backend():
|
|
210
228
|
return True
|
|
211
229
|
warn_if_noninteractive(context)
|
|
212
|
-
if export_hint:
|
|
213
|
-
print(export_hint)
|
|
214
230
|
return False
|
|
215
231
|
|
|
216
232
|
|
|
217
|
-
def show_figure_if_possible(args=None, *, block: bool =
|
|
218
|
-
"""Show the current figure when the backend supports windows.
|
|
233
|
+
def show_figure_if_possible(args=None, *, block: bool = True) -> bool:
|
|
234
|
+
"""Show the current figure when the backend supports windows.
|
|
235
|
+
|
|
236
|
+
Defaults to ``block=True`` so the window stays open until the user closes it.
|
|
237
|
+
Non-interactive view mode (no ``--i``) relies on this; ``block=False`` would
|
|
238
|
+
return immediately and the process would exit before the figure is visible.
|
|
239
|
+
"""
|
|
219
240
|
ensure_gui_backend(args)
|
|
220
241
|
if not is_interactive_backend():
|
|
221
242
|
if args is not None and not (getattr(args, "savefig", False) or getattr(args, "out", None)):
|
|
222
|
-
|
|
223
|
-
backend = _mpl.get_backend()
|
|
224
|
-
except Exception:
|
|
225
|
-
backend = "unknown"
|
|
226
|
-
print(f"Matplotlib backend '{backend}' is non-interactive; use --out to save the figure.")
|
|
243
|
+
print("No display window available. Save the figure with: batplot ... --out figure.png")
|
|
227
244
|
return False
|
|
228
245
|
import matplotlib.pyplot as plt
|
|
229
246
|
|
|
230
247
|
plt.show(block=block)
|
|
231
248
|
return True
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def prime_interactive_figure(fig=None) -> None:
|
|
252
|
+
"""Prepare a matplotlib window before an interactive menu (non-blocking)."""
|
|
253
|
+
import matplotlib.pyplot as plt
|
|
254
|
+
|
|
255
|
+
try:
|
|
256
|
+
plt.ion()
|
|
257
|
+
except Exception:
|
|
258
|
+
pass
|
|
259
|
+
if fig is not None:
|
|
260
|
+
try:
|
|
261
|
+
fig.canvas.draw_idle()
|
|
262
|
+
fig.canvas.flush_events()
|
|
263
|
+
except Exception:
|
|
264
|
+
pass
|
|
265
|
+
try:
|
|
266
|
+
plt.show(block=False)
|
|
267
|
+
except Exception:
|
|
268
|
+
pass
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def hold_figure_open() -> None:
|
|
272
|
+
"""Keep the current figure window open until the user closes it."""
|
|
273
|
+
if not is_interactive_backend():
|
|
274
|
+
return
|
|
275
|
+
import matplotlib.pyplot as plt
|
|
276
|
+
|
|
277
|
+
try:
|
|
278
|
+
plt.show()
|
|
279
|
+
except Exception:
|
|
280
|
+
pass
|