batplot 1.1.8__tar.gz → 1.3.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 (32) hide show
  1. {batplot-1.1.8 → batplot-1.3.0}/PKG-INFO +7 -1
  2. {batplot-1.1.8 → batplot-1.3.0}/README.md +6 -0
  3. {batplot-1.1.8 → batplot-1.3.0}/batplot/__init__.py +1 -1
  4. {batplot-1.1.8 → batplot-1.3.0}/batplot/args.py +10 -1
  5. {batplot-1.1.8 → batplot-1.3.0}/batplot/batch.py +184 -1
  6. {batplot-1.1.8 → batplot-1.3.0}/batplot/batplot.py +43 -4
  7. {batplot-1.1.8 → batplot-1.3.0}/batplot/cpc_interactive.py +178 -25
  8. {batplot-1.1.8 → batplot-1.3.0}/batplot/electrochem_interactive.py +253 -49
  9. {batplot-1.1.8 → batplot-1.3.0}/batplot/interactive.py +116 -22
  10. {batplot-1.1.8 → batplot-1.3.0}/batplot/operando_ec_interactive.py +324 -60
  11. {batplot-1.1.8 → batplot-1.3.0}/batplot/session.py +44 -0
  12. {batplot-1.1.8 → batplot-1.3.0}/batplot/style.py +179 -20
  13. {batplot-1.1.8 → batplot-1.3.0}/batplot/ui.py +2 -2
  14. {batplot-1.1.8 → batplot-1.3.0}/batplot.egg-info/PKG-INFO +7 -1
  15. {batplot-1.1.8 → batplot-1.3.0}/batplot.egg-info/SOURCES.txt +1 -0
  16. {batplot-1.1.8 → batplot-1.3.0}/pyproject.toml +1 -1
  17. batplot-1.3.0/setup.py +3 -0
  18. {batplot-1.1.8 → batplot-1.3.0}/LICENSE +0 -0
  19. {batplot-1.1.8 → batplot-1.3.0}/batplot/batplot_new.py +0 -0
  20. {batplot-1.1.8 → batplot-1.3.0}/batplot/cif.py +0 -0
  21. {batplot-1.1.8 → batplot-1.3.0}/batplot/cli.py +0 -0
  22. {batplot-1.1.8 → batplot-1.3.0}/batplot/converters.py +0 -0
  23. {batplot-1.1.8 → batplot-1.3.0}/batplot/modes.py +0 -0
  24. {batplot-1.1.8 → batplot-1.3.0}/batplot/operando.py +0 -0
  25. {batplot-1.1.8 → batplot-1.3.0}/batplot/plotting.py +0 -0
  26. {batplot-1.1.8 → batplot-1.3.0}/batplot/readers.py +0 -0
  27. {batplot-1.1.8 → batplot-1.3.0}/batplot/utils.py +0 -0
  28. {batplot-1.1.8 → batplot-1.3.0}/batplot.egg-info/dependency_links.txt +0 -0
  29. {batplot-1.1.8 → batplot-1.3.0}/batplot.egg-info/entry_points.txt +0 -0
  30. {batplot-1.1.8 → batplot-1.3.0}/batplot.egg-info/requires.txt +0 -0
  31. {batplot-1.1.8 → batplot-1.3.0}/batplot.egg-info/top_level.txt +0 -0
  32. {batplot-1.1.8 → batplot-1.3.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: batplot
3
- Version: 1.1.8
3
+ Version: 1.3.0
4
4
  Summary: Interactive plotting for XRD, PDF, and XAS data (.xye, .xy, .qye, .dat, .csv, .gr, .nor, .chik, .chir)
5
5
  Author-email: Tian Dai <tianda@uio.no>
6
6
  License: MIT License
@@ -107,6 +107,12 @@ batplot --gc all # All .mpt/.csv files (.mpt needs --mass, .csv doesn't)
107
107
  batplot --cv all # All .mpt files (CV mode)
108
108
  batplot --dqdv all # All .csv files (dQdV mode)
109
109
  batplot --cpc all --mass 6.2 # All .mpt/.csv files (.mpt needs --mass, .csv doesn't)
110
+
111
+ # Batch processing with style/geometry: apply consistent formatting to all files
112
+ batplot --all mystyle.bps --gc --mass 7.0 # Apply .bps style to all GC files
113
+ batplot --all config.bpsg --cv # Apply .bpsg style+geometry to all CV files
114
+ batplot --all style.bps --dqdv # Apply style to all dQdV files
115
+ batplot --all geom.bpsg --cpc --mass 5.4 # Apply style+geometry to all CPC files
110
116
  ```
111
117
 
112
118
  ### Operando Analysis
@@ -58,6 +58,12 @@ batplot --gc all # All .mpt/.csv files (.mpt needs --mass, .csv doesn't)
58
58
  batplot --cv all # All .mpt files (CV mode)
59
59
  batplot --dqdv all # All .csv files (dQdV mode)
60
60
  batplot --cpc all --mass 6.2 # All .mpt/.csv files (.mpt needs --mass, .csv doesn't)
61
+
62
+ # Batch processing with style/geometry: apply consistent formatting to all files
63
+ batplot --all mystyle.bps --gc --mass 7.0 # Apply .bps style to all GC files
64
+ batplot --all config.bpsg --cv # Apply .bpsg style+geometry to all CV files
65
+ batplot --all style.bps --dqdv # Apply style to all dQdV files
66
+ batplot --all geom.bpsg --cpc --mass 5.4 # Apply style+geometry to all CPC files
61
67
  ```
62
68
 
63
69
  ### Operando Analysis
@@ -1,6 +1,6 @@
1
1
  """batplot package."""
2
2
 
3
3
  # Skip version check to avoid OneDrive timeout issues
4
- __version__ = "1.0.18"
4
+ __version__ = "1.3.0"
5
5
 
6
6
  __all__ = ["__version__"]
@@ -23,6 +23,8 @@ def _print_general_help() -> None:
23
23
  " batplot --gc FILE.mpt --mass 7.0 # EC GC from .mpt (requires --mass mg)\n"
24
24
  " batplot --gc FILE.csv # EC GC from supported .csv (no mass required)\n"
25
25
  " batplot --gc all --mass 7.0 # Batch: all .mpt/.csv in directory (.mpt needs --mass)\n"
26
+ " batplot --all --gc style.bps --mass 7 # Batch with style: apply style.bps to all GC files\n"
27
+ " batplot --all --cv config.bpsg # Batch with style+geom: apply to all CV files\n"
26
28
  " batplot --dqdv FILE.csv # EC dQ/dV from supported .csv\n"
27
29
  " batplot --dqdv all # Batch: all .csv in directory (dQdV mode)\n"
28
30
  " batplot --cv FILE.mpt # EC CV (cyclic voltammetry) from .mpt\n"
@@ -34,7 +36,8 @@ def _print_general_help() -> None:
34
36
  " • Quick plotting with sensible defaults, no config files needed\n"
35
37
  " • Supports many common file formats (see -h xy/ec/op)\n"
36
38
  " • Interactive menus (--interactive): styling, ranges, fonts, export, sessions\n"
37
- " • Batch processing: use 'all' or directory path with any mode\n\n"
39
+ " • Batch processing: use 'all' or directory path with any mode\n"
40
+ " • Batch styling: apply .bps/.bpsg files to all exports (use --all flag)\n\n"
38
41
 
39
42
  "More help:\n"
40
43
  " batplot -h xy # XY file plotting guide\n"
@@ -93,6 +96,11 @@ def _print_ec_help() -> None:
93
96
  " batplot --dqdv all # All .csv files (dQdV mode)\n"
94
97
  " batplot --cpc all --mass 5.4 # All .mpt/.csv files (.mpt requires --mass)\n"
95
98
  " batplot --gc /path/to/folder --mass 6 # Process specific directory\n\n"
99
+ "Batch mode with style/geometry: Apply .bps/.bpsg files to all batch exports.\n"
100
+ " batplot --all --gc style.bps --mass 7 # Apply style to all GC plots\n"
101
+ " batplot --all --cv config.bpsg # Apply style+geometry to all CV plots\n"
102
+ " batplot --all --dqdv my.bps # Apply style to all dQdV plots\n"
103
+ " batplot --all --cpc geom.bpsg --mass 6 # Apply style+geom to all CPC plots\n\n"
96
104
  "Interactive (--interactive): choose cycles, colors/palettes, line widths, axis scales (linear/log/symlog),\n"
97
105
  "rename axes, toggle ticks/titles/spines, print/export/import style (.bpcfg), save session (.pkl).\n"
98
106
  "Note: Batch mode exports SVG files automatically; --interactive is for single-file plotting only.\n"
@@ -139,6 +147,7 @@ def build_parser() -> argparse.ArgumentParser:
139
147
  parser.add_argument("--dqdv", action="store_true", help=argparse.SUPPRESS)
140
148
  parser.add_argument("--cv", action="store_true", help=argparse.SUPPRESS)
141
149
  parser.add_argument("--cpc", action="store_true", help=argparse.SUPPRESS)
150
+ parser.add_argument("--all", type=str, nargs='?', const='all', help=argparse.SUPPRESS)
142
151
  return parser
143
152
 
144
153
 
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import os
6
+ import json
6
7
  import numpy as np
7
8
  import matplotlib.pyplot as plt
8
9
 
@@ -16,6 +17,152 @@ from .readers import (
16
17
  from .utils import _confirm_overwrite
17
18
 
18
19
 
20
+ def _load_style_file(style_path: str) -> dict | None:
21
+ """Load a .bps, .bpsg, or .bpcfg style file.
22
+
23
+ Args:
24
+ style_path: Path to style configuration file
25
+
26
+ Returns:
27
+ Style configuration dict or None if loading fails
28
+ """
29
+ try:
30
+ with open(style_path, 'r', encoding='utf-8') as f:
31
+ cfg = json.load(f)
32
+ return cfg
33
+ except Exception as e:
34
+ print(f"Warning: Could not load style file {style_path}: {e}")
35
+ return None
36
+
37
+
38
+ def _apply_ec_style(fig, ax, cfg: dict):
39
+ """Apply style configuration to an EC batch plot.
40
+
41
+ Applies formatting from .bps/.bpsg files including fonts, colors,
42
+ tick parameters, and geometry (if present in .bpsg files).
43
+
44
+ Args:
45
+ fig: Matplotlib figure object
46
+ ax: Matplotlib axes object
47
+ cfg: Style configuration dictionary
48
+ """
49
+ try:
50
+ # Apply fonts
51
+ font_cfg = cfg.get('font', {})
52
+ if font_cfg:
53
+ family = font_cfg.get('family')
54
+ size = font_cfg.get('size')
55
+ if family:
56
+ plt.rcParams['font.sans-serif'] = [family] if isinstance(family, str) else family
57
+ if size is not None:
58
+ plt.rcParams['font.size'] = size
59
+
60
+ # Apply figure size if present
61
+ fig_cfg = cfg.get('figure', {})
62
+ if fig_cfg:
63
+ canvas_size = fig_cfg.get('canvas_size')
64
+ if canvas_size and isinstance(canvas_size, (list, tuple)) and len(canvas_size) == 2:
65
+ try:
66
+ fig.set_size_inches(canvas_size[0], canvas_size[1])
67
+ except Exception:
68
+ pass
69
+
70
+ # Apply tick parameters
71
+ ticks_cfg = cfg.get('ticks', {})
72
+ if ticks_cfg:
73
+ # Tick widths
74
+ widths = ticks_cfg.get('widths', {})
75
+ if widths.get('x_major') is not None:
76
+ ax.tick_params(axis='x', which='major', width=widths['x_major'])
77
+ if widths.get('x_minor') is not None:
78
+ ax.tick_params(axis='x', which='minor', width=widths['x_minor'])
79
+ if widths.get('y_major') is not None or widths.get('ly_major') is not None:
80
+ w = widths.get('y_major') or widths.get('ly_major')
81
+ ax.tick_params(axis='y', which='major', width=w)
82
+ if widths.get('y_minor') is not None or widths.get('ly_minor') is not None:
83
+ w = widths.get('y_minor') or widths.get('ly_minor')
84
+ ax.tick_params(axis='y', which='minor', width=w)
85
+
86
+ # Tick lengths
87
+ lengths = ticks_cfg.get('lengths', {})
88
+ if lengths.get('major') is not None:
89
+ ax.tick_params(axis='both', which='major', length=lengths['major'])
90
+ if lengths.get('minor') is not None:
91
+ ax.tick_params(axis='both', which='minor', length=lengths['minor'])
92
+
93
+ # Tick direction
94
+ direction = ticks_cfg.get('direction')
95
+ if direction:
96
+ ax.tick_params(axis='both', which='both', direction=direction)
97
+
98
+ # Apply geometry if present (for .bpsg files)
99
+ kind = cfg.get('kind', '')
100
+ if 'geom' in kind.lower() and 'geometry' in cfg:
101
+ geom = cfg.get('geometry', {})
102
+ if geom.get('xlabel'):
103
+ ax.set_xlabel(geom['xlabel'])
104
+ if geom.get('ylabel'):
105
+ ax.set_ylabel(geom['ylabel'])
106
+ if 'xlim' in geom and isinstance(geom['xlim'], (list, tuple)) and len(geom['xlim']) == 2:
107
+ try:
108
+ ax.set_xlim(geom['xlim'][0], geom['xlim'][1])
109
+ except Exception:
110
+ pass
111
+ if 'ylim' in geom and isinstance(geom['ylim'], (list, tuple)) and len(geom['ylim']) == 2:
112
+ try:
113
+ ax.set_ylim(geom['ylim'][0], geom['ylim'][1])
114
+ except Exception:
115
+ pass
116
+
117
+ # Apply line colors if available (for GC/CV/dQdV modes)
118
+ lines_cfg = cfg.get('lines', [])
119
+ if lines_cfg and len(ax.lines) > 0:
120
+ for entry in lines_cfg:
121
+ idx = entry.get('index')
122
+ if idx is not None and 0 <= idx < len(ax.lines):
123
+ ln = ax.lines[idx]
124
+ if 'color' in entry:
125
+ try:
126
+ ln.set_color(entry['color'])
127
+ except Exception:
128
+ pass
129
+ if 'linewidth' in entry:
130
+ try:
131
+ ln.set_linewidth(entry['linewidth'])
132
+ except Exception:
133
+ pass
134
+ if 'linestyle' in entry:
135
+ try:
136
+ ln.set_linestyle(entry['linestyle'])
137
+ except Exception:
138
+ pass
139
+
140
+ # Apply spine configuration
141
+ spines_cfg = cfg.get('spines', {})
142
+ for spine_name, spine_props in spines_cfg.items():
143
+ if spine_name in ax.spines:
144
+ sp = ax.spines[spine_name]
145
+ if 'lw' in spine_props or 'linewidth' in spine_props:
146
+ try:
147
+ lw = spine_props.get('lw') or spine_props.get('linewidth')
148
+ sp.set_linewidth(lw)
149
+ except Exception:
150
+ pass
151
+ if 'color' in spine_props:
152
+ try:
153
+ sp.set_edgecolor(spine_props['color'])
154
+ except Exception:
155
+ pass
156
+ if 'visible' in spine_props:
157
+ try:
158
+ sp.set_visible(spine_props['visible'])
159
+ except Exception:
160
+ pass
161
+
162
+ except Exception as e:
163
+ print(f"Warning: Error applying style: {e}")
164
+
165
+
19
166
  def batch_process(directory: str, args):
20
167
  print(f"Batch mode: scanning {directory}")
21
168
  supported_ext = {'.xye', '.xy', '.qye', '.dat', '.csv', '.gr', '.nor', '.chik', '.chir', '.txt'}
@@ -168,15 +315,44 @@ def batch_process_ec(directory: str, args):
168
315
  Supports GC (.mpt/.csv), CV (.mpt), dQdV (.csv), and CPC (.mpt/.csv) modes.
169
316
  Exports SVG plots to batplot_svg subdirectory.
170
317
 
318
+ Can apply style/geometry from .bps/.bpsg files using --all flag:
319
+ batplot --all --gc style.bps # Apply style.bps to all .mpt/.csv GC files
320
+ batplot --all --cv style.bpsg # Apply style+geom to all CV files
321
+ batplot --all --dqdv mystyle.bps # Apply style to all dQdV files
322
+ batplot --all --cpc config.bpsg # Apply to all CPC files
323
+
171
324
  Note: For GC and CPC modes with .csv files, --mass is not required as the
172
325
  capacity data is already in the file. For .mpt files, --mass is required.
173
326
 
174
327
  Args:
175
328
  directory: Directory containing EC files
176
- args: Argument namespace with mode flags (gc, cv, dqdv, cpc) and mass
329
+ args: Argument namespace with mode flags (gc, cv, dqdv, cpc), mass, and all
177
330
  """
178
331
  print(f"EC Batch mode: scanning {directory}")
179
332
 
333
+ # Check if --all flag was used with a style file
334
+ style_cfg = None
335
+ style_file_arg = getattr(args, 'all', None)
336
+ if style_file_arg and style_file_arg != 'all':
337
+ # User provided a style file path
338
+ style_path = style_file_arg if os.path.isabs(style_file_arg) else os.path.join(directory, style_file_arg)
339
+ if os.path.exists(style_path) and style_path.lower().endswith(('.bps', '.bpsg', '.bpcfg')):
340
+ style_cfg = _load_style_file(style_path)
341
+ if style_cfg:
342
+ print(f"Using style file: {os.path.basename(style_path)}")
343
+ else:
344
+ # Try to find the file in current directory
345
+ for ext in ['.bps', '.bpsg', '.bpcfg']:
346
+ test_path = style_file_arg if style_file_arg.endswith(ext) else style_file_arg + ext
347
+ test_full = os.path.join(directory, test_path)
348
+ if os.path.exists(test_full):
349
+ style_cfg = _load_style_file(test_full)
350
+ if style_cfg:
351
+ print(f"Using style file: {os.path.basename(test_full)}")
352
+ break
353
+ if not style_cfg:
354
+ print(f"Warning: Could not find style file '{style_file_arg}'")
355
+
180
356
  # Determine which EC mode is active
181
357
  mode = None
182
358
  if getattr(args, 'gc', False):
@@ -490,6 +666,13 @@ def batch_process_ec(directory: str, args):
490
666
  ax_b.legend()
491
667
  ax_b.set_title(f"{fname}")
492
668
 
669
+ # Apply style/geometry if provided via --all flag
670
+ if style_cfg:
671
+ try:
672
+ _apply_ec_style(fig_b, ax_b, style_cfg)
673
+ except Exception as e:
674
+ print(f" Warning: Could not apply style to {fname}: {e}")
675
+
493
676
  # Adjust layout and save
494
677
  fig_b.subplots_adjust(left=0.18, right=0.97, bottom=0.16, top=0.90)
495
678
  out_name = os.path.splitext(fname)[0] + f"_{mode}.svg"
@@ -98,6 +98,11 @@ def batplot_main() -> int:
98
98
  getattr(args, 'cpc', False)
99
99
  ])
100
100
 
101
+ # Check for --all flag (with or without style file)
102
+ if ec_mode_active and getattr(args, 'all', None) is not None:
103
+ batch_process_ec(os.getcwd(), args)
104
+ exit()
105
+
101
106
  if ec_mode_active and len(args.files) == 1:
102
107
  sole = args.files[0]
103
108
  if sole.lower() == 'all':
@@ -1362,6 +1367,23 @@ def batplot_main() -> int:
1362
1367
  ax.tick_params(axis='y', which='minor', width=tw['y_minor'])
1363
1368
  except Exception:
1364
1369
  pass
1370
+ # Tick lengths restore
1371
+ try:
1372
+ tl = sess.get('tick_lengths', {})
1373
+ if tl.get('x_major') is not None or tl.get('y_major') is not None:
1374
+ major_len = tl.get('x_major') or tl.get('y_major')
1375
+ ax.tick_params(axis='both', which='major', length=major_len)
1376
+ if not hasattr(fig, '_tick_lengths'):
1377
+ fig._tick_lengths = {}
1378
+ fig._tick_lengths['major'] = major_len
1379
+ if tl.get('x_minor') is not None or tl.get('y_minor') is not None:
1380
+ minor_len = tl.get('x_minor') or tl.get('y_minor')
1381
+ ax.tick_params(axis='both', which='minor', length=minor_len)
1382
+ if not hasattr(fig, '_tick_lengths'):
1383
+ fig._tick_lengths = {}
1384
+ fig._tick_lengths['minor'] = minor_len
1385
+ except Exception:
1386
+ pass
1365
1387
  # Rebuild label texts
1366
1388
  for i, lab in enumerate(labels_list):
1367
1389
  txt = ax.text(1.0, 1.0, f"{i+1}: {lab}", ha='right', va='top', transform=ax.transAxes,
@@ -1374,6 +1396,7 @@ def batplot_main() -> int:
1374
1396
  cif_numbering_enabled = True
1375
1397
  cif_extend_suspended = False
1376
1398
  show_cif_hkl = sess.get('show_cif_hkl', False)
1399
+ show_cif_titles = sess.get('show_cif_titles', True)
1377
1400
  # Provide minimal stubs to satisfy interactive menu dependencies
1378
1401
  # Axis mode restoration informs downstream toggles (e.g., CIF conversions, crosshair availability)
1379
1402
  axis_mode_restored = sess.get('axis_mode', 'unknown')
@@ -1652,6 +1675,8 @@ def batplot_main() -> int:
1652
1675
  if args.xaxis and args.xaxis.lower() in ("2theta","two_theta","tth"):
1653
1676
  axis_mode = "2theta"
1654
1677
  else:
1678
+ # If wavelength is provided, user wants to convert to Q
1679
+ # CIF files are in Q space
1655
1680
  axis_mode = "Q"
1656
1681
  elif args.xaxis:
1657
1682
  axis_mode = args.xaxis
@@ -1665,6 +1690,16 @@ def batplot_main() -> int:
1665
1690
  use_k = axis_mode == "k" # NEW
1666
1691
  use_rft = axis_mode == "rft" # NEW
1667
1692
 
1693
+ # Validate: if using 2theta mode with CIF files, wavelength is required
1694
+ if use_2th and any_cif and not wavelength_file:
1695
+ raise ValueError(
1696
+ "Cannot display CIF files in 2θ mode without wavelength.\n"
1697
+ "Please provide wavelength using:\n"
1698
+ " --wl <wavelength_in_angstrom>\n"
1699
+ " or include wavelength in filename (e.g., data_wl1.5406.xy)\n"
1700
+ " or use Q mode (remove --xaxis 2theta)"
1701
+ )
1702
+
1668
1703
  # ---------------- Read and plot files ----------------
1669
1704
  # Helper to extract discrete peak positions from a simulated CIF pattern by local maxima picking
1670
1705
  def _extract_peak_positions(Q_array, I_array, min_rel_height=0.05):
@@ -1702,6 +1737,7 @@ def batplot_main() -> int:
1702
1737
  # Cached wavelength for CIF tick conversion (prevents interactive blocking prompts)
1703
1738
  cif_cached_wavelength = None
1704
1739
  show_cif_hkl = False
1740
+ show_cif_titles = True # show CIF filename labels by default
1705
1741
 
1706
1742
  for idx_file, file_entry in enumerate(args.files):
1707
1743
  parts = file_entry.split(":")
@@ -2058,10 +2094,12 @@ def batplot_main() -> int:
2058
2094
  ln, = ax.plot([p,p],[y_line, y_line+0.02*yr], color=color, lw=1.0, alpha=0.9, zorder=3)
2059
2095
  new_art.append(ln)
2060
2096
  # Removed numbering; keep space padding (placed per CIF row)
2061
- label_text = f" {lab}"
2062
- txt = ax.text(ax.get_xlim()[0], y_line + 0.005*yr, label_text,
2063
- ha='left', va='bottom', fontsize=max(8,int(0.55*plt.rcParams.get('font.size',12))), color=color)
2064
- new_art.append(txt)
2097
+ # Only add title label if show_cif_titles is True
2098
+ if globals().get('show_cif_titles', True):
2099
+ label_text = f" {lab}"
2100
+ txt = ax.text(ax.get_xlim()[0], y_line + 0.005*yr, label_text,
2101
+ ha='left', va='bottom', fontsize=max(8,int(0.55*plt.rcParams.get('font.size',12))), color=color)
2102
+ new_art.append(txt)
2065
2103
  ax._cif_tick_art = new_art
2066
2104
  # Store simplified metadata for hover: list of dicts with 'x','y','label'
2067
2105
  hover_meta = []
@@ -2264,6 +2302,7 @@ def batplot_main() -> int:
2264
2302
  'cif_hkl_map': cif_hkl_map,
2265
2303
  'cif_hkl_label_map': cif_hkl_label_map,
2266
2304
  'show_cif_hkl': show_cif_hkl,
2305
+ 'show_cif_titles': show_cif_titles,
2267
2306
  'cif_extend_suspended': cif_extend_suspended,
2268
2307
  'keep_canvas_fixed': keep_canvas_fixed,
2269
2308
  }