From 06b5081d1f6c4aebd4c7c0bf4225af3420b36ce7 Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Fri, 13 Mar 2026 14:29:44 -0500 Subject: [PATCH 1/5] examples: Speed up voltage_acq_clk_plot_wfm.py and make it handle multiple channels correctly --- .../analog_in/voltage_acq_int_clk_plot_wfm.py | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/examples/analog_in/voltage_acq_int_clk_plot_wfm.py b/examples/analog_in/voltage_acq_int_clk_plot_wfm.py index a87c6fc4..bf59a795 100644 --- a/examples/analog_in/voltage_acq_int_clk_plot_wfm.py +++ b/examples/analog_in/voltage_acq_int_clk_plot_wfm.py @@ -6,22 +6,42 @@ """ import matplotlib.pyplot as plot - import nidaqmx +import numpy as np from nidaqmx.constants import READ_ALL_AVAILABLE, AcquisitionType +from nitypes.time.typing import AnyDateTime +from nitypes.waveform import AnalogWaveform + + +def plot_analog_waveform( + waveform: AnalogWaveform[float], min_start_time: AnyDateTime | None = None +) -> None: + """Plot a single analog waveform.""" + # For multiplexed devices, each channel has a different time offset, based on the AI Convert + # Clock rate. Calculate the time offset for this channel by subtracting the minimum start time. + time_offset = 0.0 + if min_start_time is not None: + time_offset = (waveform.timing.start_time - min_start_time).total_seconds() + duration = waveform.sample_count * waveform.timing.sample_interval.total_seconds() + time_data = np.linspace(time_offset, time_offset + duration, waveform.sample_count) + plot.plot(time_data, waveform.scaled_data, label=waveform.channel_name) + with nidaqmx.Task() as task: task.ai_channels.add_ai_voltage_chan("Dev1/ai0") task.timing.cfg_samp_clk_timing(1000.0, sample_mode=AcquisitionType.FINITE, samps_per_chan=50) - waveform = task.read_waveform(READ_ALL_AVAILABLE) + waveforms = task.read_waveform(READ_ALL_AVAILABLE) + if not isinstance(waveforms, list): + waveforms = [waveforms] - timestamps = list(waveform.timing.get_timestamps(0, waveform.sample_count)) - time_offsets = [(ts - timestamps[0]).total_seconds() for ts in timestamps] - plot.plot(time_offsets, waveform.scaled_data) + min_start_time = min(waveform.timing.start_time for waveform in waveforms) + for waveform in waveforms: + plot_analog_waveform(waveform, min_start_time) plot.xlabel("Seconds") - plot.ylabel(waveform.units) - plot.title(waveform.channel_name) + plot.ylabel(waveforms[0].units) # assume all channels have the same units + plot.title("Waveforms") + plot.legend() plot.grid(True) plot.show() From 7187b23ca7dcf61df46c1ebce06a4ee784861c54 Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Fri, 13 Mar 2026 14:33:14 -0500 Subject: [PATCH 2/5] docs: Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 239b7f5e..e1fa07af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,7 +32,7 @@ All notable changes to this project will be documented in this file. * [Full changelog: 1.4.1...1.5.0](https://github.com/ni/nidaqmx-python/compare/1.4.1...1.5.0) * ### Resolved Issues - * ... + * [936: New example voltage_acq_int_clk_plot_wfm.py does not behave as expected](https://github.com/ni/nidaqmx-python/issues/936) * ### Major Changes * ... From 485f66c2abc1484544ca0e7dedfbd25ab4b7d4e8 Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Fri, 13 Mar 2026 14:57:08 -0500 Subject: [PATCH 3/5] examples: Fix lint errors --- examples/analog_in/voltage_acq_int_clk_plot_wfm.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/analog_in/voltage_acq_int_clk_plot_wfm.py b/examples/analog_in/voltage_acq_int_clk_plot_wfm.py index bf59a795..1c9dc72f 100644 --- a/examples/analog_in/voltage_acq_int_clk_plot_wfm.py +++ b/examples/analog_in/voltage_acq_int_clk_plot_wfm.py @@ -6,12 +6,13 @@ """ import matplotlib.pyplot as plot -import nidaqmx import numpy as np -from nidaqmx.constants import READ_ALL_AVAILABLE, AcquisitionType from nitypes.time.typing import AnyDateTime from nitypes.waveform import AnalogWaveform +import nidaqmx +from nidaqmx.constants import READ_ALL_AVAILABLE, AcquisitionType + def plot_analog_waveform( waveform: AnalogWaveform[float], min_start_time: AnyDateTime | None = None From f43316dd150f26076077491786ace8144612ec5a Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Fri, 13 Mar 2026 15:01:08 -0500 Subject: [PATCH 4/5] examples: Remove type hints from new code because the API does not have enough type hints for them to work --- examples/analog_in/voltage_acq_int_clk_plot_wfm.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/analog_in/voltage_acq_int_clk_plot_wfm.py b/examples/analog_in/voltage_acq_int_clk_plot_wfm.py index 1c9dc72f..23c8e8ed 100644 --- a/examples/analog_in/voltage_acq_int_clk_plot_wfm.py +++ b/examples/analog_in/voltage_acq_int_clk_plot_wfm.py @@ -7,16 +7,12 @@ import matplotlib.pyplot as plot import numpy as np -from nitypes.time.typing import AnyDateTime -from nitypes.waveform import AnalogWaveform import nidaqmx from nidaqmx.constants import READ_ALL_AVAILABLE, AcquisitionType -def plot_analog_waveform( - waveform: AnalogWaveform[float], min_start_time: AnyDateTime | None = None -) -> None: +def plot_analog_waveform(waveform, min_start_time=None): """Plot a single analog waveform.""" # For multiplexed devices, each channel has a different time offset, based on the AI Convert # Clock rate. Calculate the time offset for this channel by subtracting the minimum start time. From 5244f7aba7e8e27611c7316d6f3bf900ce173527 Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Fri, 13 Mar 2026 17:25:56 -0500 Subject: [PATCH 5/5] examples: Exclude X-axis endpoint from time_data --- examples/analog_in/voltage_acq_int_clk_plot_wfm.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/analog_in/voltage_acq_int_clk_plot_wfm.py b/examples/analog_in/voltage_acq_int_clk_plot_wfm.py index 23c8e8ed..8874e628 100644 --- a/examples/analog_in/voltage_acq_int_clk_plot_wfm.py +++ b/examples/analog_in/voltage_acq_int_clk_plot_wfm.py @@ -20,7 +20,9 @@ def plot_analog_waveform(waveform, min_start_time=None): if min_start_time is not None: time_offset = (waveform.timing.start_time - min_start_time).total_seconds() duration = waveform.sample_count * waveform.timing.sample_interval.total_seconds() - time_data = np.linspace(time_offset, time_offset + duration, waveform.sample_count) + time_data = np.linspace( + time_offset, time_offset + duration, waveform.sample_count, endpoint=False + ) plot.plot(time_data, waveform.scaled_data, label=waveform.channel_name)