This script is an abstraction from a script intended to plot errors in guiding a small telescope that is tracking a guide star. The data loosely imitate the kind of data one might get from the program PHD Guiding. The script should plot the data using slider control of dynamic starting points of moving windows on segments of data lists. The data are organized as lists of lists, e.g. {{t, dx}, ...}
. Each sublist has two elements: (1) time, measured in seconds, and (2) tracking error measured in pixels on x or y coordinates on the screen of a guide camera. The starting time of a window is chosen with the slider. The length of the segment in the window is fixed.
The script draws a panel with a slider and a plot. Each small movement of the slider should redraw the plot, giving a new six second window on a segment of the data, each successive window beginning one second later. The length of this imaginary guiding session and of each of the two lists, dxList
and dyList
, is 20. Hence, with windows of arbitrary length six, moving the slider from beginning to end should plot 15 windows on the data, each one replacing the previous.
A very similar script using Dynamic[]
rather than Manipulate[]
works correctly and smoothly, but Manipulate
makes a better looking plot with less code, so I would prefer to use it. The problem is that in this script using Manipulate
, moving the slider draws only the first and the last window. It acts more like a setter than a slider. I would like to know where I have gone wrong and how to make the slider operate smoothly to plot all 17 windows.
Clear[dxList, dyList, window];
window = 6; (* arbitrary short segment length *)
(* Hypothetical list of error corrections dx by time t on x axis while guiding. {{t, dx}, ...} *)
dxList = {{1, 1}, {2, 2}, {3, -1}, {4, -1.5}, {5, 0}, { 6, -.5}, {7, .5},
{8, 1.5}, {9, 1}, {10, -.5}, {11, 1}, {12, 2}, {13, -1}, {14, -2},
{15, 0}, {16, -.5}, {17, .5}, {18, 1.5}, {19, 1}, {20, -.5}};
(* Hypothetical list of error corrections dy by time on y axis while
guiding. {{t, dy}, ...} *)
(* Make list similar to dxList with random elements. *)
dyList = {#[[1]], -#[[2]] + Random[Real, 1]} & /@ dxList;
(* select[] gets a window of data from dxList or dyList starting at
time t and ending at t + segLen. *)
select[t_, window_, list_] :=
Cases[If[ (#[[1]] >= t) && (#[[1]] < (t + window)), #] & /@ list, Except[Null]];
(* Check to see how select[] is working. *)
Print["Selected segment of dxList from record 5 = ", select[5, window, xList]]
Print["Selected segment of dyList from record 5 = ", select[5, window, yList]]
Manipulate[ (* The Slider variable is "start". *)
ListPlot[ (* Plots two lists, dxList, dyList. *)
{select[start, window, dxList], select[start, window, dyList]},
Joined -> True,
PlotLabel -> Style["Telescope guiding errors, dx (Blue) dy (Red)",
FontSize -> 8],
PlotStyle -> {{Blue}, {Red}},
Background -> White,
AxesLabel -> {"Time", "Pixels"}
],
{start, {1, Length[dxList] - window + 1, 1}, Slider}
]