06-13-2011 01:23 PM
Hello everyone,
I have an interesting problem for you all. I am trying to update characteristics of a large XY graph (3600 data points for each of 160 different plot lines, all on one graph) by reference and it's going incredibly slowly.
What I have set up is a system where mousing over certain other indicators and buttons will "highlight" certain groups of plots by making the plot lines a thickness of 2 instead of 1. Similarly, clicking other buttons will change plot colors or toggle visibility of certain plots. To implement this I have a subvi that takes a reference to the xy graph and, in a for loop for each active plot, applies the changes I wish to see made. The problem is that this takes over a minute to complete for just one update!! I'm supposed to be plotting new points every second, and mouseovers and button clicks can happen many times in a second, so this is obviously unacceptable.
I noticed that as I'm looping through all 160 plots in the subvi, the XY graph is updating, one plot at a time. My question is: Is there some way to keep the graph from updating until all the changes have been made? Or maybe some way of applying all the changes at one time, instead of using a for loop?
I have discovered that if I simply drag out a HUGE xy graph property node and do everything all at once instead of in a for loop, the changes appear instantly as desired. Is this really what I have to do to achieve the results I want? It is incredibly time consuming and unmaintainable to have a gigantic property node will all stages of the for loop being applied at once.
Help is greatly appreciated!
-Aaron
Solved! Go to Solution.
06-13-2011 02:50 PM
Aaron,
It sounds like you may be unecessarily processing plots that are unchanged by a user action, which could take unneeded processing time.
The best way I can think of to approach that problem, instead of iterating through all 160 plots each time, is this: If the user interacts with a control corresponding to, say, Plot 41, then get a reference to plot 41 (from an array of all plot references), change the properties of that reference, and you're done.
(This is done by setting "Active Plot" property of XY graph class to a value of 41, then passing the "Plot" property to its own property node, where the Plot class properties can be modified). This may be done each time the user interacts with a different plot.
Also, without knowing anything else about your VI, I might suggest simply reducing the amount of information that is condensed into one place on the Front Panel. If you have 160 plots on a single graph, that might be your first problem. I can't imagine the user getting much meaning from a graph that large. Maybe break that 160 apart into relevant sets, and think about displaying each set on a different chart, tab, or window.
06-13-2011 03:16 PM
Yeah, I am already doing essentially that. Let me explain. The 160 plots and 3600 data points is kind of the worst case scenario. In all likely hood there will not be quite so many plots being displayed at one time, but the option is still there, so I would like to prepare for the worst case if I can.
I do selectively apply changes only to parts of the graph that have been affected by the user. And if these changes altered the state of just 1 plot it wouldn't be so much of a problem. But I have a series of 10 buttons, for instance, which toggle whether sets of 16 plots are displayed or not. Those same buttons, if moused over, will "highlight" the 16 plots they relate to. This toggling and visibility changes are only modifying 16 not the whole 160, but the slowness is still very apparent. In the past I have split up the sets of 16 onto 10 different plots, but that presents an whole host of other issues and the resulting code ends up very messy and hard to deal with with 10 duplicates of everything. Not to mention the ability to plot the groups of 16 on the same plot as other groups of 16 is a very useful feature for my application. So, as far as I can tell, I'm stuck with everything all on one plot.
It would be nice if there was some way to just access an array of all 160 colors or line widths, modify it, and then apply it all at once.
I was hoping there was some tricky way to do what I want, but I'm starting to think this is an inherent limitation of the LabVIEW XY graph.
Also, I'm using LabVIEW 8.6.1
Thanks for the help, hopefully you this gives you a better idea of what I'm trying to do.
06-13-2011 03:17 PM
Do you have a file with the dat so that we could plot the data and see if we can come up with something more efficient?
06-13-2011 03:37 PM
To try an simplify the problem I made an example program which illustrates the issue I've been having, for data I've just been generating a bunch of random numbers. This example VI only demonstrates changing line width, but a smiliar problem occurs for changing colors and setting visibility as I mentioned before.
When you run the program it will loop through all the plots and set them to whatever thickness you set, if you tell it to go to the same thickness that they are already set to, it goes much faster. But if you change it to some new value it takes a very long time to complete.
Thanks once again for the help and good luck finding a solution.
06-13-2011 04:04 PM
Two things you can consider:
1) Defer Panel Updates. Set to True before the Loop and False afterwards. Speeds things like this up considerably.
2) No way you can see 3600 points on a graph. With this many plots I would consider decimation of the data to reduce the number of displayed points.
06-14-2011 08:13 AM
Here is how I would attack this problem. Seems to be fast and is flexible.
06-14-2011 08:21 AM - edited 06-14-2011 08:25 AM
@Darin.K wrote:
Two things you can consider:
1) Defer Panel Updates. Set to True before the Loop and False afterwards. Speeds things like this up considerably.
2) No way you can see 3600 points on a graph. With this many plots I would consider decimation of the data to reduce the number of displayed points.
This works amazingly well! In my absolute worst case scenario it takes about 70ms to update all 160 plots for 60 minutes worth of data (3600 points) where as before it took over 240000ms. 70ms is obviously a huge improvement and I thank you very much, this is exactly what I was looking for.
Just as a side note, unfortunately I do have to display up to 3600 points, the end users want to see up to an hours worth of previous data (more even, if possible). Unless you are suggesting I should somehow cut out data, like 4 out of every 5 data points for instance? Part of the problem with cutting out points like that is that there are occasionally spikes in the data that consist of a single point. Cutting out data might remove these which would be a problem. The end users need to be able to spot these spikes when they occur. But perhaps a more complicated decimation that identifies outliers and plots them no matter what to ensure that the spikes remain and only decimate the remaining data? That could get tricky quickly, but doable I suppose.
Thanks for all the help guys, if anyone has any other methods they think might work as well, I would be interested in trying them too to compare, but Darin's solution will work great.
-Aaron
06-14-2011 08:25 AM
@aeastet wrote:
Here is how I would attack this problem. Seems to be fast and is flexible.
Hey Tim, do you think you could save as a LabVIEW 8.6 or earlier version? I would love to see what you did.
Thanks,
-Aaron
06-14-2011 08:49 AM
Here you go