batplot 1.0.6__tar.gz → 1.0.7__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.
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: batplot
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: Interactive plotting for XRD, PDF, and XAS data (.xye, .xy, .qye, .dat, .csv, .gr, .nor, .chik, .chir)
5
- Author-email: Your Name <your@email.com>
5
+ Author-email: Tian Dai <tianda@uio.no>
6
6
  Requires-Python: >=3.7
7
7
  Description-Content-Type: text/markdown
8
8
  Requires-Dist: numpy
@@ -649,19 +649,19 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
649
649
  # REPLACED print_main_menu with column layout (now hides 'd' and 'y' in --stack)
650
650
  is_diffraction = use_Q or (not use_r and not use_E and not use_k and not use_rft) # 2θ or Q
651
651
  def print_main_menu():
652
- col1 = ["c: colors", "f: font", "l: line", "t: ticks"]
652
+ has_cif = False
653
653
  try:
654
- if any(f.lower().endswith('.cif') for f in args.files):
655
- col1.append("z: hkl")
654
+ has_cif = any(f.lower().endswith('.cif') for f in args.files)
656
655
  except Exception:
657
656
  pass
657
+ col1 = ["c: colors", "f: font", "l: line", "t: ticks"]
658
+ if has_cif:
659
+ col1.append("z: hkl")
658
660
  col2 = ["a: rearrange", "d: offset", "r: rename", "g: size","x: change X", "y: change Y"]
659
- # Added s: save (session). 'o: open' removed; load .pkl by invoking batplot file.pkl
660
661
  col3 = ["v: find peaks", "p: print style", "i: import style", "n: crosshair", "e: export", "s: save", "b: undo", "q: quit"]
661
662
  if args.stack:
662
663
  col2 = [item for item in col2 if not item.startswith("d:") and not item.startswith("y:")]
663
664
  if not is_diffraction:
664
- # Remove crosshair option in non-diffraction modes
665
665
  col3 = [item for item in col3 if not item.startswith("n:")]
666
666
  rows = max(len(col1), len(col2), len(col3))
667
667
  print("\nInteractive menu:")
@@ -671,6 +671,17 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
671
671
  p2 = col2[i] if i < len(col2) else ""
672
672
  p3 = col3[i] if i < len(col3) else ""
673
673
  print(f" {p1:<16} {p2:<16} {p3:<16}")
674
+
675
+ # --- Helper for spine visibility ---
676
+ def set_spine_visible(which, visible):
677
+ if which in ax.spines:
678
+ ax.spines[which].set_visible(visible)
679
+ fig.canvas.draw_idle()
680
+
681
+ def get_spine_visible(which):
682
+ if which in ax.spines:
683
+ return ax.spines[which].get_visible()
684
+ return False
674
685
  # Initial menu display REMOVED to avoid double print
675
686
  # print_main_menu()
676
687
  ax.set_aspect('auto', adjustable='datalim')
@@ -727,6 +738,20 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
727
738
  if new_family:
728
739
  axis_label.set_fontfamily(new_family)
729
740
 
741
+ # Top duplicate label
742
+ if hasattr(ax, '_top_xlabel_artist') and ax._top_xlabel_artist is not None:
743
+ if new_size is not None:
744
+ ax._top_xlabel_artist.set_fontsize(new_size)
745
+ if new_family:
746
+ ax._top_xlabel_artist.set_fontfamily(new_family)
747
+
748
+ # Right duplicate manual label
749
+ if hasattr(ax, '_right_ylabel_artist') and ax._right_ylabel_artist is not None:
750
+ if new_size is not None:
751
+ ax._right_ylabel_artist.set_fontsize(new_size)
752
+ if new_family:
753
+ ax._right_ylabel_artist.set_fontfamily(new_family)
754
+
730
755
  # Tick labels
731
756
  for lbl in ax.get_xticklabels() + ax.get_yticklabels():
732
757
  if new_size is not None:
@@ -852,32 +877,6 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
852
877
  if x == BIRD_X and y == bird_y:
853
878
  ch = "@"
854
879
  # obstacle
855
- else:
856
- for o in obstacles:
857
- if o.x == x:
858
- if not (o.gap_start <= y < o.gap_start + GAP_SIZE):
859
- ch = "#"
860
- break
861
- row_chars.append(ch)
862
- print("|" + "".join(row_chars) + "|")
863
- print(top_border)
864
- print(f"Tick: {tick} Score: {score} (j=jump, Enter=fall, q=quit)")
865
-
866
- def collision():
867
- # ground / ceiling
868
- if bird_y < 0 or bird_y >= HEIGHT:
869
- return True
870
- for o in obstacles:
871
- if o.x == BIRD_X:
872
- if not (o.gap_start <= bird_y < o.gap_start + GAP_SIZE):
873
- return True
874
- return False
875
-
876
- print("\n=== Jumping Bird ===")
877
- print("Looks like you entered a wrong command!")
878
- print("Goal: pass pillars (#). Controls each turn:")
879
- print(" j + Enter -> jump")
880
- print(" Enter -> fall")
881
880
  print(" q -> quit game")
882
881
  print("Bird = @ | Score increments when you pass a pillar.\n")
883
882
 
@@ -1402,6 +1401,8 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1402
1401
  if line.get_visible():
1403
1402
  return line.get_linewidth()
1404
1403
  return None
1404
+ # Save spine visibility
1405
+ spine_vis = {name: sp.get_visible() for name, sp in ax.spines.items()}
1405
1406
 
1406
1407
  bbox = ax.get_position()
1407
1408
  frame_w_in = bbox.width * fw
@@ -1439,7 +1440,8 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1439
1440
  "spines": {
1440
1441
  name: {
1441
1442
  "linewidth": sp.get_linewidth(),
1442
- "color": sp.get_edgecolor()
1443
+ "color": sp.get_edgecolor(),
1444
+ "visible": spine_vis.get(name, True)
1443
1445
  } for name, sp in ax.spines.items()
1444
1446
  },
1445
1447
  "lines": [
@@ -1621,6 +1623,8 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1621
1623
  ax.spines[name].set_edgecolor(sp_dict["color"])
1622
1624
  except Exception:
1623
1625
  pass
1626
+ if "visible" in sp_dict:
1627
+ ax.spines[name].set_visible(sp_dict["visible"])
1624
1628
 
1625
1629
  # ---- Lines (full style) ----
1626
1630
  for entry in cfg.get("lines", []):
@@ -1840,6 +1844,8 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1840
1844
  fw, fh = fig.get_size_inches()
1841
1845
  frame_w_in = bbox.width * fw
1842
1846
  frame_h_in = bbox.height * fh
1847
+ # Save spine visibility
1848
+ spine_vis = {name: sp.get_visible() for name, sp in ax.spines.items()}
1843
1849
  sess = {
1844
1850
  'version': SESSION_VERSION,
1845
1851
  'x_data': [np.array(a) for a in x_data_list],
@@ -1877,7 +1883,8 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1877
1883
  'bottom': float(bbox.y0),
1878
1884
  'right': float(bbox.x0 + bbox.width),
1879
1885
  'top': float(bbox.y0 + bbox.height)
1880
- }
1886
+ },
1887
+ 'spine_vis': spine_vis
1881
1888
  },
1882
1889
  'tick_state': tick_state.copy(),
1883
1890
  'font': {
@@ -1990,6 +1997,11 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
1990
1997
  pass
1991
1998
  # Restore figure size & dpi if present
1992
1999
  fig_cfg = sess.get('figure', {})
2000
+ # Restore spine visibility if present
2001
+ spine_vis = fig_cfg.get('spine_vis', {})
2002
+ for name, vis in spine_vis.items():
2003
+ if name in ax.spines:
2004
+ ax.spines[name].set_visible(vis)
1993
2005
  try:
1994
2006
  if fig_cfg.get('size') and isinstance(fig_cfg['size'], (list, tuple)) and len(fig_cfg['size']) == 2:
1995
2007
  fw, fh = fig_cfg['size']
@@ -2357,11 +2369,16 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
2357
2369
  play_jump_game(); continue
2358
2370
  elif key == 'c':
2359
2371
  try:
2372
+ has_cif = False
2373
+ try:
2374
+ has_cif = any(f.lower().endswith('.cif') for f in args.files)
2375
+ except Exception:
2376
+ pass
2360
2377
  while True:
2361
2378
  print("Color menu:")
2362
2379
  print(" m : manual color mapping (e.g., 1:red 2:#00B006)")
2363
2380
  print(" p : apply colormap palette to a range (e.g., 1-3 viridis)")
2364
- if cif_tick_series:
2381
+ if has_cif and cif_tick_series:
2365
2382
  print(" t : change CIF tick set color (e.g., 1:red 2:#888888)")
2366
2383
  print(" q : return to main menu")
2367
2384
  sub = input("Choose (m/p/t/q): ").strip().lower()
@@ -2393,7 +2410,7 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
2393
2410
  except ValueError:
2394
2411
  print(f"Bad index: {idx_str}")
2395
2412
  fig.canvas.draw()
2396
- elif sub == 't' and cif_tick_series:
2413
+ elif sub == 't' and has_cif and cif_tick_series:
2397
2414
  print("Current CIF tick sets:")
2398
2415
  for i,(lab,_,_,_,_,color) in enumerate(cif_tick_series):
2399
2416
  print(f" {i+1}: {lab} (color {color})")
@@ -2514,8 +2531,17 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
2514
2531
  print(f"Error in color menu: {e}")
2515
2532
  elif key == 'r':
2516
2533
  try:
2534
+ has_cif = False
2535
+ try:
2536
+ has_cif = any(f.lower().endswith('.cif') for f in args.files)
2537
+ except Exception:
2538
+ pass
2517
2539
  while True:
2518
- mode = input("Rename (c=curve, t=cif tick label, x=x-axis, y=y-axis, q=return): ").strip().lower()
2540
+ rename_opts = "c=curve"
2541
+ if has_cif:
2542
+ rename_opts += ", t=cif tick label"
2543
+ rename_opts += ", x=x-axis, y=y-axis, q=return"
2544
+ mode = input(f"Rename ({rename_opts}): ").strip().lower()
2519
2545
  if mode == 'q':
2520
2546
  break
2521
2547
  if mode == '':
@@ -3012,6 +3038,10 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
3012
3038
  print(" tt top X axis title")
3013
3039
  print(" lt left Y axis title")
3014
3040
  print(" rt right Y axis title")
3041
+ print(" bl bottom plot frame line (spine)")
3042
+ print(" tl top plot frame line (spine)")
3043
+ print(" ll left plot frame line (spine)")
3044
+ print(" rl right plot frame line (spine)")
3015
3045
  print(" list show state q return")
3016
3046
  cmd = input("Enter code(s): ").strip().lower()
3017
3047
  if not cmd:
@@ -3021,11 +3051,15 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
3021
3051
  parts = cmd.split()
3022
3052
  if parts == ['list']:
3023
3053
  print_tick_state()
3054
+ # Print spine (frame) visibility
3055
+ print("Spine (frame) visibility:")
3056
+ for spine in ['bottom','top','left','right']:
3057
+ vis = get_spine_visible(spine)
3058
+ print(f" {spine:<6}: {'ON ' if vis else 'off'}")
3024
3059
  continue
3025
3060
  push_state("tick-toggle")
3026
- # Helper to sync font sizes after structural changes
3027
- # (Use shared sync_fonts helper)
3028
3061
  for p in parts:
3062
+ # Axis title toggles
3029
3063
  if p in ('bt','tt','lt','rt'):
3030
3064
  if p == 'bt':
3031
3065
  cur = ax.get_xlabel()
@@ -3038,7 +3072,6 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
3038
3072
  elif p == 'tt':
3039
3073
  vis = getattr(ax, '_top_xlabel_on', False)
3040
3074
  if not vis:
3041
- # Create duplicate artist if not existing
3042
3075
  lbl_text = ax.get_xlabel()
3043
3076
  if not lbl_text:
3044
3077
  print("No bottom X label to duplicate.")
@@ -3066,12 +3099,10 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
3066
3099
  elif p == 'rt':
3067
3100
  vis = getattr(ax, '_right_ylabel_on', False)
3068
3101
  if not vis:
3069
- # Create manual duplicate text artist
3070
3102
  base = ax.get_ylabel()
3071
3103
  if not base:
3072
3104
  print("No left Y label to duplicate.")
3073
3105
  else:
3074
- # Remove any previous artist
3075
3106
  if hasattr(ax,'_right_ylabel_artist') and ax._right_ylabel_artist is not None:
3076
3107
  try: ax._right_ylabel_artist.remove()
3077
3108
  except Exception: pass
@@ -3089,6 +3120,15 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
3089
3120
  ax._right_ylabel_on = False
3090
3121
  print("Hid right Y axis title")
3091
3122
  continue
3123
+ # Plot frame (spine) toggles
3124
+ if p in ('bl','tl','ll','rl'):
3125
+ spine_map = {'bl':'bottom','tl':'top','ll':'left','rl':'right'}
3126
+ spine = spine_map[p]
3127
+ vis = get_spine_visible(spine)
3128
+ set_spine_visible(spine, not vis)
3129
+ print(f"Toggled {spine} spine -> {'ON' if not vis else 'off'}")
3130
+ continue
3131
+ # Tick toggles
3092
3132
  if p in tick_state:
3093
3133
  tick_state[p] = not tick_state[p]
3094
3134
  print(f"Toggled {p} -> {'ON' if tick_state[p] else 'off'}")
@@ -3262,17 +3302,24 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
3262
3302
  #
3263
3303
  # ---------------- Argument Parsing ----------------
3264
3304
  parser = argparse.ArgumentParser(
3265
- description="batplot: Plot diffraction / PDF / XAS data (.xye, .xy, .qye, .dat, .csv, .gr, .nor, .chik, .chir)\n"
3305
+ description="batplot: Plot diffraction / PDF / XAS data (.xye, .xy, .qye, .dat, .csv, .gr, .nor, .chik, .chir, .txt)\n"
3266
3306
  " --delta or -d : vertical offset between curves (default 0.0 if --stack)\n"
3267
3307
  " --xrange min max : X-axis range (2θ or Q), Example: --xrange 2 10\n"
3268
3308
  " --out or -o : output image filename (default SVG), Example: --out figure.svg\n"
3269
- " --xaxis : X-axis type override if the file extension is neither .xye nor .qye (2theta, Q, or r for PDF)\n"
3309
+ " --xaxis : X-axis type override if the file extension is not recognized (choose from: 2theta, Q, r, k, energy, rft, or 'user defined')\n"
3270
3310
  " --wl : global wavelength (Å) for Q conversion, Example: --wl 1.5406\n"
3271
3311
  " --fullprof : FullProf matrix: xstart xend xstep [wavelength], Example: --fullprof 2 10 0.02 1.5406\n"
3272
3312
  " --raw : plot raw intensity values instead of normalized\n"
3273
3313
  " --stack : stack curves from top to bottom\n"
3274
- "test"
3275
3314
  " --interactive : keep figure open for interactive editing\n\n"
3315
+ "File type and X-axis selection:\n"
3316
+ " - .qye: X axis is Q\n"
3317
+ " - .gr: X axis is r\n"
3318
+ " - .nor: X axis is Energy (eV)\n"
3319
+ " - .chik: X axis is k\n"
3320
+ " - .chir: X axis is r\n"
3321
+ " - .txt: Treated as generic 2-column data.\n"
3322
+ " If none of the files have a recognized extension, you must specify --xaxis (Q, 2theta, r, k, energy, rft, or 'user defined').\n"
3276
3323
  "Example usages:\n"
3277
3324
  " batplot file1.xye:1.5406 file2.qye --stack --interactive\n"
3278
3325
  " batplot file1.dat file2.dat --xaxis Q --wl 1.5406 --delta 1.0 --out figure.svg\n"
@@ -3289,7 +3336,7 @@ parser.add_argument("--autoscale", action="store_true")
3289
3336
  parser.add_argument("--xrange", "-r", nargs=2, type=float)
3290
3337
  parser.add_argument("--out", "-o", type=str)
3291
3338
  parser.add_argument("--errors", action="store_true")
3292
- parser.add_argument("--xaxis", choices=["2theta", "Q", "r"])
3339
+ parser.add_argument("--xaxis", type=str)
3293
3340
  parser.add_argument("--convert", "-c", nargs="+")
3294
3341
  parser.add_argument("--wl", type=float)
3295
3342
  parser.add_argument("--fullprof", nargs="+", type=float)
@@ -3326,7 +3373,7 @@ args = parser.parse_args()
3326
3373
  # ---------------- Batch Processing (directory or 'all') ----------------
3327
3374
  def batch_process(directory: str, args):
3328
3375
  print(f"Batch mode: scanning {directory}")
3329
- supported_ext = {'.xye', '.xy', '.qye', '.dat', '.csv', '.gr', '.nor', '.chik', '.chir'} # added .xy
3376
+ supported_ext = {'.xye', '.xy', '.qye', '.dat', '.csv', '.gr', '.nor', '.chik', '.chir', '.txt'} # added .xy, .txt
3330
3377
  out_dir = os.path.join(directory, "batplot_svg")
3331
3378
  os.makedirs(out_dir, exist_ok=True)
3332
3379
  files = [f for f in sorted(os.listdir(directory))
@@ -3364,20 +3411,27 @@ def batch_process(directory: str, args):
3364
3411
  x, y = data[:,0], data[:,1]; e = data[:,2] if data.shape[1] >= 3 else None
3365
3412
  axis_mode = 'rft'
3366
3413
  else:
3414
+ # Support .txt as generic 2-column data
3367
3415
  data = np.loadtxt(fpath, comments="#")
3368
3416
  if data.ndim == 1: data = data.reshape(1, -1)
3369
3417
  if data.shape[1] < 2: raise ValueError("Invalid 2-column data")
3370
3418
  x, y = data[:,0], data[:,1]
3371
3419
  e = data[:,2] if data.shape[1] >= 3 else None
3372
- # Decide axis: priority: user --xaxis, .qye -> Q, else if wavelength provided -> Q, else 2theta
3420
+ # Decide axis: priority: user --xaxis, .qye -> Q, .gr -> r, .nor -> energy, .chik -> k, .chir -> rft, else prompt for --xaxis
3373
3421
  if ext == '.qye':
3374
3422
  axis_mode = 'Q'
3375
- elif args.xaxis in ('Q','2theta'):
3423
+ elif ext == '.gr':
3424
+ axis_mode = 'r'
3425
+ elif ext == '.nor':
3426
+ axis_mode = 'energy'
3427
+ elif 'chik' in ext:
3428
+ axis_mode = 'k'
3429
+ elif 'chir' in ext:
3430
+ axis_mode = 'rft'
3431
+ elif args.xaxis:
3376
3432
  axis_mode = args.xaxis
3377
- elif args.wl is not None:
3378
- axis_mode = 'Q'
3379
3433
  else:
3380
- axis_mode = '2theta'
3434
+ raise ValueError("Cannot determine X-axis type for file {} (need .qye / .gr / .nor / .chik / .chir or specify --xaxis).".format(fname))
3381
3435
  # ---- Convert to Q if needed ----
3382
3436
  if axis_mode == 'Q' and ext not in ('.qye', '.gr', '.nor'):
3383
3437
  if args.wl is None:
@@ -3686,28 +3740,27 @@ raw_y_full_list = []
3686
3740
  offsets_list = []
3687
3741
 
3688
3742
  # ---------------- Determine X-axis type ----------------
3743
+ def _ext_token(path):
3744
+ return os.path.splitext(path)[1].lower() # includes leading dot
3689
3745
  any_qye = any(f.lower().endswith(".qye") for f in args.files)
3690
3746
  any_gr = any(f.lower().endswith(".gr") for f in args.files)
3691
- any_nor = any(f.lower().endswith(".nor") for f in args.files) # <-- NEW
3747
+ any_nor = any(f.lower().endswith(".nor") for f in args.files)
3748
+ any_chik = any("chik" in _ext_token(f) for f in args.files)
3749
+ any_chir = any("chir" in _ext_token(f) for f in args.files)
3750
+ any_txt = any(f.lower().endswith(".txt") for f in args.files)
3692
3751
  any_cif = any(f.lower().endswith(".cif") for f in args.files)
3693
3752
  non_cif_count = sum(0 if f.lower().endswith('.cif') else 1 for f in args.files)
3694
3753
  cif_only = any_cif and non_cif_count == 0
3695
- def _ext_token(path):
3696
- return os.path.splitext(path)[1].lower() # includes leading dot
3697
- any_chik = any("chik" in _ext_token(f) for f in args.files)
3698
- any_chir = any("chir" in _ext_token(f) for f in args.files)
3699
3754
  any_lambda = any(":" in f for f in args.files) or args.wl is not None
3700
3755
 
3701
3756
  # Incompatibilities (no mixing of fundamentally different axis domains)
3702
- if sum(bool(x) for x in (any_gr, any_nor, (any_qye or any_lambda or any_cif))) > 1 or \
3703
- (any_gr and args.xaxis in ("Q", "2theta", "r")) or \
3704
- (any_nor and args.xaxis in ("Q", "2theta", "r")):
3705
- raise ValueError("Cannot mix .gr (r), .nor (energy), and Q/2θ/CIF data. Plot them in separate runs.")
3706
-
3707
3757
  if sum(bool(x) for x in (any_gr, any_nor, any_chik, any_chir, (any_qye or any_lambda or any_cif))) > 1:
3708
- raise ValueError("Cannot mix .gr (r), .nor (energy), .chik (k), .chir (FT-EXAFS R) and Q/2θ/CIF data together. Split runs.")
3758
+ raise ValueError("Cannot mix .gr (r), .nor (energy), .chik (k), .chir (FT-EXAFS R), and Q/2θ/CIF data together. Split runs.")
3709
3759
 
3710
- if any_gr:
3760
+ # Automatic axis selection based on file extensions
3761
+ if any_qye:
3762
+ axis_mode = "Q"
3763
+ elif any_gr:
3711
3764
  axis_mode = "r"
3712
3765
  elif any_nor:
3713
3766
  axis_mode = "energy"
@@ -3715,6 +3768,12 @@ elif any_chik:
3715
3768
  axis_mode = "k"
3716
3769
  elif any_chir:
3717
3770
  axis_mode = "rft"
3771
+ elif any_txt:
3772
+ # .txt is generic, require --xaxis
3773
+ if args.xaxis:
3774
+ axis_mode = args.xaxis
3775
+ else:
3776
+ raise ValueError("Cannot determine X-axis type for .txt files. Please specify --xaxis (Q, 2theta, r, k, energy, rft, or 'user defined').")
3718
3777
  elif any_qye or any_lambda or any_cif:
3719
3778
  if args.xaxis and args.xaxis.lower() in ("2theta","two_theta","tth"):
3720
3779
  axis_mode = "2theta"
@@ -3723,7 +3782,7 @@ elif any_qye or any_lambda or any_cif:
3723
3782
  elif args.xaxis:
3724
3783
  axis_mode = args.xaxis
3725
3784
  else:
3726
- raise ValueError("Cannot determine X-axis type (need .qye / .gr / .nor / .chik / .chir / .cif / wavelength / --xaxis).")
3785
+ raise ValueError("Cannot determine X-axis type (need .qye / .gr / .nor / .chik / .chir / .cif / wavelength / --xaxis). For .txt or unknown file types, use --xaxis Q, 2theta, r, k, energy, rft, or 'user defined'.")
3727
3786
 
3728
3787
  use_Q = axis_mode == "Q"
3729
3788
  use_2th = axis_mode == "2theta"
@@ -4254,7 +4313,10 @@ elif use_k: x_label = r"k ($\mathrm{\AA}^{-1}$)"
4254
4313
  elif use_rft: x_label = "Radial distance (Å)"
4255
4314
  elif use_Q: x_label = r"Q ($\mathrm{\AA}^{-1}$)"
4256
4315
  elif use_2th: x_label = r"$2\theta$ (deg)"
4257
- else: x_label = "X"
4316
+ elif args.xaxis:
4317
+ x_label = str(args.xaxis)
4318
+ else:
4319
+ x_label = "X"
4258
4320
  ax.set_xlabel(x_label, fontsize=16)
4259
4321
  if args.raw:
4260
4322
  ax.set_ylabel("Intensity", fontsize=16)
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: batplot
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: Interactive plotting for XRD, PDF, and XAS data (.xye, .xy, .qye, .dat, .csv, .gr, .nor, .chik, .chir)
5
- Author-email: Your Name <your@email.com>
5
+ Author-email: Tian Dai <tianda@uio.no>
6
6
  Requires-Python: >=3.7
7
7
  Description-Content-Type: text/markdown
8
8
  Requires-Dist: numpy
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "batplot"
7
- version = "1.0.6"
7
+ version = "1.0.7"
8
8
  description = "Interactive plotting for XRD, PDF, and XAS data (.xye, .xy, .qye, .dat, .csv, .gr, .nor, .chik, .chir)"
9
9
  authors = [
10
- { name = "Your Name", email = "your@email.com" }
10
+ { name = "Tian Dai", email = "tianda@uio.no" }
11
11
  ]
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.7"
File without changes
File without changes