Skip to content

Commit 7e0f989

Browse files
committed
Properly autoscale plots
Fixes #447, #446
1 parent 9bf0992 commit 7e0f989

File tree

7 files changed

+223
-179
lines changed

7 files changed

+223
-179
lines changed

src/sdr/_simulation/_impairment.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,9 @@ def clock_error(
436436
sdr.plot.dtft(x, sample_rate=sample_rate, label="No clock error"); \
437437
sdr.plot.dtft(y, sample_rate=sample_rate, label="Added Tx clock error"); \
438438
sdr.plot.dtft(z, sample_rate=sample_rate, label="Removed Tx clock error"); \
439-
plt.axvline(freq / 1e3, color="k", linestyle="--"); \
440-
plt.axvline((freq + freq_offset) / 1e3, color="k", linestyle="--"); \
441-
plt.xlim(80, 140);
439+
plt.axvline(freq, color="k", linestyle="--"); \
440+
plt.axvline(freq + freq_offset, color="k", linestyle="--"); \
441+
plt.xlim(80e3, 140e3);
442442
443443
This example demonstrates the effect of clock error on a complex baseband signal. The signal has a carrier
444444
frequency of 1 MHz and sample rate of 2 MS/s. A frequency offset of 100 kHz is desired, corresponding to a
@@ -476,9 +476,9 @@ def clock_error(
476476
sdr.plot.dtft(x, sample_rate=sample_rate, label="No clock error"); \
477477
sdr.plot.dtft(y, sample_rate=sample_rate, label="Added Tx clock error"); \
478478
sdr.plot.dtft(z, sample_rate=sample_rate, label="Removed Tx clock error"); \
479-
plt.axvline(0 / 1e3, color="k", linestyle="--"); \
480-
plt.axvline(freq_offset / 1e3, color="k", linestyle="--"); \
481-
plt.xlim(-20, 120);
479+
plt.axvline(0, color="k", linestyle="--"); \
480+
plt.axvline(freq_offset, color="k", linestyle="--"); \
481+
plt.xlim(-20e3, 120e3);
482482
483483
Group:
484484
simulation-impairments

src/sdr/plot/_filter.py

Lines changed: 9 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
from .._conversion import db
1414
from .._filter import FIR, IIR
1515
from .._helper import export, verify_arraylike, verify_bool, verify_isinstance, verify_literal, verify_scalar
16-
from ._helper import integer_x_axis, min_ylim, standard_plot, verify_sample_rate
16+
from ._helper import freq_x_axis, min_ylim, standard_plot, time_x_axis, time_y_axis, verify_sample_rate
1717
from ._rc_params import RC_PARAMS
18-
from ._units import freq_units, time_units
1918

2019

2120
def _convert_to_taps(
@@ -117,9 +116,8 @@ def impulse_response(
117116
h, zi = scipy.signal.lfilter(b, a, d, zi=zi)
118117
t = np.arange(h.size) + offset
119118

120-
integer_x_axis(ax)
121119
standard_plot(t, h, ax=ax, type=type, y_axis="complex", **kwargs)
122-
ax.set_xlabel("Sample, $n$")
120+
time_x_axis(ax, False)
123121
ax.set_ylabel("Amplitude")
124122
ax.set_title("Impulse response, $h[n]$")
125123

@@ -200,9 +198,8 @@ def step_response(
200198
s, zi = scipy.signal.lfilter(b, a, u, zi=zi)
201199
t = np.arange(s.size)
202200

203-
integer_x_axis(ax)
204201
standard_plot(t, s, ax=ax, type=type, y_axis="complex", **kwargs)
205-
ax.set_xlabel("Sample, $n$")
202+
time_x_axis(ax, False)
206203
ax.set_ylabel("Amplitude")
207204
ax.set_title("Step response, $s[n]$")
208205

@@ -378,10 +375,6 @@ def magnitude_response(
378375
f -= sample_rate / 2
379376
H = np.fft.fftshift(H)
380377

381-
if sample_rate_provided:
382-
units, scalar = freq_units(f)
383-
f *= scalar
384-
385378
if y_axis == "log":
386379
H = db(np.abs(H) ** 2)
387380
else:
@@ -395,17 +388,11 @@ def magnitude_response(
395388
ax.grid(True, which="both")
396389
if "label" in kwargs:
397390
ax.legend()
398-
399-
if sample_rate_provided:
400-
ax.set_xlabel(f"Frequency ({units}), $f$")
401-
else:
402-
ax.set_xlabel("Normalized frequency, $f / f_s$")
403-
391+
freq_x_axis(ax, sample_rate_provided)
404392
if y_axis == "log":
405393
ax.set_ylabel(r"Power (dB), $|H(\omega)|^2$")
406394
else:
407395
ax.set_ylabel(r"Power, $|H(\omega)|^2$")
408-
409396
ax.set_title(r"Magnitude response, $|H(\omega)|^2$")
410397

411398

@@ -505,10 +492,6 @@ def phase_response(
505492
f -= sample_rate / 2
506493
H = np.fft.fftshift(H)
507494

508-
if sample_rate_provided:
509-
units, scalar = freq_units(f)
510-
f *= scalar
511-
512495
if unwrap:
513496
theta = np.rad2deg(np.unwrap(np.angle(H)))
514497
else:
@@ -526,10 +509,7 @@ def phase_response(
526509
ax.grid(True, which="both")
527510
if "label" in kwargs:
528511
ax.legend()
529-
if sample_rate_provided:
530-
ax.set_xlabel(f"Frequency ({units}), $f$")
531-
else:
532-
ax.set_xlabel("Normalized frequency, $f / f_s$")
512+
freq_x_axis(ax, sample_rate_provided)
533513
ax.set_ylabel(r"Phase (deg), $\angle H(\omega)$")
534514
ax.set_title(r"Phase response, $\angle H(\omega)$")
535515

@@ -633,12 +613,6 @@ def phase_delay(
633613
tau_phi = -theta / (2 * np.pi * f)
634614
tau_phi[np.argmin(np.abs(f))] = np.nan # Avoid crazy result when dividing by near zero
635615

636-
if sample_rate_provided:
637-
f_units, scalar = freq_units(f)
638-
f *= scalar
639-
t_units, scalar = time_units(tau_phi)
640-
tau_phi *= scalar
641-
642616
if x_axis == "log":
643617
ax.semilogx(f, tau_phi, **kwargs)
644618
else:
@@ -649,6 +623,8 @@ def phase_delay(
649623
ax.grid(True, which="both")
650624
if "label" in kwargs:
651625
ax.legend()
626+
f_units = freq_x_axis(ax, sample_rate_provided)
627+
t_units = time_y_axis(ax, sample_rate_provided)
652628
if sample_rate_provided:
653629
ax.set_xlabel(f"Frequency ({f_units}), $f$")
654630
ax.set_ylabel(rf"Phase delay ({t_units}), $\tau_{{\phi}}{{\omega}}$")
@@ -751,14 +727,6 @@ def group_delay(
751727
f -= sample_rate / 2
752728
tau_g = np.fft.fftshift(tau_g)
753729

754-
if sample_rate_provided:
755-
f_units, scalar = freq_units(f)
756-
f *= scalar
757-
758-
tau_g /= sample_rate
759-
t_units, scalar = time_units(tau_g)
760-
tau_g *= scalar
761-
762730
if x_axis == "log":
763731
ax.semilogx(f, tau_g, **kwargs)
764732
else:
@@ -769,6 +737,8 @@ def group_delay(
769737
ax.grid(True, which="both")
770738
if "label" in kwargs:
771739
ax.legend()
740+
f_units = freq_x_axis(ax, sample_rate_provided)
741+
t_units = time_y_axis(ax, sample_rate_provided)
772742
if sample_rate_provided:
773743
ax.set_xlabel(f"Frequency ({f_units}), $f$")
774744
ax.set_ylabel(rf"Group delay ({t_units}), $\tau_g(\omega)$")

src/sdr/plot/_freq_domain.py

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@
1212
from typing_extensions import Literal
1313

1414
from .._helper import export, verify_arraylike, verify_bool, verify_isinstance, verify_literal, verify_scalar
15-
from ._helper import integer_x_axis, standard_plot, verify_sample_rate
15+
from ._helper import freq_x_axis, standard_plot, verify_sample_rate
1616
from ._rc_params import RC_PARAMS
17-
from ._units import freq_units
1817

1918

2019
@export
@@ -153,19 +152,9 @@ def dft(
153152
X = np.fft.fftshift(X)
154153
f = np.fft.fftshift(f)
155154

156-
if sample_rate_provided:
157-
units, scalar = freq_units(f)
158-
f *= scalar
159-
160155
standard_plot(f, X, ax=ax, y_axis=y_axis, diff=diff, type=type, **kwargs)
161156

162-
if x_axis == "bin":
163-
integer_x_axis(ax)
164-
ax.set_xlabel("DFT bin index, $k$")
165-
elif sample_rate_provided:
166-
ax.set_xlabel(f"Frequency ({units}), $f$")
167-
else:
168-
ax.set_xlabel("Normalized frequency, $f/f_s$")
157+
freq_x_axis(ax, sample_rate_provided, bins=x_axis == "bin")
169158

170159
if y_axis == "complex":
171160
ax.set_ylabel("Amplitude, $X[k]$")

0 commit comments

Comments
 (0)