Selective update of waves displayed in graphs

Hi,

I'm displaying large waves (> 10e5 points, up to 8 of them) in a graph. These waves hold scaled data from hardware.

Now everytime I update one of these waves I'm only updating the rows with new data to save time instead of rewriting the whole wave.
Is there a way to tell Igor which parts of the wave changed so that only these parts need to be redrawn?

I'm already manually adjusting the axis ranges only every 25th wave update to save time.
Do you need to look at the plot "live"? I'm wondering (and this could be a ridiculous suggestion), if the graph window is hidden, maybe you could save a picture of it to the gallery for viewing later. I used the trick of saving a picture when working with large waves previously. What I don't know is if hiding the window makes this possible, or if this would not even be of any use.
You could keep a copy of the data and display only the copy in the graph. You then move new data to the copy only when you are ready to update the graph.

A.G.
WaveMetrics, Inc.
Igor wrote:
You could keep a copy of the data and display only the copy in the graph. You then move new data to the copy only when you are ready to update the graph.

A.G.
WaveMetrics, Inc.

this is also what i want to say..:)
thomas_braun wrote:
Hi,

I'm displaying large waves (> 10e5 points, up to 8 of them) in a graph. These waves hold scaled data from hardware.

Now everytime I update one of these waves I'm only updating the rows with new data to save time instead of rewriting the whole wave.
Is there a way to tell Igor which parts of the wave changed so that only these parts need to be redrawn?

I'm already manually adjusting the axis ranges only every 25th wave update to save time.


I don't completely understand where/what the hold-up is as I don't completely understand your situation, but maybe splitting the data wave into smaller chunks will work. Then appending all chunks to the graph and updating only the respective chunk/s over which the change has occurred. I don't know how easy that would be.

Also, maybe the "raw" data is not visually needed to be displayed in its entirety, so that it can be decimated by some factor satisfying the condition that the eye cannot distinguish the difference or the difference may be minor.

best,
_sk
Thanks for all your answers.

sjr51 wrote:
Do you need to look at the plot "live"? ...


Yes I view the data live during data acquisition.

Igor wrote:
You could keep a copy of the data and display only the copy in the graph. You then move new data to the copy only when you are ready to update the graph.


There is no good point for when I'm ready as I want to view it live.

_sk wrote:


I don't completely understand where/what the hold-up is as I don't completely understand your situation, but maybe splitting the data wave into smaller chunks will work. Then appending all chunks to the graph and updating only the respective chunk/s over which the change has occurred. I don't know how easy that would be.



This sounds like an interesting idea. I'll try that.

_sk wrote:


Also, maybe the "raw" data is not visually needed to be displayed in its entirety, so that it can be decimated by some factor satisfying the condition that the eye cannot distinguish the difference or the difference may be minor.



We thought about that too, but could not come up with a general and reliable decimation approach.
_sk wrote:

I don't completely understand where/what the hold-up is as I don't completely understand your situation, but maybe splitting the data wave into smaller chunks will work. Then appending all chunks to the graph and updating only the respective chunk/s over which the change has occurred. I don't know how easy that would be.


I've now tried that using

Function DoTest()

    variable start

    Make/O/n=1e6 data = p
    Make/O/n=1e4 chunk = 0.5 * p

    Display/K=1 data, chunk
    string graph = S_name

    SetAxis left 0,999999
    SetAxis bottom 0,999999

    DoUpdate/W=$graph

    start = StopMSTimer(-2)
    data[0] += 0
    DoUpdate/W=$graph
    printf "%g s\r", (StopMsTimer(-2) - start)/1e6

    start = StopMSTimer(-2)
    chunk[0] += 0
    DoUpdate/W=$graph
    printf "%g s\r", (StopMsTimer(-2) - start)/1e6
End


This creates a graph with two traces in it. One large wave and a smaller one.
Then I update each of the waves and measure the time it takes for the update.

And I get

•dotest() 0.0290689 s 0.0360801 s

which means it does not matter which wave I change, Igor needs the same amount of time.
Whenever you change a wave displayed in a graph, the entire graph is re-drawn. You could possibly imagine the difficulty of know what needs to be redrawn with the general case of an XY trace that can cross itself or any other trace at any arbitrary place.

There is one exception: since a graph is actually a bitmap, and re-drawing a graph from the bitmap is quite fast, you can designate a trace as "live" mode. Then the graph's bitmap is drawn to include everything but the live-mode traces, and if a live-mode trace's data changes, the graph is re-drawn by drawing the bitmap to the graph's window followed by drawing the live-mode traces directly to the window. It is the step of first drawing the bitmap of the entire graph that accounts for the restrictions on live-mode traces.

I'm not sure that live mode really helps your situation, though.

John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
johnweeks wrote:
Whenever you change a wave displayed in a graph, the entire graph is re-drawn. You could possibly imagine the difficulty of know what needs to be redrawn with the general case of an XY trace that can cross itself or any other trace at any arbitrary place.


Yeep that is difficult. But a lot of things are difficult yet implemented in Igor ;)

johnweeks wrote:

There is one exception: since a graph is actually a bitmap, and re-drawing a graph from the bitmap is quite fast, you can designate a trace as "live" mode. Then the graph's bitmap is drawn to include everything but the live-mode traces, and if a live-mode trace's data changes, the graph is re-drawn by drawing the bitmap to the graph's window followed by drawing the live-mode traces directly to the window. It is the step of first drawing the bitmap of the entire graph that accounts for the restrictions on live-mode traces.

I'm not sure that live mode really helps your situation, though.


I've tried that and it did not speedup that in my case.
Just out of curiosity, if you display a single acquisition wave in the Data Browser plot pane, does that refresh fast enough for you?

While it would probably be incredibly annoying to get this to look right, you might be able to plot your data as multiple subwindows along the horizontal direction, each displaying a separate wave that is a subset of the data. Redrawing a single subwindow should then be faster than redrawing everything, and I think that only the subwindow with changed data would need to be redrawn.
... and another proposal that may be somewhat less annoying is to try displaying the data in Gizmo. It is fairly straightforward to lock the rotation and choose the proper orientation etc.

Igor wrote:
... and another proposal that may be somewhat less annoying is to try displaying the data in Gizmo. It is fairly straightforward to lock the rotation and choose the proper orientation etc.


What are the advantages (i.e. opengl drawing at 60fps) of using the gizmo? Could you explain the advantages?

best,
_sk
The idea with multiple windows is good. I'll need to think about how I can use that.

Regarding Gizmo I've tried to use it for plain 1D waves before but failed last time I tried. Also the documentation in 3D graphics states "1D waves can not be used for 3D plots. " and I did not dig deeper at that point. So an example would be helpful.
_sk wrote:

What are the advantages (i.e. opengl drawing at 60fps) of using the gizmo? Could you explain the advantages?
_sk


Regular Graph windows display traces subject to a number of constraints that are absent from OpenGL drawing. Graphics hardware is more efficient at accelerating the drawing data that resides in graphics memory as opposed to handing a bunch of OS calls MoveTo() LineTo(), etc. OS calls on both platforms are having trouble with efficiently rendering thick lines on high resolution monitors. OpenGL does not care about this. A unit-width line will be thinner than it would appear in a graph but it would not take two weeks to render the trace. The higher efficiency is more pronounced in rendering images where Gizmo uses optimized textures while Graph windows map pixels to rectangles.
thomas_braun wrote:
The idea with multiple windows is good. I'll need to think about how I can use that.

Regarding Gizmo I've tried to use it for plain 1D waves before but failed last time I tried. Also the documentation in 3D graphics states "1D waves can not be used for 3D plots. " and I did not dig deeper at that point. So an example would be helpful.


The documentation is correct but you seem to focus on the wrong part. You do need a triplet wave to display a path in Gizmo. You can set the z column to zero, insert your data into the y column and keep the x in the acquisition units. You then display the path, rotate the graph so that you view it from the top and lock the rotation. Also make sure to start by allocating a very large triplet, fill it x and z as described above and set the y values to NaN. Then during your acquisition update the y values as you go.
Igor wrote:
Just out of curiosity, if you display a single acquisition wave in the Data Browser plot pane, does that refresh fast enough for you?


I can't really judge that as I can not measure the time it takes nor can I display mutiple waves at once (the case where the slowdown is measurable).

I'll give Gizmo a shot.
Igor wrote:
Just out of curiosity, if you display a single acquisition wave in the Data Browser plot pane, does that refresh fast enough for you?


I can't really judge that as I can not measure the time it takes nor can I display mutiple waves at once (the case where the slowdown is measurable by just looking at it).

I'll give Gizmo a shot.