batplot 1.7.25__py3-none-any.whl → 1.7.26__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/__init__.py +1 -1
- batplot/batplot.py +62 -31
- batplot/color_utils.py +13 -6
- batplot/cpc_interactive.py +511 -320
- batplot/electrochem_interactive.py +20 -2
- batplot/interactive.py +8 -4
- batplot/operando_ec_interactive.py +1 -1
- batplot/session.py +11 -3
- batplot/ui.py +13 -29
- {batplot-1.7.25.dist-info → batplot-1.7.26.dist-info}/METADATA +1 -1
- {batplot-1.7.25.dist-info → batplot-1.7.26.dist-info}/RECORD +15 -15
- {batplot-1.7.25.dist-info → batplot-1.7.26.dist-info}/WHEEL +0 -0
- {batplot-1.7.25.dist-info → batplot-1.7.26.dist-info}/entry_points.txt +0 -0
- {batplot-1.7.25.dist-info → batplot-1.7.26.dist-info}/licenses/LICENSE +0 -0
- {batplot-1.7.25.dist-info → batplot-1.7.26.dist-info}/top_level.txt +0 -0
|
@@ -1684,6 +1684,13 @@ def electrochem_interactive_menu(fig, ax, cycle_lines: Dict[int, Dict[str, Optio
|
|
|
1684
1684
|
if not already_confirmed and os.path.exists(target):
|
|
1685
1685
|
target = _confirm_overwrite(target)
|
|
1686
1686
|
if target:
|
|
1687
|
+
# Save current legend position before export (savefig can change layout)
|
|
1688
|
+
saved_legend_pos = None
|
|
1689
|
+
try:
|
|
1690
|
+
saved_legend_pos = getattr(fig, '_ec_legend_xy_in', None)
|
|
1691
|
+
except Exception:
|
|
1692
|
+
pass
|
|
1693
|
+
|
|
1687
1694
|
# If exporting SVG, make background transparent for PowerPoint
|
|
1688
1695
|
_, ext2 = os.path.splitext(target)
|
|
1689
1696
|
ext2 = ext2.lower()
|
|
@@ -1727,6 +1734,15 @@ def electrochem_interactive_menu(fig, ax, cycle_lines: Dict[int, Dict[str, Optio
|
|
|
1727
1734
|
fig.savefig(target, bbox_inches='tight')
|
|
1728
1735
|
print(f"Exported figure to {target}")
|
|
1729
1736
|
fig._last_figure_export_path = target
|
|
1737
|
+
|
|
1738
|
+
# Restore legend position after savefig (which may have changed layout)
|
|
1739
|
+
if saved_legend_pos is not None:
|
|
1740
|
+
try:
|
|
1741
|
+
fig._ec_legend_xy_in = saved_legend_pos
|
|
1742
|
+
_rebuild_legend(ax)
|
|
1743
|
+
fig.canvas.draw_idle()
|
|
1744
|
+
except Exception:
|
|
1745
|
+
pass
|
|
1730
1746
|
except Exception as e:
|
|
1731
1747
|
print(f"Export failed: {e}")
|
|
1732
1748
|
except Exception as e:
|
|
@@ -3283,8 +3299,10 @@ def electrochem_interactive_menu(fig, ax, cycle_lines: Dict[int, Dict[str, Optio
|
|
|
3283
3299
|
continue
|
|
3284
3300
|
elif key == 'f':
|
|
3285
3301
|
# Font submenu with numbered options
|
|
3302
|
+
cur_family = plt.rcParams.get('font.sans-serif', [''])[0]
|
|
3303
|
+
cur_size = plt.rcParams.get('font.size', None)
|
|
3286
3304
|
while True:
|
|
3287
|
-
print("\nFont menu: f=font family, s=size, q=back")
|
|
3305
|
+
print(f"\nFont menu (current: family='{cur_family}', size={cur_size}): f=font family, s=size, q=back")
|
|
3288
3306
|
sub = input("Font> ").strip().lower()
|
|
3289
3307
|
if not sub:
|
|
3290
3308
|
continue
|
|
@@ -3298,7 +3316,7 @@ def electrochem_interactive_menu(fig, ax, cycle_lines: Dict[int, Dict[str, Optio
|
|
|
3298
3316
|
for i, font in enumerate(fonts, 1):
|
|
3299
3317
|
print(f" {i}: {font}")
|
|
3300
3318
|
print("Or enter custom font name directly.")
|
|
3301
|
-
choice = input("Font family (number or name): ").strip()
|
|
3319
|
+
choice = input(f"Font family (current: '{cur_family}', number or name): ").strip()
|
|
3302
3320
|
if not choice:
|
|
3303
3321
|
continue
|
|
3304
3322
|
# Check if it's a number
|
batplot/interactive.py
CHANGED
|
@@ -963,7 +963,7 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
|
|
|
963
963
|
txt = ax.text(1.0, 1.0, "",
|
|
964
964
|
ha='right', va='bottom',
|
|
965
965
|
transform=ax.transAxes,
|
|
966
|
-
fontsize=max(9, int(0.6 * plt.rcParams.get('font.size',
|
|
966
|
+
fontsize=max(9, int(0.6 * plt.rcParams.get('font.size', 16))),
|
|
967
967
|
color='0.15',
|
|
968
968
|
bbox=dict(boxstyle='round,pad=0.25', fc='white', ec='0.7', alpha=0.8))
|
|
969
969
|
|
|
@@ -3130,15 +3130,18 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
|
|
|
3130
3130
|
except Exception as e:
|
|
3131
3131
|
print(f"Error setting widths: {e}")
|
|
3132
3132
|
elif key == 'f':
|
|
3133
|
+
cur_family = plt.rcParams.get('font.sans-serif', [''])[0]
|
|
3134
|
+
cur_size = plt.rcParams.get('font.size', None)
|
|
3133
3135
|
while True:
|
|
3134
|
-
subkey = input(colorize_prompt("Font submenu (s=size, f=family, q=return
|
|
3136
|
+
subkey = input(colorize_prompt(f"Font submenu (current: family='{cur_family}', size={cur_size}) - s=size, f=family, q=return: ")).strip().lower()
|
|
3135
3137
|
if subkey == 'q':
|
|
3136
3138
|
break
|
|
3137
3139
|
if subkey == '':
|
|
3138
3140
|
continue
|
|
3139
3141
|
if subkey == 's':
|
|
3140
3142
|
try:
|
|
3141
|
-
|
|
3143
|
+
cur_size = plt.rcParams.get('font.size', None)
|
|
3144
|
+
fs = input(f"Enter new font size (current: {cur_size}, q=cancel): ").strip()
|
|
3142
3145
|
if not fs or fs.lower() == 'q':
|
|
3143
3146
|
print("Canceled.")
|
|
3144
3147
|
else:
|
|
@@ -3153,13 +3156,14 @@ def interactive_menu(fig, ax, y_data_list, x_data_list, labels, orig_y,
|
|
|
3153
3156
|
print(f"Error changing font size: {e}")
|
|
3154
3157
|
elif subkey == 'f':
|
|
3155
3158
|
try:
|
|
3159
|
+
cur_family = plt.rcParams.get('font.sans-serif', [''])[0]
|
|
3156
3160
|
print("Common publication fonts:")
|
|
3157
3161
|
print(" 1) Arial")
|
|
3158
3162
|
print(" 2) Helvetica")
|
|
3159
3163
|
print(" 3) Times New Roman")
|
|
3160
3164
|
print(" 4) STIXGeneral")
|
|
3161
3165
|
print(" 5) DejaVu Sans")
|
|
3162
|
-
ft_raw = input("Enter font number or family name (q=cancel): ").strip()
|
|
3166
|
+
ft_raw = input(f"Enter font number or family name (current: '{cur_family}', q=cancel): ").strip()
|
|
3163
3167
|
if not ft_raw or ft_raw.lower() == 'q':
|
|
3164
3168
|
print("Canceled.")
|
|
3165
3169
|
else:
|
|
@@ -1553,7 +1553,7 @@ def operando_ec_interactive_menu(fig, ax, im, cbar, ec_ax, file_paths=None):
|
|
|
1553
1553
|
# Create text annotations for coordinates
|
|
1554
1554
|
coord_text = fig.text(0.02, 0.98, '', transform=fig.transFigure,
|
|
1555
1555
|
verticalalignment='top',
|
|
1556
|
-
fontsize=max(9, int(0.6 * mpl_plt.rcParams.get('font.size',
|
|
1556
|
+
fontsize=max(9, int(0.6 * mpl_plt.rcParams.get('font.size', 16))),
|
|
1557
1557
|
color='0.15',
|
|
1558
1558
|
bbox=dict(boxstyle='round,pad=0.25', fc='white', ec='0.7', alpha=0.8))
|
|
1559
1559
|
except Exception as e:
|
batplot/session.py
CHANGED
|
@@ -2868,15 +2868,23 @@ def load_cpc_session(filename: str):
|
|
|
2868
2868
|
fw, fh = fig.get_size_inches()
|
|
2869
2869
|
fx = 0.5 + float(xy_in[0]) / float(fw)
|
|
2870
2870
|
fy = 0.5 + float(xy_in[1]) / float(fh)
|
|
2871
|
-
|
|
2871
|
+
# Use same spacing parameters as _legend_no_frame for consistent legend appearance
|
|
2872
|
+
leg = ax.legend(H, L, loc='center', bbox_to_anchor=(fx, fy), bbox_transform=fig.transFigure,
|
|
2873
|
+
handlelength=1.0, handletextpad=0.35, labelspacing=0.25,
|
|
2874
|
+
borderaxespad=0.5, borderpad=0.3, columnspacing=0.6,
|
|
2875
|
+
labelcolor='linecolor', frameon=False)
|
|
2872
2876
|
# persist inches on fig for interactive menu
|
|
2873
2877
|
try:
|
|
2874
2878
|
fig._cpc_legend_xy_in = (float(xy_in[0]), float(xy_in[1]))
|
|
2875
2879
|
except Exception:
|
|
2876
2880
|
pass
|
|
2877
2881
|
else:
|
|
2878
|
-
|
|
2879
|
-
|
|
2882
|
+
# Use same spacing parameters as _legend_no_frame for consistent legend appearance
|
|
2883
|
+
leg = ax.legend(H, L, loc='best',
|
|
2884
|
+
handlelength=1.0, handletextpad=0.35, labelspacing=0.25,
|
|
2885
|
+
borderaxespad=0.5, borderpad=0.3, columnspacing=0.6,
|
|
2886
|
+
labelcolor='linecolor', frameon=False)
|
|
2887
|
+
# Ensure legend frame is off (redundant but safe)
|
|
2880
2888
|
try:
|
|
2881
2889
|
if leg is not None:
|
|
2882
2890
|
leg.set_frame_on(False)
|
batplot/ui.py
CHANGED
|
@@ -611,7 +611,7 @@ def resize_plot_frame(fig, ax, y_data_list: List, label_text_objects: List, args
|
|
|
611
611
|
ax_bbox = ax.get_position()
|
|
612
612
|
cur_ax_w_in = ax_bbox.width * fig_w_in
|
|
613
613
|
cur_ax_h_in = ax_bbox.height * fig_h_in
|
|
614
|
-
print(f"Current canvas
|
|
614
|
+
print(f"Current canvas: {fig_w_in:.2f} x {fig_h_in:.2f} in")
|
|
615
615
|
print(f"Current plot frame: {cur_ax_w_in:.2f} x {cur_ax_h_in:.2f} in (W x H)")
|
|
616
616
|
try:
|
|
617
617
|
spec = input("Enter new plot frame size (e.g. '6 4', '6x4', 'w=6 h=4', 'scale=1.2', single width, q=back): ").strip().lower()
|
|
@@ -651,16 +651,9 @@ def resize_plot_frame(fig, ax, y_data_list: List, label_text_objects: List, args
|
|
|
651
651
|
print("Could not parse specification.")
|
|
652
652
|
continue
|
|
653
653
|
req_w_in, req_h_in = new_w_in, new_h_in
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
if new_w_in > max_w_in:
|
|
658
|
-
print(f"Requested width {new_w_in:.2f} exceeds max {max_w_in:.2f}; clamped.")
|
|
659
|
-
new_w_in = max_w_in
|
|
660
|
-
if new_h_in > max_h_in:
|
|
661
|
-
print(f"Requested height {new_h_in:.2f} exceeds max {max_h_in:.2f}; clamped.")
|
|
662
|
-
new_h_in = max_h_in
|
|
663
|
-
min_ax_in = 0.25
|
|
654
|
+
# Apply exact requested size without any clamping
|
|
655
|
+
# Only enforce minimum size to prevent division by zero
|
|
656
|
+
min_ax_in = 0.01
|
|
664
657
|
new_w_in = max(min_ax_in, new_w_in)
|
|
665
658
|
new_h_in = max(min_ax_in, new_h_in)
|
|
666
659
|
tol = 1e-3
|
|
@@ -676,33 +669,24 @@ def resize_plot_frame(fig, ax, y_data_list: List, label_text_objects: List, args
|
|
|
676
669
|
lm, bm, rm, tm = fig._last_user_margins
|
|
677
670
|
fig.subplots_adjust(left=lm, bottom=bm, right=rm, top=tm)
|
|
678
671
|
update_labels_func(ax, y_data_list, label_text_objects, args.stack)
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
continue
|
|
672
|
+
fig.canvas.draw_idle()
|
|
673
|
+
print(f"Plot frame unchanged ({new_w_in:.2f} x {new_h_in:.2f} in); layout preserved.")
|
|
674
|
+
continue
|
|
683
675
|
left = (1 - w_frac) / 2
|
|
684
676
|
right = left + w_frac
|
|
685
677
|
bottom = (1 - h_frac) / 2
|
|
686
678
|
top = bottom + h_frac
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
right = min(1 - min_margin_frac, right)
|
|
690
|
-
top = min(1 - min_margin_frac, top)
|
|
691
|
-
if right - left < 0.05 or top - bottom < 0.05:
|
|
692
|
-
print("Requested frame too small after safety clamps; aborting.")
|
|
693
|
-
else:
|
|
694
|
-
fig.subplots_adjust(left=left, right=right, bottom=bottom, top=top)
|
|
679
|
+
# Apply exact size without margin clamping
|
|
680
|
+
fig.subplots_adjust(left=left, right=right, bottom=bottom, top=top)
|
|
695
681
|
update_labels_func(ax, y_data_list, label_text_objects, args.stack)
|
|
696
|
-
|
|
682
|
+
# Store the final size (exactly as requested, no text visibility adjustments)
|
|
697
683
|
sp = fig.subplotpars
|
|
698
|
-
fig._last_user_axes_inches = (
|
|
684
|
+
fig._last_user_axes_inches = (new_w_in, new_h_in)
|
|
699
685
|
fig._last_user_margins = (sp.left, sp.bottom, sp.right, sp.top)
|
|
700
686
|
final_w_in = (sp.right - sp.left) * fig_w_in
|
|
701
687
|
final_h_in = (sp.top - sp.bottom) * fig_h_in
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
else:
|
|
705
|
-
print(f"Plot frame set to {final_w_in:.2f} x {final_h_in:.2f} in inside fixed canvas {fig_w_in:.2f} x {fig_h_in:.2f} in.")
|
|
688
|
+
# Show the requested size (which is what was applied)
|
|
689
|
+
print(f"Plot frame set to {req_w_in:.2f} x {req_h_in:.2f} in inside canvas {fig_w_in:.2f} x {fig_h_in:.2f} in.")
|
|
706
690
|
except KeyboardInterrupt:
|
|
707
691
|
print("Canceled.")
|
|
708
692
|
return
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: batplot
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.26
|
|
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=
|
|
1
|
+
batplot/__init__.py,sha256=l-iAn_Q1KA7sJv2vOZzjjw4K2UWfntwGpQk9Z3lyuRw,119
|
|
2
2
|
batplot/args.py,sha256=6g1eHVsycDSAenwrXuCTcyuXCy_-30zy1lWtdguBG2s,34983
|
|
3
3
|
batplot/batch.py,sha256=YQ7obCIqLCObwDbM7TXpOBh7g7BO95wZNsa2Fy84c6o,53858
|
|
4
|
-
batplot/batplot.py,sha256=
|
|
4
|
+
batplot/batplot.py,sha256=40lU1nY1NqeAOpzNG_vLF_L34COKhiA19pMpbvA3SJc,171885
|
|
5
5
|
batplot/cif.py,sha256=JfHwNf3SHrcpALc_F5NjJmQ3lg71MBRSaIUJjGYPTx8,30120
|
|
6
6
|
batplot/cli.py,sha256=ScDb2je8VQ0mz_z0SLCHEigiTuFPY5pb1snnzCouKms,5828
|
|
7
|
-
batplot/color_utils.py,sha256=
|
|
7
|
+
batplot/color_utils.py,sha256=7InQLVo1XTg7sgAbltM2KeDSFJgr787YEaV9vJbIoWY,20460
|
|
8
8
|
batplot/config.py,sha256=6nGY7fKN4T5KZUGQS2ArUBgEkLAL0j37XwG5SCVQgKA,6420
|
|
9
9
|
batplot/converters.py,sha256=rR2WMPM0nR5E3eZI3gWbaJf_AfbdQx3urVSbJmZXNzo,8237
|
|
10
|
-
batplot/cpc_interactive.py,sha256=
|
|
11
|
-
batplot/electrochem_interactive.py,sha256=
|
|
12
|
-
batplot/interactive.py,sha256=
|
|
10
|
+
batplot/cpc_interactive.py,sha256=YGt-TLfO5W_YyUdIInfW6y6bZxQJyfeGX7JGBv1kNbs,232634
|
|
11
|
+
batplot/electrochem_interactive.py,sha256=n_Jc9shH4LIL3r6z3MXnx02ZddMKZoh4dg25hHhfJRw,218297
|
|
12
|
+
batplot/interactive.py,sha256=johjaK8Er1y3rc5Cvg0C3Lv8Cqf2IliOyYrSnSrCzW4,203997
|
|
13
13
|
batplot/manual.py,sha256=pbRI6G4Pm12pOW8LrOLWWu7IEOtqWN3tRHtgge50LlA,11556
|
|
14
14
|
batplot/modes.py,sha256=qE2OsOQQKhwOWene5zxJeuuewTrZxubtahQuz5je7ok,37252
|
|
15
15
|
batplot/operando.py,sha256=CdTZJa6Cr1wNczFEbwAido2mc7C_h1xxoQ5b045ktSk,28105
|
|
16
|
-
batplot/operando_ec_interactive.py,sha256=
|
|
16
|
+
batplot/operando_ec_interactive.py,sha256=BOFj1E7H7b1wW0_pNwYCf7e2E70HemYzl1UjHihxB68,293096
|
|
17
17
|
batplot/plotting.py,sha256=hG2_EdDhF1Qpn1XfZKdCQ5-w_m9gUYFbr804UQ5QjsU,10841
|
|
18
18
|
batplot/readers.py,sha256=kAI0AvYrdfGRZkvADJ4riN96IWtrH24aAoZpBtONTbw,112960
|
|
19
|
-
batplot/session.py,sha256=
|
|
19
|
+
batplot/session.py,sha256=FEWYHu1XUIrWxD3an5m7HB57pHst2CHgJ_brAmCBk38,132199
|
|
20
20
|
batplot/style.py,sha256=ZeRJ15fneSQqCYN_SGap-9Y2J8UkzRxYmf6qLJA6zMo,62058
|
|
21
|
-
batplot/ui.py,sha256=
|
|
21
|
+
batplot/ui.py,sha256=ifpbK74juUzLMCt-sJGVaWtpDb1NMRJzs2YyiwwafzY,35302
|
|
22
22
|
batplot/utils.py,sha256=3dBZALWiCu5c6uc5MBII7n8329BZjieTEw4qithTlow,33939
|
|
23
23
|
batplot/version_check.py,sha256=OG4LuHo5-rSqLLHQo5nWbX9lbNq6NyxRdvVUUcJRBqQ,6219
|
|
24
24
|
batplot/data/USER_MANUAL.md,sha256=VYPvNZt3Fy8Z4Izr2FnQBw9vEaFTPkybhHDnF-OuKws,17694
|
|
25
|
-
batplot-1.7.
|
|
25
|
+
batplot-1.7.26.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
|
|
@@ -45,8 +45,8 @@ batplot_backup_20251121_223043/style.py,sha256=xg-tj6bEbFUVjjxYMokiLehS4tSfKanLI
|
|
|
45
45
|
batplot_backup_20251121_223043/ui.py,sha256=K0XZWyiuBRNkFod9mgZyJ9CLN78GR1-hh6EznnIb5S8,31208
|
|
46
46
|
batplot_backup_20251121_223043/utils.py,sha256=jydA0JxsCWWAudXEwSjlxTG17y2F8U6hIAukAzi1P0g,32526
|
|
47
47
|
batplot_backup_20251121_223043/version_check.py,sha256=vlHkGkgUJcD_Z4KZmwonxZvKZh0MwHLaBSxaLPc66AQ,4555
|
|
48
|
-
batplot-1.7.
|
|
49
|
-
batplot-1.7.
|
|
50
|
-
batplot-1.7.
|
|
51
|
-
batplot-1.7.
|
|
52
|
-
batplot-1.7.
|
|
48
|
+
batplot-1.7.26.dist-info/METADATA,sha256=nuvFZX39gTf0X-Dxff9jzQur4tLBTpRPuE55CPiYEdA,7407
|
|
49
|
+
batplot-1.7.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
50
|
+
batplot-1.7.26.dist-info/entry_points.txt,sha256=73GgH3Zs-qGIvgiyQLgGsSW-ryOwPPKHveOW6TDIR5Q,82
|
|
51
|
+
batplot-1.7.26.dist-info/top_level.txt,sha256=CgqK4RpsYnUFAcqO4bLOnEhCoPY4IPEGLPkiDlzLIxg,39
|
|
52
|
+
batplot-1.7.26.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|