batplot 1.8.4__py3-none-any.whl → 1.8.5__py3-none-any.whl

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.

Potentially problematic release.


This version of batplot might be problematic. Click here for more details.

batplot/operando.py CHANGED
@@ -296,6 +296,28 @@ def plot_operando_folder(folder: str, args) -> Tuple[plt.Figure, plt.Axes, Dict[
296
296
  # Result shape: (n_scans, n_x_points)
297
297
  # Example: 50 scans × 1000 points = (50, 1000) array
298
298
  Z = np.vstack(stack) # shape (n_scans, n_x)
299
+
300
+ # STEP 5.5: Apply first derivative if --1d or --2d flag is set
301
+ # This calculates dy/dx for each scan using np.gradient
302
+ if getattr(args, 'derivative_1d', False) or getattr(args, 'derivative_2d', False):
303
+ print("[operando] Applying first derivative (dy/dx) to each scan...")
304
+ Z_deriv = np.zeros_like(Z)
305
+ for i in range(Z.shape[0]):
306
+ row = Z[i, :]
307
+ # Calculate derivative using gradient (handles NaN gracefully in numpy 1.20+)
308
+ # Use the grid spacing for proper derivative calculation
309
+ dx = grid_x[1] - grid_x[0] if len(grid_x) > 1 else 1.0
310
+ # Replace NaN with interpolated values for gradient, then mask back
311
+ valid_mask = ~np.isnan(row)
312
+ if np.sum(valid_mask) > 1:
313
+ # For valid regions, calculate gradient
314
+ deriv = np.gradient(row, dx)
315
+ # Keep NaN where original was NaN
316
+ deriv[~valid_mask] = np.nan
317
+ Z_deriv[i, :] = deriv
318
+ else:
319
+ Z_deriv[i, :] = np.nan
320
+ Z = Z_deriv
299
321
 
300
322
  # Detect an electrochemistry .mpt file in the same folder (if any)
301
323
  # Filter out macOS resource fork files (starting with ._)
@@ -832,7 +832,8 @@ def operando_ec_interactive_menu(fig, ax, im, cbar, ec_ax, file_paths=None):
832
832
  "ox: X range",
833
833
  "oy: Y range",
834
834
  "oz: intensity range",
835
- "or: rename"
835
+ "or: rename",
836
+ "pk: peak search"
836
837
  ]
837
838
  col3 = [
838
839
  "et: time range",
@@ -885,7 +886,8 @@ def operando_ec_interactive_menu(fig, ax, im, cbar, ec_ax, file_paths=None):
885
886
  "ox: X range",
886
887
  "oy: Y range",
887
888
  "oz: intensity range",
888
- "or: rename"
889
+ "or: rename",
890
+ "pk: peak search"
889
891
  ]
890
892
  col3 = [
891
893
  "n: crosshair",
@@ -2285,6 +2287,234 @@ def operando_ec_interactive_menu(fig, ax, im, cbar, ec_ax, file_paths=None):
2285
2287
  except Exception as e:
2286
2288
  print(f"Save failed: {e}")
2287
2289
  print_menu(); continue
2290
+ if cmd == 'pk':
2291
+ try:
2292
+ import os
2293
+ from .utils import choose_save_path
2294
+ try:
2295
+ from scipy.signal import find_peaks
2296
+ except ImportError:
2297
+ print("Error: scipy is required for peak finding. Install with: pip install scipy")
2298
+ print_menu(); continue
2299
+
2300
+ # Get operando data
2301
+ data_array = np.asarray(im.get_array(), dtype=float)
2302
+ if data_array.ndim != 2 or data_array.size == 0:
2303
+ print("Error: No operando data available.")
2304
+ print_menu(); continue
2305
+
2306
+ extent = im.get_extent() # (left, right, bottom, top)
2307
+ x0, x1, y0, y1 = extent
2308
+ x_min, x_max = (x0, x1) if x0 <= x1 else (x1, x0)
2309
+ y_min, y_max = (y0, y1) if y0 <= y1 else (y1, y0)
2310
+
2311
+ n_scans, n_x_points = data_array.shape
2312
+
2313
+ # Create x-axis array
2314
+ x_axis = np.linspace(x_min, x_max, n_x_points)
2315
+
2316
+ print("\nPeak Search Menu:")
2317
+ print(" 1: Find peaks in X range")
2318
+ print(" e: Explanation of peak searching")
2319
+ print(" q: Back to main menu")
2320
+ sub = _safe_input("Choose option: ").strip().lower()
2321
+
2322
+ if sub == 'e':
2323
+ print("\n" + "="*70)
2324
+ print("PEAK SEARCHING EXPLANATION")
2325
+ print("="*70)
2326
+ print("\nPeak searching identifies local maxima in diffraction patterns.")
2327
+ print("This is useful for tracking how peak positions change over time")
2328
+ print("(or scan number) in operando experiments.\n")
2329
+ print("HOW IT WORKS:")
2330
+ print("1. Select X range: Choose the region where you want to find peaks")
2331
+ print("2. For each scan (file):")
2332
+ print(" - Extract intensity profile in the selected X range")
2333
+ print(" - Find local maxima (peaks) using scipy.signal.find_peaks")
2334
+ print(" - Refine peak positions using quadratic interpolation")
2335
+ print("3. Export results: Peak positions vs file number saved to .txt file\n")
2336
+ print("PARAMETERS:")
2337
+ print("- Prominence: Minimum height of peak relative to surrounding baseline")
2338
+ print(" (Higher = fewer, stronger peaks)")
2339
+ print("- Distance: Minimum separation between peaks (in data points)")
2340
+ print(" (Larger = peaks must be further apart)")
2341
+ print("- Width: Minimum width of peak at half maximum")
2342
+ print(" (Larger = broader peaks only)\n")
2343
+ print("OUTPUT FORMAT:")
2344
+ print("The exported .txt file contains:")
2345
+ print(" Column 1: File number (scan index, 0-based)")
2346
+ print(" Column 2: Peak position (X-axis value)")
2347
+ print(" Column 3: Peak intensity (optional, if enabled)\n")
2348
+ print("="*70 + "\n")
2349
+ print_menu(); continue
2350
+
2351
+ if sub == 'q':
2352
+ print_menu(); continue
2353
+
2354
+ if sub == '1' or sub == '':
2355
+ # Get X range
2356
+ print(f"\nCurrent X range: {x_min:.6g} to {x_max:.6g}")
2357
+ print("Enter X range for peak search (min max), or press Enter to use full range:")
2358
+ x_range_input = _safe_input("X range: ").strip()
2359
+
2360
+ if x_range_input:
2361
+ try:
2362
+ parts = x_range_input.split()
2363
+ if len(parts) >= 2:
2364
+ x_range_min = float(parts[0])
2365
+ x_range_max = float(parts[1])
2366
+ else:
2367
+ print("Invalid format. Use: min max")
2368
+ print_menu(); continue
2369
+ except ValueError:
2370
+ print("Invalid number format.")
2371
+ print_menu(); continue
2372
+ else:
2373
+ x_range_min = x_min
2374
+ x_range_max = x_max
2375
+
2376
+ # Clamp to valid range
2377
+ x_range_min = max(x_min, min(x_max, x_range_min))
2378
+ x_range_max = max(x_min, min(x_max, x_range_max))
2379
+ if x_range_min >= x_range_max:
2380
+ print("Invalid range: min must be < max")
2381
+ print_menu(); continue
2382
+
2383
+ # Find column indices for X range
2384
+ col_min = int(np.argmin(np.abs(x_axis - x_range_min)))
2385
+ col_max = int(np.argmin(np.abs(x_axis - x_range_max)))
2386
+ if col_min > col_max:
2387
+ col_min, col_max = col_max, col_min
2388
+ col_max = min(col_max + 1, n_x_points) # Include endpoint
2389
+
2390
+ # Get parameters for peak finding
2391
+ print("\nPeak finding parameters:")
2392
+ prominence_input = _safe_input("Prominence (relative to max, default 0.1): ").strip()
2393
+ prominence = float(prominence_input) if prominence_input else 0.1
2394
+
2395
+ distance_input = _safe_input("Minimum distance between peaks (data points, default 5): ").strip()
2396
+ distance = int(distance_input) if distance_input else 5
2397
+
2398
+ width_input = _safe_input("Minimum peak width (data points, default 1, 0=disabled): ").strip()
2399
+ width = int(width_input) if width_input else 1
2400
+
2401
+ include_intensity = _safe_input("Include peak intensity in output? (y/n, default n): ").strip().lower() == 'y'
2402
+
2403
+ # Find peaks for each scan
2404
+ print(f"\nFinding peaks in X range [{x_range_min:.6g}, {x_range_max:.6g}]...")
2405
+ results = []
2406
+
2407
+ for scan_idx in range(n_scans):
2408
+ # Extract intensity profile for this scan in X range
2409
+ intensity_profile = data_array[scan_idx, col_min:col_max]
2410
+ x_profile = x_axis[col_min:col_max]
2411
+
2412
+ if len(intensity_profile) < 3:
2413
+ continue
2414
+
2415
+ # Find peaks
2416
+ try:
2417
+ # Calculate prominence threshold
2418
+ max_intensity = np.max(intensity_profile)
2419
+ min_intensity = np.min(intensity_profile)
2420
+ prominence_abs = (max_intensity - min_intensity) * prominence
2421
+
2422
+ peak_kwargs = {
2423
+ 'prominence': prominence_abs if prominence_abs > 0 else None,
2424
+ 'distance': max(1, distance),
2425
+ }
2426
+ if width > 0:
2427
+ peak_kwargs['width'] = width
2428
+
2429
+ # Remove None values
2430
+ peak_kwargs = {k: v for k, v in peak_kwargs.items() if v is not None}
2431
+
2432
+ peak_indices, peak_properties = find_peaks(intensity_profile, **peak_kwargs)
2433
+
2434
+ # Refine peak positions using quadratic interpolation
2435
+ for peak_idx in peak_indices:
2436
+ if peak_idx == 0 or peak_idx == len(intensity_profile) - 1:
2437
+ peak_x = x_profile[peak_idx]
2438
+ peak_intensity = intensity_profile[peak_idx]
2439
+ else:
2440
+ # Quadratic interpolation for sub-pixel accuracy
2441
+ y1 = intensity_profile[peak_idx - 1]
2442
+ y2 = intensity_profile[peak_idx]
2443
+ y3 = intensity_profile[peak_idx + 1]
2444
+ x1 = x_profile[peak_idx - 1]
2445
+ x2 = x_profile[peak_idx]
2446
+ x3 = x_profile[peak_idx + 1]
2447
+
2448
+ denom = (y1 - 2*y2 + y3)
2449
+ if abs(denom) > 1e-12:
2450
+ dx = 0.5 * (y1 - y3) / denom
2451
+ if -0.6 < dx < 0.6:
2452
+ peak_x = x2 + dx * (x3 - x1) / 2.0
2453
+ peak_intensity = y2 + 0.5 * dx * (y3 - y1)
2454
+ else:
2455
+ peak_x = x2
2456
+ peak_intensity = y2
2457
+ else:
2458
+ peak_x = x2
2459
+ peak_intensity = y2
2460
+
2461
+ if include_intensity:
2462
+ results.append((scan_idx, peak_x, peak_intensity))
2463
+ else:
2464
+ results.append((scan_idx, peak_x))
2465
+ except Exception as e:
2466
+ # Skip this scan if peak finding fails
2467
+ continue
2468
+
2469
+ if not results:
2470
+ print("No peaks found in the selected X range.")
2471
+ print_menu(); continue
2472
+
2473
+ # Save results
2474
+ folder = choose_save_path(file_paths, purpose="peak search export")
2475
+ if not folder:
2476
+ print_menu(); continue
2477
+
2478
+ print(f"\nChosen path: {folder}")
2479
+ fname = _safe_input("Export filename (default: peaks.txt): ").strip()
2480
+ if not fname:
2481
+ fname = "peaks.txt"
2482
+ if not fname.endswith('.txt'):
2483
+ fname += '.txt'
2484
+
2485
+ target = fname if os.path.isabs(fname) else os.path.join(folder, fname)
2486
+ if os.path.exists(target):
2487
+ yn = _safe_input(f"'{os.path.basename(target)}' exists. Overwrite? (y/n): ").strip().lower()
2488
+ if yn != 'y':
2489
+ print_menu(); continue
2490
+
2491
+ # Write results
2492
+ try:
2493
+ with open(target, 'w') as f:
2494
+ if include_intensity:
2495
+ f.write("# File number\tPeak position\tPeak intensity\n")
2496
+ for scan_idx, peak_x, peak_intensity in results:
2497
+ f.write(f"{scan_idx}\t{peak_x:.6f}\t{peak_intensity:.6f}\n")
2498
+ else:
2499
+ f.write("# File number\tPeak position\n")
2500
+ for result in results:
2501
+ if len(result) == 2:
2502
+ scan_idx, peak_x = result
2503
+ f.write(f"{scan_idx}\t{peak_x:.6f}\n")
2504
+ else:
2505
+ scan_idx, peak_x, _ = result
2506
+ f.write(f"{scan_idx}\t{peak_x:.6f}\n")
2507
+ print(f"Peak positions exported to {target}")
2508
+ print(f"Found {len(results)} peaks across {len(set(r[0] for r in results))} scans")
2509
+ except Exception as e:
2510
+ print(f"Error saving file: {e}")
2511
+ else:
2512
+ print("Invalid option.")
2513
+ except Exception as e:
2514
+ print(f"Error in peak search: {e}")
2515
+ import traceback
2516
+ traceback.print_exc()
2517
+ print_menu(); continue
2288
2518
  if cmd == 'h':
2289
2519
  # Always read fresh value from attribute to avoid stale cached value
2290
2520
  ax_h_in = getattr(ax, '_fixed_ax_h_in', ax_h_in)
batplot/session.py CHANGED
@@ -500,6 +500,30 @@ def dump_session(
500
500
  'orig_y': [np.array(a) for a in orig_y],
501
501
  'offsets': list(offsets_list),
502
502
  'labels': list(labels),
503
+ # Processed data (for smooth/reduce operations)
504
+ 'original_x_data_list': ([np.array(a) for a in getattr(fig, '_original_x_data_list', [])]
505
+ if hasattr(fig, '_original_x_data_list') else None),
506
+ 'original_y_data_list': ([np.array(a) for a in getattr(fig, '_original_y_data_list', [])]
507
+ if hasattr(fig, '_original_y_data_list') else None),
508
+ 'full_processed_x_data_list': ([np.array(a) for a in getattr(fig, '_full_processed_x_data_list', [])]
509
+ if hasattr(fig, '_full_processed_x_data_list') else None),
510
+ 'full_processed_y_data_list': ([np.array(a) for a in getattr(fig, '_full_processed_y_data_list', [])]
511
+ if hasattr(fig, '_full_processed_y_data_list') else None),
512
+ 'smooth_settings': (dict(getattr(fig, '_smooth_settings', {}))
513
+ if hasattr(fig, '_smooth_settings') else None),
514
+ 'last_smooth_settings': (dict(getattr(fig, '_last_smooth_settings', {}))
515
+ if hasattr(fig, '_last_smooth_settings') else None),
516
+ # Derivative data (for derivative operations)
517
+ 'pre_derivative_x_data_list': ([np.array(a) for a in getattr(fig, '_pre_derivative_x_data_list', [])]
518
+ if hasattr(fig, '_pre_derivative_x_data_list') else None),
519
+ 'pre_derivative_y_data_list': ([np.array(a) for a in getattr(fig, '_pre_derivative_y_data_list', [])]
520
+ if hasattr(fig, '_pre_derivative_y_data_list') else None),
521
+ 'pre_derivative_ylabel': (str(getattr(fig, '_pre_derivative_ylabel', ''))
522
+ if hasattr(fig, '_pre_derivative_ylabel') else None),
523
+ 'derivative_order': (int(getattr(fig, '_derivative_order', 0))
524
+ if hasattr(fig, '_derivative_order') else None),
525
+ 'derivative_reversed': (bool(getattr(fig, '_derivative_reversed', False))
526
+ if hasattr(fig, '_derivative_reversed') else None),
503
527
  'line_styles': [
504
528
  {
505
529
  'color': ln.get_color(),
batplot/style.py CHANGED
@@ -451,7 +451,19 @@ def print_style_info(
451
451
  except Exception:
452
452
  pass
453
453
 
454
- # Omit CIF/HKL details from compact style print
454
+ # CIF hkl label visibility
455
+ if show_cif_hkl is not None:
456
+ print(f"CIF hkl labels: {'shown' if show_cif_hkl else 'hidden'}")
457
+ elif cif_tick_series:
458
+ # Try to read from __main__ module if not provided
459
+ try:
460
+ import sys
461
+ _bp_module = sys.modules.get('__main__')
462
+ if _bp_module is not None and hasattr(_bp_module, 'show_cif_hkl'):
463
+ hkl_state = bool(getattr(_bp_module, 'show_cif_hkl', False))
464
+ print(f"CIF hkl labels: {'shown' if hkl_state else 'hidden'}")
465
+ except Exception:
466
+ pass
455
467
 
456
468
  # Omit non-style global flags (mode/raw/autoscale/delta)
457
469
 
@@ -670,6 +682,14 @@ def export_style_config(
670
682
  # Save CIF title visibility
671
683
  if show_cif_titles is not None:
672
684
  cfg["show_cif_titles"] = bool(show_cif_titles)
685
+ # Save CIF hkl label visibility (read from __main__ module if available)
686
+ try:
687
+ import sys
688
+ _bp_module = sys.modules.get('__main__')
689
+ if _bp_module is not None and hasattr(_bp_module, 'show_cif_hkl'):
690
+ cfg["show_cif_hkl"] = bool(getattr(_bp_module, 'show_cif_hkl', False))
691
+ except Exception:
692
+ pass
673
693
  if cif_tick_series:
674
694
  cfg["cif_ticks"] = [
675
695
  {"index": i, "color": color}
@@ -692,6 +712,20 @@ def export_style_config(
692
712
  if serialized_palettes:
693
713
  cfg['curve_palettes'] = serialized_palettes
694
714
 
715
+ # Store smooth settings (metadata only, not full arrays)
716
+ if hasattr(fig, '_smooth_settings'):
717
+ cfg['smooth_settings'] = dict(fig._smooth_settings)
718
+ if hasattr(fig, '_last_smooth_settings'):
719
+ cfg['last_smooth_settings'] = dict(fig._last_smooth_settings)
720
+ # Store derivative order (metadata only)
721
+ if hasattr(fig, '_derivative_order'):
722
+ cfg['derivative_order'] = int(fig._derivative_order)
723
+ if hasattr(fig, '_derivative_reversed'):
724
+ cfg['derivative_reversed'] = bool(fig._derivative_reversed)
725
+ # Note: We don't store original_x_data_list/original_y_data_list or pre_derivative data in style files
726
+ # as style files are for styling only, and the data would be specific
727
+ # to the dataset. Session files (pickle) store this data instead.
728
+
695
729
  # If overwrite_path is provided, determine export type from existing file
696
730
  if overwrite_path:
697
731
  try:
@@ -1230,8 +1264,61 @@ def apply_style_config(
1230
1264
  setattr(_bp_module, 'show_cif_titles', bool(cfg["show_cif_titles"]))
1231
1265
  except Exception:
1232
1266
  pass
1267
+ # Restore CIF hkl label visibility
1268
+ if "show_cif_hkl" in cfg:
1269
+ try:
1270
+ _bp_module = sys.modules.get('__main__')
1271
+ if _bp_module is not None:
1272
+ setattr(_bp_module, 'show_cif_hkl', bool(cfg["show_cif_hkl"]))
1273
+ # Also update _bp object if available
1274
+ if cif_tick_series is not None:
1275
+ # Try to update via interactive menu's _bp object
1276
+ try:
1277
+ import sys
1278
+ _bp_obj = getattr(sys.modules.get('__main__'), '_bp', None)
1279
+ if _bp_obj is not None:
1280
+ setattr(_bp_obj, 'show_cif_hkl', bool(cfg["show_cif_hkl"]))
1281
+ except Exception:
1282
+ pass
1283
+ except Exception:
1284
+ pass
1285
+ # Restore smooth settings (metadata only, not full arrays)
1286
+ if "smooth_settings" in cfg:
1287
+ try:
1288
+ fig._smooth_settings = dict(cfg["smooth_settings"])
1289
+ except Exception:
1290
+ pass
1291
+ elif hasattr(fig, '_smooth_settings'):
1292
+ delattr(fig, '_smooth_settings')
1293
+ if "last_smooth_settings" in cfg:
1294
+ try:
1295
+ fig._last_smooth_settings = dict(cfg["last_smooth_settings"])
1296
+ except Exception:
1297
+ pass
1298
+ elif hasattr(fig, '_last_smooth_settings'):
1299
+ delattr(fig, '_last_smooth_settings')
1300
+ # Restore derivative order (metadata only)
1301
+ if "derivative_order" in cfg:
1302
+ try:
1303
+ order = int(cfg["derivative_order"])
1304
+ fig._derivative_order = order
1305
+ is_reversed = cfg.get("derivative_reversed", False)
1306
+ if "derivative_reversed" in cfg:
1307
+ fig._derivative_reversed = bool(cfg["derivative_reversed"])
1308
+ # Update y-axis label based on derivative order
1309
+ from .interactive import _update_ylabel_for_derivative
1310
+ current_ylabel = ax.get_ylabel() or ""
1311
+ new_ylabel = _update_ylabel_for_derivative(order, current_ylabel, is_reversed=is_reversed)
1312
+ ax.set_ylabel(new_ylabel)
1313
+ except Exception:
1314
+ pass
1315
+ elif hasattr(fig, '_derivative_order'):
1316
+ delattr(fig, '_derivative_order')
1317
+ # Note: We don't restore original_x_data_list/original_y_data_list or pre_derivative data from style files
1318
+ # as style files are for styling only, and the data would be specific
1319
+ # to the dataset. Session files (pickle) store this data instead.
1233
1320
  # Redraw CIF ticks after applying changes
1234
- if (cif_cfg and cif_tick_series is not None) or "show_cif_titles" in cfg:
1321
+ if (cif_cfg and cif_tick_series is not None) or "show_cif_titles" in cfg or "show_cif_hkl" in cfg:
1235
1322
  if hasattr(ax, "_cif_draw_func"):
1236
1323
  try:
1237
1324
  ax._cif_draw_func()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: batplot
3
- Version: 1.8.4
3
+ Version: 1.8.5
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
@@ -1,28 +1,28 @@
1
- batplot/__init__.py,sha256=A2c5RdJQEC4-Snfk1leoeq38dCyGoAxBuEvXo3Kb50A,118
2
- batplot/args.py,sha256=mrDjMURp_OQnXrAwl9WnE_FW4HJu940O7NmL9QWQnD4,35189
3
- batplot/batch.py,sha256=P2HNBYqrSzDr2fruYz8BFKwNFX6vdJpHDZpaG_hmEc8,55253
4
- batplot/batplot.py,sha256=IDnc-aGIMo1oMfXsQjU_koKqq2E9xXNn1Bm92xsmeYE,177109
1
+ batplot/__init__.py,sha256=6mfbpfSzbSfjCLrvmBzBMKmDyiFSBUJlcB8Qqv6o26s,118
2
+ batplot/args.py,sha256=DGTe2PKmJnI8Iq12QgO76V8lZvWhMOqY14gsyE5SgEs,37001
3
+ batplot/batch.py,sha256=hqLNvd88OLd0PLo_ot6JjC3FM6wwxCJ1jO2J63f9Zyg,55899
4
+ batplot/batplot.py,sha256=-mAf1aW7bniyfQ5DCorqyOr-OcRtUgRtq6TZHKk5xCU,184599
5
5
  batplot/cif.py,sha256=JfHwNf3SHrcpALc_F5NjJmQ3lg71MBRSaIUJjGYPTx8,30120
6
6
  batplot/cli.py,sha256=2-7NtxBlyOUfzHVwP7vZK7OZlyKyPVy-3daKN-MPWyU,6657
7
7
  batplot/color_utils.py,sha256=7InQLVo1XTg7sgAbltM2KeDSFJgr787YEaV9vJbIoWY,20460
8
8
  batplot/config.py,sha256=6nGY7fKN4T5KZUGQS2ArUBgEkLAL0j37XwG5SCVQgKA,6420
9
- batplot/converters.py,sha256=rR2WMPM0nR5E3eZI3gWbaJf_AfbdQx3urVSbJmZXNzo,8237
10
- batplot/cpc_interactive.py,sha256=qadWV2PaQMsqM16mSp5r1-WP7di0JCnzNI4RJy27alo,239616
11
- batplot/electrochem_interactive.py,sha256=8mFr5vtWb_ZDiJmZWXjkARq21D2GflT8-J2xvCGvDIc,222769
12
- batplot/interactive.py,sha256=5u2ulhTzRr7fA-INc5hfcz7xaHObnnigiXjrgdtE7XE,206728
9
+ batplot/converters.py,sha256=c4qhgN9zHUiBZhXVAdf0zGtPPoktD3JjMLkhjjYEwlk,9787
10
+ batplot/cpc_interactive.py,sha256=-9etN342VqLbY9pLP7cyBcSzgVHuWpDwEZHkXzShl7E,240683
11
+ batplot/electrochem_interactive.py,sha256=a3ocYQEfi0FsiMq9B4_0GY97td00e8uyzlHc3Sr6EKE,225211
12
+ batplot/interactive.py,sha256=b-0xeza_Rs4S59ve-pyWVq_-FvTpqDIy1tu4M3tT3Eg,300447
13
13
  batplot/manual.py,sha256=pbRI6G4Pm12pOW8LrOLWWu7IEOtqWN3tRHtgge50LlA,11556
14
14
  batplot/modes.py,sha256=qE2OsOQQKhwOWene5zxJeuuewTrZxubtahQuz5je7ok,37252
15
- batplot/operando.py,sha256=p2Ug1mFUQxaU702cTBGgJKb3_v1C2p3LLUwfXaVBpPY,28311
16
- batplot/operando_ec_interactive.py,sha256=8GQ47-I8SLTS88sFEk8m3vDxFEjSfD3hao62Qke7SxA,305137
15
+ batplot/operando.py,sha256=h09xu1BsdR68YlzhWeUSypYX83DzjJABIQQS2noQzPI,29400
16
+ batplot/operando_ec_interactive.py,sha256=YExiuKn-qQksW3YFYCTpvumuCit4cc4YiiaSRWGa0og,317833
17
17
  batplot/plotting.py,sha256=hG2_EdDhF1Qpn1XfZKdCQ5-w_m9gUYFbr804UQ5QjsU,10841
18
18
  batplot/readers.py,sha256=kAI0AvYrdfGRZkvADJ4riN96IWtrH24aAoZpBtONTbw,112960
19
- batplot/session.py,sha256=sYhY3WH-Kks5SMO91kfGDkSs32SX_iFS62ZkUm3jwzY,142722
20
- batplot/style.py,sha256=jXtFaJR1aa6vIHupmDNqY2NY5Rgtw49UxF7cS4y8fCA,63375
19
+ batplot/session.py,sha256=sgcJyCj00lOhmIRdDxGSqu2vEpOm7WSFZzLXxukYNL0,144936
20
+ batplot/style.py,sha256=3XnWlU9aTb1b-aiq5BQOuAREE5nOEYZ0b75v_LS0xDM,67790
21
21
  batplot/ui.py,sha256=ifpbK74juUzLMCt-sJGVaWtpDb1NMRJzs2YyiwwafzY,35302
22
22
  batplot/utils.py,sha256=LY2-Axr3DsQMTxuXe48vSjrLJKEnkzkZjdSFdQizbpg,37599
23
23
  batplot/version_check.py,sha256=--U_74DKgHbGtVdBsg9DfUJ10S5-OMXT-rzaYjK0JBc,9997
24
- batplot/data/USER_MANUAL.md,sha256=VYPvNZt3Fy8Z4Izr2FnQBw9vEaFTPkybhHDnF-OuKws,17694
25
- batplot-1.8.4.dist-info/licenses/LICENSE,sha256=2PAnHeCiTfgI7aKZLWr0G56HI9fGKQ0CEbQ02H-yExQ,1065
24
+ batplot/data/USER_MANUAL.md,sha256=w6pmDXoLINFkCWWh3zay7uNIxUaDxSOrocnPIZwu2uA,19542
25
+ batplot-1.8.5.dist-info/licenses/LICENSE,sha256=2PAnHeCiTfgI7aKZLWr0G56HI9fGKQ0CEbQ02H-yExQ,1065
26
26
  batplot_backup_20251121_223043/__init__.py,sha256=3s2DUQuTbWs65hoN9cQQ8IiJbaFJY8fNxiCpwRBYoOA,118
27
27
  batplot_backup_20251121_223043/args.py,sha256=OH-h84QhN-IhMS8sPAsSEqccHD3wpeMgmXa_fqv5xtg,21215
28
28
  batplot_backup_20251121_223043/batch.py,sha256=oI7PONJyciHDOqNPq-8fnOQMyn9CpAdVznKaEdsy0ig,48650
@@ -68,8 +68,8 @@ batplot_backup_20251221_101150/style.py,sha256=ig1ozX4dhEsXf5JKaPZOvgVS3CWx-BTFS
68
68
  batplot_backup_20251221_101150/ui.py,sha256=ifpbK74juUzLMCt-sJGVaWtpDb1NMRJzs2YyiwwafzY,35302
69
69
  batplot_backup_20251221_101150/utils.py,sha256=LY2-Axr3DsQMTxuXe48vSjrLJKEnkzkZjdSFdQizbpg,37599
70
70
  batplot_backup_20251221_101150/version_check.py,sha256=ztTHwqgWd8OlS9PLLY5A_TabWxBASDA_-5yyN15PZC8,9996
71
- batplot-1.8.4.dist-info/METADATA,sha256=da51wuDhz7bqCTInJ_tjZzZy2wC6ujSfsrgYIi-GYgI,7175
72
- batplot-1.8.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
73
- batplot-1.8.4.dist-info/entry_points.txt,sha256=73GgH3Zs-qGIvgiyQLgGsSW-ryOwPPKHveOW6TDIR5Q,82
74
- batplot-1.8.4.dist-info/top_level.txt,sha256=Z5Q4sAiT_FDqZqhlLsYn9avRTuFAEEf3AVfkswxOb18,70
75
- batplot-1.8.4.dist-info/RECORD,,
71
+ batplot-1.8.5.dist-info/METADATA,sha256=WTflN9nVzAXg4xPnjpjfJeRNhuyUaXaJKBLyjhjVxko,7175
72
+ batplot-1.8.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
73
+ batplot-1.8.5.dist-info/entry_points.txt,sha256=73GgH3Zs-qGIvgiyQLgGsSW-ryOwPPKHveOW6TDIR5Q,82
74
+ batplot-1.8.5.dist-info/top_level.txt,sha256=Z5Q4sAiT_FDqZqhlLsYn9avRTuFAEEf3AVfkswxOb18,70
75
+ batplot-1.8.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5