Conversation
|
Got basic timeseries with linestack working. I've also got some code snippets for interpolating to display heatmap with non-uniformly sampled timeseries data. I should be able to have this fully working with time series very soon :D Kooha-2025-12-27-03-50-45.mp4 |
|
Got heatmap to display timeseries working. It should also work with non-uniformly sampled data by interpolating, need to test. Also need to implementing switching between heatmap and line representations, need to delete the graphic when switching. Kooha-2025-12-27-17-47-16.mp4 |
|
So timeseries can be represented with arrays of one of the following shapes (let's ignore x-axis values for now). If we have: l: number of timeseries We can have the following shapes: Extended to n-dimensional arrays (for example, trajectories projected onto principal components?). If each non-timeseries dim is I don't think we can auto-detect if
Scatters can be similar to some cases of nd-lines 🤔 , but x values would be directly specified and the current index is parametric (example with time indicating position in a low dim space). This would actually be true for lines as well if representing trajectories. So for nd-line maybe we have two versions, parametric (y and z are not functions of x, but x, y, z are a function of some other dim) and non-parametric (simple timeseries lines where y and z are functions of x). |
|
I made a more generalist
where: It can map arrays of these dims to a line, line collection, line stack, scatter, or list of scatters (similar to multi-line). I think this is a much more elegant way to deal with things, and Example if we have data that is I think we can also use this for heatmaps and interpolation. Use the reference units to determine a uniform x-range for the current display window, and we can interpolate using EDIT: I think that the |
|
For positions graphics, I should actually do |
|
Some more ideas: Allow any 2-3 dims to be used as the graphic dimensions and specify the slider dims. This would also allow using named dims (such as those used in xarray). We interpret the given order of the EDIT: A limitation of the above is that a user can't collapse multiple "graphic/display dimensions" into "final graphic/display dimensions" if they're hard-coded this like. So something like: An example for images would be collapsing |
|
We can use I was thinking of what's the best way to show a scatter for each keypoint, and I think I should make a |
|
ok I think stuff is working ndpositions-2026-01-29_22.55.54.mp4 |
|
I think I need to make a |
|
A set of imgui UIs that allow controlling some aspects of the "nd graphics" could be useful, such as:
|
Stuff I should finish before implementing the orchestrator:
Things that make me "uncomfortable" that I need to settle:dim shapesDim shape for nd-positions is
Do we just document this well, that the When using nd-positions data in conjunction with nd-image data, we'd have something like this: Where The |
|
Working on "implement mapping from a slider reference index with units (such as time) to array index.", which requires proper implementation of |
|
Window funcs working for ndp_windows-2026-02-01_03.39.52.mp4 |
|
The videos all look really cool! I like that you can arbitrarily change the window size I like the switching between LineStack and heatmap too Some of the names are a bit long/weird; I would maybe consider making the property setters that users would interact with shorter/simpler Other things that stand out to me:
|
* remove isolated_buffer * remove isolated_buffer from mixin * basics works for positions data * replaceable buffers for all positions related features * image data buffer can change * resizeable buffers for volume * black * buffer resize condition checked only if new value is an array * gc for buffer managers * uniform colors WIP * switching color modes works! * typo * balck * update tests for color_mode * update examples * backend tests passing * default for all uniforms is True * update examples * forgot * update test * example tests passing * dereferencing test and fixes * simplify texture array tests a bit * image replace buffer tests pass yay * forgot a file * comments, check image graphic * add image reshaping example * add buffer replace imgui thing for manual testing * black * dont call wgpu_obj.destroy(), seems to work and clear VRAM with normal dereferencing * slower changes * update * update example * fixes and tweaks for test * remove unecessary stuff * update * docstrings * fix example * update example * update example * update docs
|
Some thoughts: Need to have a max limit beyond which window funcs are ignored. Now with OOC we can view timeseries that is tens of GBs+ in size, but we wouldn't want to put the |
I think that if a |
|
ok next I'm going to an "auto dynamic display_window" which sets the I think the way to do this is:
Keep manually settable |
|
Here's an example of how to the OOC timeseries with some toy data: n = 100
p = 10_000_000
xs = np.linspace(0, 100_000 * np.pi, p, dtype=np.float32)# + np.random.normal(0, 0.2, size=p)
def xs_mapping(x) -> int:
"""maps world space x position -> array index"""
return int((x * 100) // np.pi)
xs_mapping(xs[132154])
data = np.zeros((n, p, 2), dtype=np.float32)
for i in range(n):
data[i] = np.column_stack([xs, np.sin(xs * 5) + 0 + np.random.normal(scale=0.5, size=p)])
ndp = NDPositions(data, graphic=fpl.LineStack, display_window=1000, multi=True)
fig = fpl.Figure()
fig[0, 0].add_graphic(ndp.graphic)
fig.show(maintain_aspect=False)
xrange = (0, 10)
def update_view():
xmin, ymin, xmax, ymax = fig[0, 0].frame.rect
yavg = (ymax - ymin) / 2
xrange_world = [fig[0, 0].map_screen_to_world((x, y))[0] for x, y in [(xmin + 1, yavg), (xmax - 1, yavg)]]
global xrange
if xrange_world == xrange:
return
xrange = xrange_world
x0, x1 = xs_mapping(xrange[0]), xs_mapping(xrange[1])
disp_window = x1 - x0
ndp.display_window = disp_window
ndp.indices = (int(np.mean([x0, x1])),)
fig.add_animations(update_view)I think we can have a The position of the linear selector and index should be independent of the currently rendered portion of the timeseries data. So we can have an additional property, such as In the orchestrator we should hide these details from the user, perhaps by separating arbitrary nd positions from timeseries representation which set ``display_window="auto-x"` internally, as well as add the update func as an animation function. |
|
I can make a subclass of ndpositions specific to timeseries data which also allows specifying xs and ys separately. It should also allow specifying arrays of shape [s1,... sn, n, p, 1 | 2] where p is the size of the ys, n is the number of lines to be stacked. The processor will then slice xs and ys (or the array of shape shown above) separately and then column_stack before passing it off to the super class to do the rest (window func etc). Dask seems like it's too slow or uses too much ram for doing this kind of lazy slicing and stacking. |
|
Might be useful to have a non-isolated buffer here so |
|
Next stuff to do: Pull in ND Image branch! Think about and implement mapping of input data to other graphical buffers, like colors or sizes, in NDProcessor. Maybe return a dict where the keys define the features to set and values define new values for the feature? These could map to colors, markers, sizes, etc. Similarly, allow using an NDProcessor method to set tooltips. NDProcessor can have an optional method that spits out tooltip info for a displayed data point index. |
|
Idea for dataframes, pass in a dataframe and a list of 2-tuples or 3-tuples indicating columns for (x, y, z) vals. Allow passing the names of other columns that are used to map to other graphic features (colors, sizes, markers, etc.) or tooltips. Kinda like seaborn. This way we don't need a specific NDProcessor for deeplabcut-style results. |

it begins 😄
implements #951