batplot 1.3.0__tar.gz → 1.3.1__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.3.0 → batplot-1.3.1}/PKG-INFO +4 -3
- {batplot-1.3.0 → batplot-1.3.1}/README.md +3 -2
- batplot-1.3.1/batplot/__init__.py +5 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/args.py +1 -1
- {batplot-1.3.0 → batplot-1.3.1}/batplot/batplot.py +17 -4
- {batplot-1.3.0 → batplot-1.3.1}/batplot/cpc_interactive.py +1 -1
- {batplot-1.3.0 → batplot-1.3.1}/batplot/electrochem_interactive.py +1 -1
- {batplot-1.3.0 → batplot-1.3.1}/batplot/interactive.py +16 -4
- {batplot-1.3.0 → batplot-1.3.1}/batplot/operando_ec_interactive.py +4 -4
- {batplot-1.3.0 → batplot-1.3.1}/batplot/session.py +11 -4
- {batplot-1.3.0 → batplot-1.3.1}/batplot/style.py +11 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/ui.py +3 -3
- {batplot-1.3.0 → batplot-1.3.1}/batplot.egg-info/PKG-INFO +4 -3
- {batplot-1.3.0 → batplot-1.3.1}/pyproject.toml +1 -1
- batplot-1.3.0/batplot/__init__.py +0 -6
- {batplot-1.3.0 → batplot-1.3.1}/LICENSE +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/batch.py +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/batplot_new.py +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/cif.py +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/cli.py +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/converters.py +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/modes.py +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/operando.py +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/plotting.py +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/readers.py +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot/utils.py +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot.egg-info/SOURCES.txt +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot.egg-info/dependency_links.txt +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot.egg-info/entry_points.txt +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot.egg-info/requires.txt +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/batplot.egg-info/top_level.txt +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/setup.cfg +0 -0
- {batplot-1.3.0 → batplot-1.3.1}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: batplot
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1
|
|
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
|
|
@@ -60,7 +60,7 @@ Dynamic: license-file
|
|
|
60
60
|
- **Operando Analysis**: Correlate in-situ characterizations (XRD/PDF/XAS) with electrochemical data
|
|
61
61
|
- **Interactive plotting**: Real-time editing customized for each type of plottings
|
|
62
62
|
- **Session Persistence**: Save and reload complete plot states with `.pkl` files
|
|
63
|
-
- **Style Management**: Import/export plot styles as `.
|
|
63
|
+
- **Style Management**: Import/export plot styles as `.bps`/`.bpsg` files
|
|
64
64
|
- **Batch Processing**: Plot multiple files simultaneously with automatic SVG export
|
|
65
65
|
|
|
66
66
|
## Installation
|
|
@@ -130,6 +130,7 @@ batplot --operando --interactive
|
|
|
130
130
|
| **Electrochemistry** | `.csv` (Neware), `.mpt` (Biologic) |
|
|
131
131
|
| **XRD / PDF** | `.xye`, `.xy`, `.qye`, `.dat` |
|
|
132
132
|
| **XAS** | `.nor`, `.chik`, `.chir` |
|
|
133
|
+
| **Others** | `user defined` (plot first two columns as x and y) |
|
|
133
134
|
|
|
134
135
|
## Interactive Features
|
|
135
136
|
|
|
@@ -137,7 +138,7 @@ When launched with `--interactive`:
|
|
|
137
138
|
- **Cycle/Scan Control**: Toggle visibility, change colors
|
|
138
139
|
- **Styling**: Line widths, markers, transparency
|
|
139
140
|
- **Axes**: Labels, limits, ticks, spine styles
|
|
140
|
-
- **Export**: Save sessions (`.pkl`), styles (`.
|
|
141
|
+
- **Export**: Save sessions (`.pkl`), styles (`.bps`/`.bpsg`), or high-res images
|
|
141
142
|
- **Live Preview**: All changes update in real-time
|
|
142
143
|
|
|
143
144
|
## Documentation
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
- **Operando Analysis**: Correlate in-situ characterizations (XRD/PDF/XAS) with electrochemical data
|
|
12
12
|
- **Interactive plotting**: Real-time editing customized for each type of plottings
|
|
13
13
|
- **Session Persistence**: Save and reload complete plot states with `.pkl` files
|
|
14
|
-
- **Style Management**: Import/export plot styles as `.
|
|
14
|
+
- **Style Management**: Import/export plot styles as `.bps`/`.bpsg` files
|
|
15
15
|
- **Batch Processing**: Plot multiple files simultaneously with automatic SVG export
|
|
16
16
|
|
|
17
17
|
## Installation
|
|
@@ -81,6 +81,7 @@ batplot --operando --interactive
|
|
|
81
81
|
| **Electrochemistry** | `.csv` (Neware), `.mpt` (Biologic) |
|
|
82
82
|
| **XRD / PDF** | `.xye`, `.xy`, `.qye`, `.dat` |
|
|
83
83
|
| **XAS** | `.nor`, `.chik`, `.chir` |
|
|
84
|
+
| **Others** | `user defined` (plot first two columns as x and y) |
|
|
84
85
|
|
|
85
86
|
## Interactive Features
|
|
86
87
|
|
|
@@ -88,7 +89,7 @@ When launched with `--interactive`:
|
|
|
88
89
|
- **Cycle/Scan Control**: Toggle visibility, change colors
|
|
89
90
|
- **Styling**: Line widths, markers, transparency
|
|
90
91
|
- **Axes**: Labels, limits, ticks, spine styles
|
|
91
|
-
- **Export**: Save sessions (`.pkl`), styles (`.
|
|
92
|
+
- **Export**: Save sessions (`.pkl`), styles (`.bps`/`.bpsg`), or high-res images
|
|
92
93
|
- **Live Preview**: All changes update in real-time
|
|
93
94
|
|
|
94
95
|
## Documentation
|
|
@@ -102,7 +102,7 @@ def _print_ec_help() -> None:
|
|
|
102
102
|
" batplot --all --dqdv my.bps # Apply style to all dQdV plots\n"
|
|
103
103
|
" batplot --all --cpc geom.bpsg --mass 6 # Apply style+geom to all CPC plots\n\n"
|
|
104
104
|
"Interactive (--interactive): choose cycles, colors/palettes, line widths, axis scales (linear/log/symlog),\n"
|
|
105
|
-
"rename axes, toggle ticks/titles/spines, print/export/import style (.
|
|
105
|
+
"rename axes, toggle ticks/titles/spines, print/export/import style (.bps/.bpsg), save session (.pkl).\n"
|
|
106
106
|
"Note: Batch mode exports SVG files automatically; --interactive is for single-file plotting only.\n"
|
|
107
107
|
)
|
|
108
108
|
print(msg)
|
|
@@ -1297,10 +1297,19 @@ def batplot_main() -> int:
|
|
|
1297
1297
|
delta = sess.get('delta', 0.0)
|
|
1298
1298
|
ax.set_xlabel(sess.get('axis', {}).get('xlabel', 'X'))
|
|
1299
1299
|
ax.set_ylabel(sess.get('axis', {}).get('ylabel', 'Intensity'))
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1300
|
+
|
|
1301
|
+
# Restore normalization ranges (if saved)
|
|
1302
|
+
axis_cfg = sess.get('axis', {})
|
|
1303
|
+
if 'norm_xlim' in axis_cfg and axis_cfg['norm_xlim'] is not None:
|
|
1304
|
+
ax._norm_xlim = tuple(axis_cfg['norm_xlim'])
|
|
1305
|
+
if 'norm_ylim' in axis_cfg and axis_cfg['norm_ylim'] is not None:
|
|
1306
|
+
ax._norm_ylim = tuple(axis_cfg['norm_ylim'])
|
|
1307
|
+
|
|
1308
|
+
# Restore display limits
|
|
1309
|
+
if 'xlim' in axis_cfg:
|
|
1310
|
+
ax.set_xlim(*axis_cfg['xlim'])
|
|
1311
|
+
if 'ylim' in axis_cfg:
|
|
1312
|
+
ax.set_ylim(*axis_cfg['ylim'])
|
|
1304
1313
|
# Apply figure size & dpi if stored
|
|
1305
1314
|
fig_cfg = sess.get('figure', {})
|
|
1306
1315
|
try:
|
|
@@ -1881,6 +1890,10 @@ def batplot_main() -> int:
|
|
|
1881
1890
|
ax.autoscale_view()
|
|
1882
1891
|
fig.canvas.draw()
|
|
1883
1892
|
|
|
1893
|
+
# Store the x/y limits that were used for data normalization (.bpsg save/restore)
|
|
1894
|
+
ax._norm_xlim = tuple(ax.get_xlim())
|
|
1895
|
+
ax._norm_ylim = tuple(ax.get_ylim())
|
|
1896
|
+
|
|
1884
1897
|
# Define a sample_tick safely (may be None if no labels yet)
|
|
1885
1898
|
sample_tick = None
|
|
1886
1899
|
xt_lbls = ax.get_xticklabels()
|
|
@@ -1398,7 +1398,7 @@ def cpc_interactive_menu(fig, ax, ax2, sc_charge, sc_discharge, sc_eff, file_dat
|
|
|
1398
1398
|
print("Available style files:")
|
|
1399
1399
|
for i, f in enumerate(files, 1):
|
|
1400
1400
|
print(f" {i}: {f}")
|
|
1401
|
-
inp = input("Enter number or filename (.bps/.bpsg
|
|
1401
|
+
inp = input("Enter number or filename (.bps/.bpsg; q=cancel): ").strip()
|
|
1402
1402
|
if not inp or inp.lower() == 'q':
|
|
1403
1403
|
_print_menu(); continue
|
|
1404
1404
|
push_state("import-style")
|
|
@@ -1029,7 +1029,7 @@ def electrochem_interactive_menu(fig, ax, cycle_lines: Dict[int, Dict[str, Optio
|
|
|
1029
1029
|
print("Available style files:")
|
|
1030
1030
|
for _i, _f in enumerate(_style_files, 1):
|
|
1031
1031
|
print(f" {_i}: {_f}")
|
|
1032
|
-
inp = input("Enter number or filename (.bps/.bpsg
|
|
1032
|
+
inp = input("Enter number or filename (.bps/.bpsg, q=cancel): ").strip()
|
|
1033
1033
|
if not inp or inp.lower() == 'q':
|
|
1034
1034
|
_print_menu(len(all_cycles), is_dqdv); continue
|
|
1035
1035
|
push_state("import-style")
|
|
@@ -1022,6 +1022,7 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
|
|
|
1022
1022
|
print("Canceled.")
|
|
1023
1023
|
continue
|
|
1024
1024
|
target_path = os.path.join(folder, name)
|
|
1025
|
+
skip_confirm = True # Already confirmed above
|
|
1025
1026
|
else:
|
|
1026
1027
|
print("Invalid number.")
|
|
1027
1028
|
continue
|
|
@@ -1032,11 +1033,13 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
|
|
|
1032
1033
|
if ext == '':
|
|
1033
1034
|
name = name + '.pkl'
|
|
1034
1035
|
target_path = name if os.path.isabs(name) else os.path.join(folder, name)
|
|
1036
|
+
skip_confirm = False # Let dump_session ask
|
|
1035
1037
|
if os.path.exists(target_path):
|
|
1036
1038
|
yn = input(f"'{os.path.basename(target_path)}' exists. Overwrite? (y/n): ").strip().lower()
|
|
1037
1039
|
if yn != 'y':
|
|
1038
1040
|
print("Canceled.")
|
|
1039
1041
|
continue
|
|
1042
|
+
skip_confirm = True # Already confirmed
|
|
1040
1043
|
# Delegate to session dumper
|
|
1041
1044
|
_bp_dump_session(
|
|
1042
1045
|
target_path,
|
|
@@ -1055,6 +1058,7 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
|
|
|
1055
1058
|
cif_hkl_label_map=(getattr(_bp, 'cif_hkl_label_map', None) if _bp is not None else None),
|
|
1056
1059
|
show_cif_hkl=(bool(getattr(_bp,'show_cif_hkl', False)) if _bp is not None else False),
|
|
1057
1060
|
show_cif_titles=(bool(getattr(_bp,'show_cif_titles', True)) if _bp is not None else True),
|
|
1061
|
+
skip_confirm=skip_confirm,
|
|
1058
1062
|
)
|
|
1059
1063
|
print(f"Saved session to {target_path}")
|
|
1060
1064
|
except Exception as e:
|
|
@@ -1698,6 +1702,10 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
|
|
|
1698
1702
|
push_state("font-change")
|
|
1699
1703
|
fs_val = float(fs)
|
|
1700
1704
|
apply_font_changes(new_size=fs_val)
|
|
1705
|
+
# Reposition top/right labels to match new tick label sizes
|
|
1706
|
+
position_top_xlabel()
|
|
1707
|
+
position_right_ylabel()
|
|
1708
|
+
fig.canvas.draw()
|
|
1701
1709
|
except Exception as e:
|
|
1702
1710
|
print(f"Error changing font size: {e}")
|
|
1703
1711
|
elif subkey == 'f':
|
|
@@ -1723,6 +1731,10 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
|
|
|
1723
1731
|
push_state("font-change")
|
|
1724
1732
|
print(f"Setting font family to: {ft}")
|
|
1725
1733
|
apply_font_changes(new_family=ft)
|
|
1734
|
+
# Reposition top/right labels to match new tick label sizes
|
|
1735
|
+
position_top_xlabel()
|
|
1736
|
+
position_right_ylabel()
|
|
1737
|
+
fig.canvas.draw()
|
|
1726
1738
|
except Exception as e:
|
|
1727
1739
|
print(f"Error changing font family: {e}")
|
|
1728
1740
|
else:
|
|
@@ -2048,13 +2060,13 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
|
|
|
2048
2060
|
style_menu_active = True
|
|
2049
2061
|
while style_menu_active:
|
|
2050
2062
|
print_style_info()
|
|
2051
|
-
# List available .bpcfg to speed up export/import workflows
|
|
2063
|
+
# List available style files (.bps, .bpsg, .bpcfg) to speed up export/import workflows
|
|
2052
2064
|
try:
|
|
2053
|
-
_bpcfg_files = sorted([f for f in os.listdir(os.getcwd()) if f.lower().endswith('.bpcfg')])
|
|
2065
|
+
_bpcfg_files = sorted([f for f in os.listdir(os.getcwd()) if f.lower().endswith(('.bps', '.bpsg', '.bpcfg'))])
|
|
2054
2066
|
except Exception:
|
|
2055
2067
|
_bpcfg_files = []
|
|
2056
2068
|
if _bpcfg_files:
|
|
2057
|
-
print("Existing
|
|
2069
|
+
print("Existing style files (.bps/.bpsg):")
|
|
2058
2070
|
for _i, _f in enumerate(_bpcfg_files, 1):
|
|
2059
2071
|
print(f" {_i}: {_f}")
|
|
2060
2072
|
sub = input("Style submenu: (e=export, q=return, r=refresh): ").strip().lower()
|
|
@@ -2081,7 +2093,7 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
|
|
|
2081
2093
|
print("Available style files:")
|
|
2082
2094
|
for _i, _f in enumerate(_style_files, 1):
|
|
2083
2095
|
print(f" {_i}: {_f}")
|
|
2084
|
-
inp = input("Enter number or filename (.bps/.bpsg
|
|
2096
|
+
inp = input("Enter number or filename (.bps/.bpsg; q=cancel): ").strip()
|
|
2085
2097
|
if not inp or inp.lower() == 'q':
|
|
2086
2098
|
print("Canceled.")
|
|
2087
2099
|
continue
|
|
@@ -1938,13 +1938,13 @@ def operando_ec_interactive_menu(fig, ax, im, cbar, ec_ax):
|
|
|
1938
1938
|
print(" (no EC line found)")
|
|
1939
1939
|
|
|
1940
1940
|
print("-------------------------\n")
|
|
1941
|
-
# List .bpcfg
|
|
1941
|
+
# List style files (.bps, .bpsg, .bpcfg) for convenience
|
|
1942
1942
|
try:
|
|
1943
|
-
_bpcfg_files = sorted([f for f in os.listdir(os.getcwd()) if f.lower().endswith('.bpcfg')])
|
|
1943
|
+
_bpcfg_files = sorted([f for f in os.listdir(os.getcwd()) if f.lower().endswith(('.bps', '.bpsg', '.bpcfg'))])
|
|
1944
1944
|
except Exception:
|
|
1945
1945
|
_bpcfg_files = []
|
|
1946
1946
|
if _bpcfg_files:
|
|
1947
|
-
print("Existing
|
|
1947
|
+
print("Existing style files (.bps/.bpsg):")
|
|
1948
1948
|
for _i, _f in enumerate(_bpcfg_files, 1):
|
|
1949
1949
|
print(f" {_i}: {_f}")
|
|
1950
1950
|
sub = input("Style: (e=export, q=return): ").strip().lower()
|
|
@@ -2145,7 +2145,7 @@ def operando_ec_interactive_menu(fig, ax, im, cbar, ec_ax):
|
|
|
2145
2145
|
print("Available style files:")
|
|
2146
2146
|
for _i, _f in enumerate(_style_files, 1):
|
|
2147
2147
|
print(f" {_i}: {_f}")
|
|
2148
|
-
inp = input("Enter number or filename (.bps/.bpsg
|
|
2148
|
+
inp = input("Enter number or filename (.bps/.bpsg, q=cancel): ").strip()
|
|
2149
2149
|
if not inp or inp.lower() == 'q':
|
|
2150
2150
|
print_menu(); continue
|
|
2151
2151
|
_snapshot("import-style")
|
|
@@ -36,10 +36,12 @@ def dump_session(
|
|
|
36
36
|
cif_hkl_label_map: Dict[str, Dict[float, str]] | None = None,
|
|
37
37
|
show_cif_hkl: bool | None = None,
|
|
38
38
|
show_cif_titles: bool | None = None,
|
|
39
|
+
skip_confirm: bool = False,
|
|
39
40
|
) -> None:
|
|
40
41
|
"""Serialize the current interactive session to a pickle file.
|
|
41
42
|
|
|
42
43
|
Parameters mirror the state captured in the original inline helper.
|
|
44
|
+
skip_confirm: If True, skip overwrite confirmation (already confirmed by caller).
|
|
43
45
|
"""
|
|
44
46
|
|
|
45
47
|
# Infer axis mode string
|
|
@@ -172,6 +174,8 @@ def dump_session(
|
|
|
172
174
|
'ylabel': ax.get_ylabel(),
|
|
173
175
|
'xlim': ax.get_xlim(),
|
|
174
176
|
'ylim': ax.get_ylim(),
|
|
177
|
+
'norm_xlim': getattr(ax, '_norm_xlim', None), # x-range used for normalization
|
|
178
|
+
'norm_ylim': getattr(ax, '_norm_ylim', None), # y-range used for normalization
|
|
175
179
|
},
|
|
176
180
|
'figure': {
|
|
177
181
|
'size': tuple(map(float, fig.get_size_inches())),
|
|
@@ -211,10 +215,13 @@ def dump_session(
|
|
|
211
215
|
'has_bottom_x': bool(ax.get_xlabel()),
|
|
212
216
|
'has_left_y': bool(ax.get_ylabel()),
|
|
213
217
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
+
if skip_confirm:
|
|
219
|
+
target = filename
|
|
220
|
+
else:
|
|
221
|
+
target = _confirm_overwrite(filename)
|
|
222
|
+
if not target:
|
|
223
|
+
print("Session save canceled.")
|
|
224
|
+
return
|
|
218
225
|
with open(target, 'wb') as f:
|
|
219
226
|
pickle.dump(sess, f)
|
|
220
227
|
print(f"Session saved to {target}")
|
|
@@ -287,6 +287,9 @@ def export_style_config(
|
|
|
287
287
|
'ylabel': ax.get_ylabel() or '',
|
|
288
288
|
'xlim': list(ax.get_xlim()),
|
|
289
289
|
'ylim': list(ax.get_ylim()),
|
|
290
|
+
# Store the x/y ranges that the current data was normalized to
|
|
291
|
+
'norm_xlim': list(getattr(ax, '_norm_xlim', ax.get_xlim())),
|
|
292
|
+
'norm_ylim': list(getattr(ax, '_norm_ylim', ax.get_ylim())),
|
|
290
293
|
}
|
|
291
294
|
default_ext = '.bpsg'
|
|
292
295
|
else:
|
|
@@ -672,6 +675,14 @@ def apply_style_config(
|
|
|
672
675
|
ax.set_xlabel(geom['xlabel'])
|
|
673
676
|
if 'ylabel' in geom and geom['ylabel']:
|
|
674
677
|
ax.set_ylabel(geom['ylabel'])
|
|
678
|
+
|
|
679
|
+
# Restore normalization ranges (if saved)
|
|
680
|
+
if 'norm_xlim' in geom and isinstance(geom['norm_xlim'], list) and len(geom['norm_xlim']) == 2:
|
|
681
|
+
ax._norm_xlim = tuple(geom['norm_xlim'])
|
|
682
|
+
if 'norm_ylim' in geom and isinstance(geom['norm_ylim'], list) and len(geom['norm_ylim']) == 2:
|
|
683
|
+
ax._norm_ylim = tuple(geom['norm_ylim'])
|
|
684
|
+
|
|
685
|
+
# Restore display limits
|
|
675
686
|
if 'xlim' in geom and isinstance(geom['xlim'], list) and len(geom['xlim']) == 2:
|
|
676
687
|
ax.set_xlim(geom['xlim'][0], geom['xlim'][1])
|
|
677
688
|
if 'ylim' in geom and isinstance(geom['ylim'], list) and len(geom['ylim']) == 2:
|
|
@@ -197,10 +197,10 @@ def position_right_ylabel(ax, fig, tick_state: Dict[str, bool]):
|
|
|
197
197
|
except Exception:
|
|
198
198
|
pass
|
|
199
199
|
|
|
200
|
-
# Convert to points and add gap (match
|
|
200
|
+
# Convert to points and add gap (6pt gap to visually match left labelpad=8pt)
|
|
201
201
|
if max_w_px > 0:
|
|
202
202
|
tick_width_pts = max_w_px * 72.0 / dpi
|
|
203
|
-
dx_pts = tick_width_pts +
|
|
203
|
+
dx_pts = tick_width_pts + 6.0 # 6pt gap to visually match left labelpad
|
|
204
204
|
else:
|
|
205
205
|
dx_pts = 6.0 # Minimal spacing when no tick labels (match small labelpad)
|
|
206
206
|
|
|
@@ -634,4 +634,4 @@ __all__ = [
|
|
|
634
634
|
'ensure_text_visibility',
|
|
635
635
|
'resize_plot_frame',
|
|
636
636
|
'resize_canvas',
|
|
637
|
-
]
|
|
637
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: batplot
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1
|
|
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
|
|
@@ -60,7 +60,7 @@ Dynamic: license-file
|
|
|
60
60
|
- **Operando Analysis**: Correlate in-situ characterizations (XRD/PDF/XAS) with electrochemical data
|
|
61
61
|
- **Interactive plotting**: Real-time editing customized for each type of plottings
|
|
62
62
|
- **Session Persistence**: Save and reload complete plot states with `.pkl` files
|
|
63
|
-
- **Style Management**: Import/export plot styles as `.
|
|
63
|
+
- **Style Management**: Import/export plot styles as `.bps`/`.bpsg` files
|
|
64
64
|
- **Batch Processing**: Plot multiple files simultaneously with automatic SVG export
|
|
65
65
|
|
|
66
66
|
## Installation
|
|
@@ -130,6 +130,7 @@ batplot --operando --interactive
|
|
|
130
130
|
| **Electrochemistry** | `.csv` (Neware), `.mpt` (Biologic) |
|
|
131
131
|
| **XRD / PDF** | `.xye`, `.xy`, `.qye`, `.dat` |
|
|
132
132
|
| **XAS** | `.nor`, `.chik`, `.chir` |
|
|
133
|
+
| **Others** | `user defined` (plot first two columns as x and y) |
|
|
133
134
|
|
|
134
135
|
## Interactive Features
|
|
135
136
|
|
|
@@ -137,7 +138,7 @@ When launched with `--interactive`:
|
|
|
137
138
|
- **Cycle/Scan Control**: Toggle visibility, change colors
|
|
138
139
|
- **Styling**: Line widths, markers, transparency
|
|
139
140
|
- **Axes**: Labels, limits, ticks, spine styles
|
|
140
|
-
- **Export**: Save sessions (`.pkl`), styles (`.
|
|
141
|
+
- **Export**: Save sessions (`.pkl`), styles (`.bps`/`.bpsg`), or high-res images
|
|
141
142
|
- **Live Preview**: All changes update in real-time
|
|
142
143
|
|
|
143
144
|
## Documentation
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "batplot"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.1"
|
|
8
8
|
description = "Interactive plotting for XRD, PDF, and XAS data (.xye, .xy, .qye, .dat, .csv, .gr, .nor, .chik, .chir)"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Tian Dai", email = "tianda@uio.no" }
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|