Skip to content

Commit

Permalink
Add optional secondary twin x-axis to live plotter
Browse files Browse the repository at this point in the history
  • Loading branch information
tryuan99 committed Jul 22, 2024
1 parent a6c7b94 commit 3536a1b
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 15 deletions.
13 changes: 10 additions & 3 deletions utils/plotter/adc_muxed_data_live_plotter_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ def _parse_adc_data(read_data: str, num_sensors: int) -> tuple[float]:
# The OpenMote prints (sequence number, channel, coarse code, medium
# code, fine code, ADC output for each sensor, RSSI).
adc_output = read_data.split(" ")[5:5 + num_sensors]
return [float(data) for data in adc_output]
adc_output_float = [float(data) for data in adc_output]
for i in range(2, num_sensors):
adc_output_float[i] /= 16384
return adc_output_float
except:
logging.error("Failed to parse ADC data.")
return [0] * num_sensorss
return [0] * num_sensors


def main(argv):
Expand All @@ -34,11 +37,15 @@ def main(argv):
FLAGS.max_duration,
lambda read_data: _parse_adc_data(read_data, FLAGS.num_sensors),
num_traces=FLAGS.num_sensors,
secindices=list(range(2, FLAGS.num_sensors)),
title="ADC data",
xlabel="Time [s]",
ylabel="ADC output [LSB]",
ymin=0,
ymax=512)
ymax=512,
secylabel="Time constant [s]",
secymin=0,
secymax=1)
plotter.run()


Expand Down
63 changes: 54 additions & 9 deletions utils/plotter/live_plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ def __init__(self,
xmax: float,
ymin: float,
ymax: float,
num_traces: int = 1) -> None:
num_traces: int = 1,
secindices: tuple[int] = None,
secylabel: str = None,
secymin: float = None,
secymax: float = None) -> None:
self.num_traces = num_traces
self.xmax = xmax

Expand All @@ -35,15 +39,30 @@ def __init__(self,
self.ax.set_ylabel(ylabel)
self.ax.set_xlim((0, xmax))
self.ax.set_ylim((ymin, ymax))
if secindices is not None:
self.secax = self.ax.twinx()
self.secax.set_ylabel(secylabel)
self.secax.set_ylim((secymin, secymax))

# Initialize the data and the traces. If the live plot is continuous,
# the x-axis is the time in seconds. Otherwise, the x-axis is the
# sample index.
self.x = np.zeros(1)
self.y = np.zeros((1, num_traces))
self.data_lock = Lock()
self.traces = self.ax.plot(self.x, self.y)
self.ax.legend([f"Trace {i + 1}" for i in range(num_traces)])
self.traces = []
for i in range(num_traces):
args = {
"color": f"C{i}",
"marker": "^",
"label": f"Trace {i}",
}
if secindices is None or i not in secindices:
trace, = self.ax.plot(self.x, self.y[:, i], **args)
else:
trace, = self.secax.plot(self.x, self.y[:, i], **args)
self.traces.append(trace)
self.ax.legend(handles=self.traces)

# Create a thread for updating the data.
self.data_thread = Thread(target=self._update_data)
Expand Down Expand Up @@ -121,9 +140,22 @@ def __init__(self,
ylabel: str,
ymin: float,
ymax: float,
num_traces: int = 1) -> None:
super().__init__(title, xlabel, ylabel, max_num_points, ymin, ymax,
num_traces)
num_traces: int = 1,
secindices: tuple[int] = None,
secylabel: str = None,
secymin: float = None,
secymax: float = None) -> None:
super().__init__(title,
xlabel,
ylabel,
max_num_points,
ymin,
ymax,
num_traces=num_traces,
secindices=secindices,
secylabel=secylabel,
secymin=secymin,
secymax=secymax)

def next_data(self) -> tuple[float, float | tuple[float]]:
"""Returns the next data to plot.
Expand All @@ -148,9 +180,22 @@ def __init__(self,
ylabel: str,
ymin: float,
ymax: float,
num_traces: int = 1) -> None:
super().__init__(title, xlabel, ylabel, max_duration, ymin, ymax,
num_traces)
num_traces: int = 1,
secindices: tuple[int] = None,
secylabel: str = None,
secymin: float = None,
secymax: float = None) -> None:
super().__init__(title,
xlabel,
ylabel,
max_duration,
ymin,
ymax,
num_traces=num_traces,
secindices=secindices,
secylabel=secylabel,
secymin=secymin,
secymax=secymax)
self.last_data_time = 0

def next_data(self) -> tuple[float, float | tuple[float]]:
Expand Down
19 changes: 16 additions & 3 deletions utils/plotter/serial_live_plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,22 @@ def __init__(self,
ylabel: str,
ymin: float,
ymax: float,
num_traces: int = 1) -> None:
super().__init__(max_duration, title, xlabel, ylabel, ymin, ymax,
num_traces)
num_traces: int = 1,
secindices: tuple[int] = None,
secylabel: str = None,
secymin: float = None,
secymax: float = None) -> None:
super().__init__(max_duration,
title,
xlabel,
ylabel,
ymin,
ymax,
num_traces=num_traces,
secindices=secindices,
secylabel=secylabel,
secymin=secymin,
secymax=secymax)
self.parse_data = parse_data

# Open the serial port.
Expand Down

0 comments on commit 3536a1b

Please sign in to comment.