diff --git a/python/src/adctoolbox/aout/plot_dnl_inl.py b/python/src/adctoolbox/aout/plot_dnl_inl.py index 035d0f7..041ac76 100644 --- a/python/src/adctoolbox/aout/plot_dnl_inl.py +++ b/python/src/adctoolbox/aout/plot_dnl_inl.py @@ -124,8 +124,15 @@ def _plot_single_curve(ax, code, data, num_bits=None, ylabel='Data (LSB)', color color : str, default='r' Line color """ + code = np.asarray(code) + if num_bits is not None: + full_scale = 2**num_bits + x_values = code / full_scale + else: + x_values = code + # Plot curve - ax.plot(code, data, f'{color}-', linewidth=0.5) + ax.plot(x_values, data, f'{color}-', linewidth=0.5) # Add reference lines ax.axhline(1.0, color='gray', linestyle='--', linewidth=1.2, alpha=0.8) @@ -133,20 +140,17 @@ def _plot_single_curve(ax, code, data, num_bits=None, ylabel='Data (LSB)', color # Always show grid and labels ax.grid(True, alpha=0.3) - ax.set_xlabel('Code (LSB)') ax.set_ylabel(ylabel) # Set x-axis limits if num_bits is not None: - full_scale = 2**num_bits - ax.set_xlim([0, full_scale]) - # Set x-ticks: 1/8, 2/8, ..., 8/8 of full scale with actual code values as labels - tick_positions = [full_scale * i / 8 for i in range(1, 9)] - tick_labels = [f'{int(full_scale * i / 8)}' for i in range(1, 9)] - ax.set_xticks(tick_positions) - ax.set_xticklabels(tick_labels) + ax.set_xlim([0, 1]) + ax.set_xlabel(f'Code (2^{num_bits} LSB)') + ax.set_xticks([0, 0.25, 0.5, 0.75, 1.0]) + ax.set_xticklabels(['0', '0.25', '0.5', '0.75', '1']) else: ax.set_xlim([np.min(code), np.max(code)]) + ax.set_xlabel('Code (LSB)') # Set y-axis limits: minimum ±1, or 1.2x data range if larger data_min, data_max = np.min(data), np.max(data) diff --git a/python/src/adctoolbox/examples/04_debug_analog/exp_a32_inl_from_sine_sweep_length.py b/python/src/adctoolbox/examples/04_debug_analog/exp_a32_inl_from_sine_sweep_length.py index 416a6a2..1965db2 100644 --- a/python/src/adctoolbox/examples/04_debug_analog/exp_a32_inl_from_sine_sweep_length.py +++ b/python/src/adctoolbox/examples/04_debug_analog/exp_a32_inl_from_sine_sweep_length.py @@ -57,7 +57,7 @@ fig.suptitle(f'INL/DNL Sweep: Record Length Comparison (Fs={fs/1e6:.0f} MHz, Fin={fin_target/1e6:.0f} MHz)', fontsize=14, fontweight='bold') plt.tight_layout(rect=[0, 0, 1, 0.96]) -fig_path = output_dir / 'exp_a33_compute_inl_sweep_length.png' +fig_path = output_dir / 'exp_a32_inl_from_sine_sweep_length.png' fig.savefig(fig_path, dpi=150) print(f"\n[Save fig] -> [{fig_path}]") plt.close(fig) diff --git a/python/tests/unit/aout/test_inl_from_ramp.py b/python/tests/unit/aout/test_inl_from_ramp.py index 5f618f3..698a71e 100644 --- a/python/tests/unit/aout/test_inl_from_ramp.py +++ b/python/tests/unit/aout/test_inl_from_ramp.py @@ -170,6 +170,11 @@ def test_analyze_inl_from_ramp_plots_with_existing_dnl_inl_style(): assert len(fig.axes) == 2 assert fig.axes[0].get_ylabel() == "DNL (LSB)" assert fig.axes[1].get_ylabel() == "INL (LSB)" + assert fig.axes[0].get_xlabel() == "Code (2^4 LSB)" + assert fig.axes[1].get_xlabel() == "Code (2^4 LSB)" + assert fig.axes[0].get_xlim() == pytest.approx((0, 1)) + assert fig.axes[1].get_xlim() == pytest.approx((0, 1)) + assert fig.axes[0].get_xticks().tolist() == pytest.approx([0, 0.25, 0.5, 0.75, 1]) assert len(fig.axes[0].lines) >= 1 assert len(fig.axes[1].lines) >= 1 plt.close(fig)