-
Notifications
You must be signed in to change notification settings - Fork 10
Open
Description
Hi!
There is https://github.com/LenShustek/grapher , but it's a native Windows app. I'm not really into frontend coding at all, but I threw something together using this AI crap which at least can show a plot using basic Python libs. If you happen to have Python, NumPy and matplotlib installed, you may want to give this a try:
#!/usr/bin/env python3
# .tbin -> .csv:
# ../../src/csvtbin -read SRI_SDS_102715028_4secs
#
# ...then call ./show.py SRI_SDS_102715028_4secs.csv
import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FormatStrFormatter
from matplotlib.widgets import Slider
# -------------------------------
# CSV-like file loader
# -------------------------------
def load_track_file(filename):
with open(filename, "r") as f:
lines = f.readlines()
# Ignore first line (title)
header = lines[1].strip().split(",")
header = [h.strip() for h in header]
data = []
for line in lines[2:]:
parts = [p.strip() for p in line.split(",") if p.strip() != ""]
if len(parts) < 2:
continue
data.append([float(p) for p in parts])
data = np.array(data)
time = data[:, 0]
tracks = data[:, 1:]
track_names = header[1:]
return time, tracks, track_names
# -------------------------------
# Plotting & interaction
# -------------------------------
def plot_tracks(time, tracks, track_names):
updating = False
n_tracks = tracks.shape[1]
fig, axes = plt.subplots(
n_tracks, 1,
sharex=True,
figsize=(10, 2 * n_tracks)
)
if n_tracks == 1:
axes = [axes]
plt.subplots_adjust(bottom=0.18, hspace=0.15)
# Precompute min/max
mins = tracks.min(axis=0)
maxs = tracks.max(axis=0)
scatters = []
for i, ax in enumerate(axes):
sc = ax.scatter(time, tracks[:, i], s=6)
scatters.append(sc)
ax.set_ylabel(
f"{track_names[i]}\n"
f"min={mins[i]:.5f}\n"
f"max={maxs[i]:.5f}",
rotation=0,
labelpad=40,
va="center"
)
ax.set_ylim(mins[i], maxs[i])
ax.grid(True, axis="x", linestyle=":", color="0.7")
axes[-1].set_xlabel("Time (s)")
axes[-1].xaxis.set_major_formatter(FormatStrFormatter('%.6f'))
t_min = time.min()
t_max = time.max()
start = t_min
span = (t_max - t_min) * 0.1
# Status line
status = fig.text(
0.01, 0.01, "",
ha="left", va="bottom", fontsize=9
)
def update_view():
end = start + span
for ax in axes:
ax.set_xlim(start, end)
# Status line at the bottom.
status.set_text(
f"Start: {start:.6f} s | "
f"Span: {span:.6f} s | "
f"Max Time: {t_max:.6f} s"
)
fig.canvas.draw_idle()
# -------------------------------
# Sliders
# -------------------------------
ax_start = plt.axes([0.15, 0.08, 0.7, 0.03])
ax_span = plt.axes([0.15, 0.04, 0.7, 0.03])
start_slider = Slider(
ax_start, "Start",
t_min, t_max,
valinit=start,
valfmt="%.6f"
)
span_slider = Slider(
ax_span, "Span",
(t_max - t_min) * 0.001,
(t_max - t_min),
valinit=span,
valfmt="%.6f"
)
def on_slider_change(val):
nonlocal start, span, updating
if updating:
return
start = start_slider.val
span = span_slider.val
update_view()
start_slider.on_changed(on_slider_change)
span_slider.on_changed(on_slider_change)
# -------------------------------
# Keyboard controls
# -------------------------------
def on_key(event):
nonlocal start, span, updating
mid = start + 0.5 * span
if event.key == "up":
span *= 1.3
start = mid - 0.5 * span
elif event.key == "down":
span *= 0.7
start = mid - 0.5 * span
elif event.key == "left":
start -= 0.3 * span
elif event.key == "right":
start += 0.3 * span
else:
return
span = max(span, (t_max - t_min) * 1e-6)
start = max(t_min, min(start, t_max - span))
updating = True
span_slider.set_val(span)
start_slider.set_val(start)
updating = False
update_view()
fig.canvas.mpl_connect("key_press_event", on_key)
update_view()
plt.show()
# -------------------------------
# Main
# -------------------------------
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python viewer.py <datafile>")
sys.exit(1)
filename = sys.argv[1]
time, tracks, track_names = load_track_file(filename)
plot_tracks(time, tracks, track_names)
So convert a tbin to csv, then call it like ./show.py sometihing.csv. Cursor left/right to move in time, Cursor up/down to zoom in/out.
As this is only a quick hack with questionable quality and origin, feel free to just close this ticket. But I wanted to at at least show a route to an alternative to a hative application.
Metadata
Metadata
Assignees
Labels
No labels