batplot 1.8.5__tar.gz → 1.8.8__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.5/batplot.egg-info → batplot-1.8.8}/PKG-INFO +1 -1
- {batplot-1.8.5 → batplot-1.8.8}/batplot/__init__.py +1 -1
- {batplot-1.8.5 → batplot-1.8.8}/batplot/batplot.py +145 -55
- {batplot-1.8.5 → batplot-1.8.8}/batplot/cpc_interactive.py +286 -140
- {batplot-1.8.5 → batplot-1.8.8}/batplot/electrochem_interactive.py +57 -44
- {batplot-1.8.5 → batplot-1.8.8}/batplot/interactive.py +216 -2
- {batplot-1.8.5 → batplot-1.8.8}/batplot/modes.py +12 -11
- {batplot-1.8.5 → batplot-1.8.8}/batplot/operando_ec_interactive.py +158 -14
- {batplot-1.8.5 → batplot-1.8.8}/batplot/session.py +61 -9
- {batplot-1.8.5 → batplot-1.8.8}/batplot/style.py +109 -19
- {batplot-1.8.5 → batplot-1.8.8/batplot.egg-info}/PKG-INFO +1 -1
- {batplot-1.8.5 → batplot-1.8.8}/pyproject.toml +1 -1
- {batplot-1.8.5 → batplot-1.8.8}/LICENSE +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/MANIFEST.in +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/README.md +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/USER_MANUAL.md +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/args.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/batch.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/cif.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/cli.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/color_utils.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/config.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/converters.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/data/USER_MANUAL.md +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/manual.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/operando.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/plotting.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/readers.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/ui.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/utils.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot/version_check.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot.egg-info/SOURCES.txt +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot.egg-info/dependency_links.txt +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot.egg-info/entry_points.txt +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot.egg-info/requires.txt +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot.egg-info/top_level.txt +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/__init__.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/args.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/batch.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/batplot.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/cif.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/cli.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/color_utils.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/config.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/converters.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/cpc_interactive.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/electrochem_interactive.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/interactive.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/modes.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/operando.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/operando_ec_interactive.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/plotting.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/readers.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/session.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/style.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/ui.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/utils.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251121_223043/version_check.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/__init__.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/args.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/batch.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/batplot.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/cif.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/cli.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/color_utils.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/config.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/converters.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/cpc_interactive.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/electrochem_interactive.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/interactive.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/manual.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/modes.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/operando.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/operando_ec_interactive.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/plotting.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/readers.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/session.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/style.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/ui.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/utils.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/batplot_backup_20251221_101150/version_check.py +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/setup.cfg +0 -0
- {batplot-1.8.5 → batplot-1.8.8}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: batplot
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.8
|
|
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
|
|
@@ -422,7 +422,10 @@ def batplot_main() -> int:
|
|
|
422
422
|
# Ensure font and canvas settings match GC/dQdV
|
|
423
423
|
_plt.rcParams.update({
|
|
424
424
|
'font.family': 'sans-serif',
|
|
425
|
-
|
|
425
|
+
# Prefer DejaVu Sans first because it has good Unicode
|
|
426
|
+
# coverage (including subscript/superscript digits), then
|
|
427
|
+
# fall back to other common sans-serif fonts.
|
|
428
|
+
'font.sans-serif': ['DejaVu Sans', 'Arial', 'Helvetica', 'STIXGeneral', 'Liberation Sans', 'Arial Unicode MS'],
|
|
426
429
|
'mathtext.fontset': 'dejavusans',
|
|
427
430
|
'font.size': 16
|
|
428
431
|
})
|
|
@@ -616,8 +619,10 @@ def batplot_main() -> int:
|
|
|
616
619
|
# Set global default font
|
|
617
620
|
plt.rcParams.update({
|
|
618
621
|
'font.family': 'sans-serif',
|
|
619
|
-
|
|
620
|
-
|
|
622
|
+
# Use DejaVu Sans first to ensure good Unicode coverage (subscripts,
|
|
623
|
+
# superscripts, Greek, etc.), then fall back to other common fonts.
|
|
624
|
+
'font.sans-serif': ['DejaVu Sans', 'Arial', 'Helvetica', 'STIXGeneral', 'Liberation Sans', 'Arial Unicode MS'],
|
|
625
|
+
'mathtext.fontset': 'dejavusans', # keeps math consistent with sans-serif
|
|
621
626
|
'font.size': 16
|
|
622
627
|
})
|
|
623
628
|
|
|
@@ -1165,11 +1170,9 @@ def batplot_main() -> int:
|
|
|
1165
1170
|
print(f"Skipped {file_basename}: unsupported format (must be .csv, .xlsx, or .mpt)")
|
|
1166
1171
|
continue
|
|
1167
1172
|
|
|
1168
|
-
# Assign colors: distinct hue
|
|
1173
|
+
# Assign colors: distinct hue per file
|
|
1169
1174
|
capacity_color = capacity_colors[file_idx % len(capacity_colors)]
|
|
1170
1175
|
efficiency_color = efficiency_colors[file_idx % len(efficiency_colors)]
|
|
1171
|
-
# Generate discharge color using the same function as interactive menu
|
|
1172
|
-
discharge_color = _generate_similar_color(capacity_color)
|
|
1173
1176
|
|
|
1174
1177
|
file_data.append({
|
|
1175
1178
|
'filename': file_basename,
|
|
@@ -1179,7 +1182,6 @@ def batplot_main() -> int:
|
|
|
1179
1182
|
'cap_discharge': cap_discharge,
|
|
1180
1183
|
'eff': eff,
|
|
1181
1184
|
'color': capacity_color,
|
|
1182
|
-
'discharge_color': discharge_color,
|
|
1183
1185
|
'eff_color': efficiency_color,
|
|
1184
1186
|
'visible': True
|
|
1185
1187
|
})
|
|
@@ -1207,7 +1209,7 @@ def batplot_main() -> int:
|
|
|
1207
1209
|
cap_charge = file_info['cap_charge']
|
|
1208
1210
|
cap_discharge = file_info['cap_discharge']
|
|
1209
1211
|
eff = file_info['eff']
|
|
1210
|
-
color = file_info['color'] #
|
|
1212
|
+
color = file_info['color'] # Base color for capacity (both charge/discharge)
|
|
1211
1213
|
eff_color = file_info['eff_color'] # Cold color for efficiency
|
|
1212
1214
|
label = file_info['filename']
|
|
1213
1215
|
|
|
@@ -1221,16 +1223,30 @@ def batplot_main() -> int:
|
|
|
1221
1223
|
label_dch = f'{label} (Dch)'
|
|
1222
1224
|
label_eff = f'{label} (Eff)'
|
|
1223
1225
|
|
|
1224
|
-
#
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1226
|
+
# Capacity curves: same color, different fill style
|
|
1227
|
+
# - Charge: filled square
|
|
1228
|
+
# - Discharge: hollow square (edge only)
|
|
1229
|
+
sc_charge = ax.scatter(
|
|
1230
|
+
cyc_nums,
|
|
1231
|
+
cap_charge,
|
|
1232
|
+
label=label_chg,
|
|
1233
|
+
s=32,
|
|
1234
|
+
zorder=3,
|
|
1235
|
+
alpha=0.8,
|
|
1236
|
+
marker='s',
|
|
1237
|
+
color=color,
|
|
1238
|
+
)
|
|
1239
|
+
sc_discharge = ax.scatter(
|
|
1240
|
+
cyc_nums,
|
|
1241
|
+
cap_discharge,
|
|
1242
|
+
label=label_dch,
|
|
1243
|
+
s=32,
|
|
1244
|
+
zorder=3,
|
|
1245
|
+
alpha=0.8,
|
|
1246
|
+
marker='s',
|
|
1247
|
+
facecolor='none',
|
|
1248
|
+
edgecolor=color,
|
|
1249
|
+
)
|
|
1234
1250
|
sc_eff = ax2.scatter(cyc_nums, eff, color=eff_color, marker='^', label=label_eff,
|
|
1235
1251
|
s=40, alpha=0.7, zorder=3)
|
|
1236
1252
|
|
|
@@ -1247,27 +1263,25 @@ def batplot_main() -> int:
|
|
|
1247
1263
|
h1, l1 = ax.get_legend_handles_labels()
|
|
1248
1264
|
h2, l2 = ax2.get_legend_handles_labels()
|
|
1249
1265
|
combined_handles = h1 + h2
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
except Exception:
|
|
1270
|
-
pass
|
|
1266
|
+
combined_labels = l1 + l2
|
|
1267
|
+
if combined_handles:
|
|
1268
|
+
# Don't use labelcolor='linecolor' for scatter plots with hollow markers
|
|
1269
|
+
# as it causes issues with color extraction
|
|
1270
|
+
leg = ax.legend(
|
|
1271
|
+
combined_handles, combined_labels,
|
|
1272
|
+
loc='best',
|
|
1273
|
+
frameon=False,
|
|
1274
|
+
handlelength=1.0,
|
|
1275
|
+
handletextpad=0.35,
|
|
1276
|
+
labelspacing=0.25,
|
|
1277
|
+
borderaxespad=0.5,
|
|
1278
|
+
borderpad=0.3,
|
|
1279
|
+
columnspacing=0.6,
|
|
1280
|
+
)
|
|
1281
|
+
except Exception as e:
|
|
1282
|
+
print(f"Warning: Could not create CPC legend: {e}")
|
|
1283
|
+
import traceback
|
|
1284
|
+
traceback.print_exc()
|
|
1271
1285
|
|
|
1272
1286
|
# Adjust layout to ensure top and bottom labels/titles are visible
|
|
1273
1287
|
fig.subplots_adjust(left=0.12, right=0.88, top=0.88, bottom=0.15)
|
|
@@ -1842,6 +1856,11 @@ def batplot_main() -> int:
|
|
|
1842
1856
|
_plt.show(block=False)
|
|
1843
1857
|
except Exception:
|
|
1844
1858
|
pass
|
|
1859
|
+
# Seed last-session path so 'os' overwrite command is available immediately
|
|
1860
|
+
try:
|
|
1861
|
+
fig._last_session_save_path = os.path.abspath(sess_path)
|
|
1862
|
+
except Exception:
|
|
1863
|
+
pass
|
|
1845
1864
|
try:
|
|
1846
1865
|
source_list = list(getattr(fig, '_bp_source_paths', []) or [])
|
|
1847
1866
|
sess_abs = os.path.abspath(sess_path)
|
|
@@ -1877,6 +1896,11 @@ def batplot_main() -> int:
|
|
|
1877
1896
|
_plt.show(block=False)
|
|
1878
1897
|
except Exception:
|
|
1879
1898
|
pass
|
|
1899
|
+
# Seed last-session path so 'os' overwrite command is available immediately
|
|
1900
|
+
try:
|
|
1901
|
+
fig2._last_session_save_path = os.path.abspath(sess_path)
|
|
1902
|
+
except Exception:
|
|
1903
|
+
pass
|
|
1880
1904
|
try:
|
|
1881
1905
|
if operando_ec_interactive_menu is not None:
|
|
1882
1906
|
operando_ec_interactive_menu(fig2, ax2, im2, cbar2, ec_ax2)
|
|
@@ -1905,6 +1929,11 @@ def batplot_main() -> int:
|
|
|
1905
1929
|
_plt.show(block=False)
|
|
1906
1930
|
except Exception:
|
|
1907
1931
|
pass
|
|
1932
|
+
# Seed last-session path so 'os' overwrite command is available immediately
|
|
1933
|
+
try:
|
|
1934
|
+
fig_c._last_session_save_path = os.path.abspath(sess_path)
|
|
1935
|
+
except Exception:
|
|
1936
|
+
pass
|
|
1908
1937
|
try:
|
|
1909
1938
|
if cpc_interactive_menu is not None:
|
|
1910
1939
|
cpc_interactive_menu(fig_c, ax_c, ax2_c, sc_c, sc_d, sc_e, file_data=file_data)
|
|
@@ -2207,6 +2236,14 @@ def batplot_main() -> int:
|
|
|
2207
2236
|
fig._tick_lengths['minor'] = minor_len
|
|
2208
2237
|
except Exception:
|
|
2209
2238
|
pass
|
|
2239
|
+
# Tick direction restore (t submenu)
|
|
2240
|
+
try:
|
|
2241
|
+
tick_direction = sess.get('tick_direction', 'out')
|
|
2242
|
+
if tick_direction:
|
|
2243
|
+
setattr(fig, '_tick_direction', tick_direction)
|
|
2244
|
+
ax.tick_params(axis='both', which='both', direction=tick_direction)
|
|
2245
|
+
except Exception:
|
|
2246
|
+
pass
|
|
2210
2247
|
|
|
2211
2248
|
# Restore WASD state (spine, ticks, labels, title visibility for all 4 sides)
|
|
2212
2249
|
try:
|
|
@@ -2675,8 +2712,24 @@ def batplot_main() -> int:
|
|
|
2675
2712
|
offset = 0.0
|
|
2676
2713
|
direction = -1 if args.stack else 1 # stack downward
|
|
2677
2714
|
if args.interactive:
|
|
2715
|
+
# Interactive: keep a reasonably compact default size so the window
|
|
2716
|
+
# fits well on most screens; margins are handled by the menu logic.
|
|
2678
2717
|
plt.ion()
|
|
2679
|
-
|
|
2718
|
+
figsize = (8, 6)
|
|
2719
|
+
else:
|
|
2720
|
+
# Non-interactive (no --i): use a slightly larger canvas so that labels,
|
|
2721
|
+
# titles, legends, and CIF ticks are not clipped even with long filenames.
|
|
2722
|
+
# The size (9, 6.4) keeps a similar aspect ratio but with a bit more room
|
|
2723
|
+
# than the interactive default while still fitting comfortably on screen.
|
|
2724
|
+
figsize = (9.5, 6.4)
|
|
2725
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
2726
|
+
|
|
2727
|
+
# Set consistent margins for all modes.
|
|
2728
|
+
# This prevents labels/titles from being cut off at the edges.
|
|
2729
|
+
try:
|
|
2730
|
+
fig.subplots_adjust(left=0.125, right=0.9, top=0.88, bottom=0.11)
|
|
2731
|
+
except Exception:
|
|
2732
|
+
pass
|
|
2680
2733
|
|
|
2681
2734
|
y_data_list = []
|
|
2682
2735
|
x_data_list = []
|
|
@@ -2710,7 +2763,17 @@ def batplot_main() -> int:
|
|
|
2710
2763
|
any_cif = any(f.lower().endswith(".cif") for f in args.files)
|
|
2711
2764
|
non_cif_count = sum(0 if f.lower().endswith('.cif') else 1 for f in args.files)
|
|
2712
2765
|
cif_only = any_cif and non_cif_count == 0
|
|
2713
|
-
|
|
2766
|
+
# Check for wavelength parameters (file:wl), but exclude Windows drive letters (C:\...)
|
|
2767
|
+
def has_wavelength_param(f):
|
|
2768
|
+
if ":" not in f:
|
|
2769
|
+
return False
|
|
2770
|
+
# Check if it's a Windows path (single letter followed by :\ or :/)
|
|
2771
|
+
if len(f) >= 2 and f[1] == ':' and len(f[0]) == 1 and f[0].isalpha():
|
|
2772
|
+
# This is a Windows drive letter, check after the drive path
|
|
2773
|
+
# Look for additional colons beyond the drive letter
|
|
2774
|
+
return ":" in f[2:]
|
|
2775
|
+
return True
|
|
2776
|
+
any_lambda = any(has_wavelength_param(f) for f in args.files) or args.wl is not None
|
|
2714
2777
|
|
|
2715
2778
|
# Incompatibilities (no mixing of fundamentally different axis domains)
|
|
2716
2779
|
if sum(bool(x) for x in (any_gr, any_nor, any_chik, any_chir, (any_qye or any_lambda or any_cif))) > 1:
|
|
@@ -2730,7 +2793,8 @@ def batplot_main() -> int:
|
|
|
2730
2793
|
elif any_txt:
|
|
2731
2794
|
# .txt is generic, require --xaxis
|
|
2732
2795
|
if args.xaxis:
|
|
2733
|
-
|
|
2796
|
+
# Normalize case: 'q' or 'Q' → 'Q' (uppercase), everything else lowercase
|
|
2797
|
+
axis_mode = "Q" if args.xaxis.upper() == "Q" else args.xaxis.lower()
|
|
2734
2798
|
else:
|
|
2735
2799
|
raise ValueError("Unknown file type. Use: batplot file.txt --xaxis [Q|2theta|r|k|energy|rft] or batplot -h for help.")
|
|
2736
2800
|
elif any_lambda or any_cif:
|
|
@@ -2741,7 +2805,8 @@ def batplot_main() -> int:
|
|
|
2741
2805
|
# CIF files are in Q space
|
|
2742
2806
|
axis_mode = "Q"
|
|
2743
2807
|
elif args.xaxis:
|
|
2744
|
-
|
|
2808
|
+
# Normalize case: 'q' or 'Q' → 'Q' (uppercase), everything else lowercase
|
|
2809
|
+
axis_mode = "Q" if args.xaxis.upper() == "Q" else args.xaxis.lower()
|
|
2745
2810
|
else:
|
|
2746
2811
|
raise ValueError("Unknown file type. Use: batplot file.csv --xaxis [Q|2theta|r|k|energy|rft] or batplot -h for help.")
|
|
2747
2812
|
|
|
@@ -2841,8 +2906,16 @@ def batplot_main() -> int:
|
|
|
2841
2906
|
|
|
2842
2907
|
# Use data_files instead of args.files for processing
|
|
2843
2908
|
for idx_file, file_entry in enumerate(data_files):
|
|
2909
|
+
# Handle Windows paths (C:\...) vs wavelength parameters (file:wl)
|
|
2910
|
+
# On Windows, check if first part is a single letter (drive letter)
|
|
2844
2911
|
parts = file_entry.split(":")
|
|
2845
|
-
|
|
2912
|
+
if len(parts) > 1 and len(parts[0]) == 1 and parts[0].isalpha():
|
|
2913
|
+
# Windows drive letter detected (e.g., "C" from "C:\path")
|
|
2914
|
+
# Rejoin the first two parts as the filename
|
|
2915
|
+
fname = parts[0] + ":" + parts[1]
|
|
2916
|
+
parts = [fname] + parts[2:] # Reconstruct parts with full Windows path
|
|
2917
|
+
else:
|
|
2918
|
+
fname = parts[0]
|
|
2846
2919
|
# Parse wavelength parameters: file:wl1 or file:wl1:wl2 or file.cif:wl
|
|
2847
2920
|
wavelength_file = None
|
|
2848
2921
|
original_wavelength = None # First wavelength (for Q conversion)
|
|
@@ -3532,19 +3605,36 @@ def batplot_main() -> int:
|
|
|
3532
3605
|
ax._cif_hover_cid = cid
|
|
3533
3606
|
|
|
3534
3607
|
if cif_tick_series:
|
|
3535
|
-
# Auto-assign distinct colors
|
|
3608
|
+
# Auto-assign distinct colors for CIF tick series.
|
|
3609
|
+
# For multiple CIF series:
|
|
3610
|
+
# - If <= 10 files, use 'tab10' but in a re-ordered sequence to
|
|
3611
|
+
# maximize visual separation between adjacent colors.
|
|
3612
|
+
# - If > 10 files, use 'viridis' with evenly spaced samples.
|
|
3613
|
+
#
|
|
3614
|
+
# This overrides any previous per-series color so that the requested
|
|
3615
|
+
# colormap behavior is always enforced.
|
|
3536
3616
|
if len(cif_tick_series) > 1:
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3617
|
+
try:
|
|
3618
|
+
n_cif = len(cif_tick_series)
|
|
3619
|
+
if n_cif <= 10:
|
|
3620
|
+
tab10 = plt.get_cmap('tab10').colors
|
|
3621
|
+
# Reorder indices for more distinct neighboring colors
|
|
3622
|
+
order = [0, 3, 6, 1, 4, 7, 2, 5, 8, 9]
|
|
3541
3623
|
new_series = []
|
|
3542
|
-
for i,(lab,fname,peaksQ,wl,qmax_sim,col) in enumerate(cif_tick_series):
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3624
|
+
for i, (lab, fname, peaksQ, wl, qmax_sim, col) in enumerate(cif_tick_series):
|
|
3625
|
+
idx = order[i] if i < len(order) else i % len(tab10)
|
|
3626
|
+
color = tab10[idx]
|
|
3627
|
+
new_series.append((lab, fname, peaksQ, wl, qmax_sim, color))
|
|
3628
|
+
else:
|
|
3629
|
+
cmap = plt.get_cmap('viridis')
|
|
3630
|
+
positions = np.linspace(0.0, 1.0, n_cif)
|
|
3631
|
+
new_series = []
|
|
3632
|
+
for (pos, (lab, fname, peaksQ, wl, qmax_sim, col)) in zip(positions, cif_tick_series):
|
|
3633
|
+
color = cmap(pos)
|
|
3634
|
+
new_series.append((lab, fname, peaksQ, wl, qmax_sim, color))
|
|
3635
|
+
cif_tick_series[:] = new_series
|
|
3636
|
+
except Exception:
|
|
3637
|
+
pass
|
|
3548
3638
|
if use_2th:
|
|
3549
3639
|
_ensure_wavelength_for_2theta()
|
|
3550
3640
|
draw_cif_ticks()
|