0
votes

I'd like to improve the efficiency of my GUI in app designer, even if it involves frontloading figure generation once so as to save time in subsequent views/updates.

I'm trying to update a UIAxes which includes 4 patch() handles, and approximately 10 plot3() handles referencing approximately 30 lines. The goal is to generate the figure, and then have the ability to update the location of all of the data over 120 different timepoints. ("Play" through the results)

The problem is that it takes approximately 1.5seconds to update the figure once. Updating the patch() handles is approximately an order of magnitude faster than the plot3() handles. While my code doesn't need to run instantly, I was hoping it might update much faster (< 0.5 seconds per timepoint).

I'm using the following syntax to update (as an example) one of my plot3 handles, which includes 3 distinct line objects (thus the cell referencing of {'XData'}):

set(p1.foo1,{'XData'},num2cell([foo1.fem.nds(:,1,1) foo1.tib.nds(:,1,1)],2)); 
set(p1.foo1,{'YData'},num2cell([foo1.fem.nds(:,2,1) foo1.tib.nds(:,2,1)],2)); 
set(p1.foo1,{'ZData'},num2cell([foo1.fem.nds(:,3,1) foo1.tib.nds(:,3,1)],2));

This takes approximately 0.3 seconds to run, and is only 1 of 5 plot3 handles. I've also tried running the set() command inside a loop to avoid the num2cell call as I assumed it was slower. Unfortunately that slowed things down even more.

So I'm wondering if anyone is familiar with another solution to either: 1) Updating the plot data in a faster more efficient way than I've described here. 2) Frontloading all of these figure assemblies (120 time points, 120 figures), and maybe just placing them into my GUI one at a time as I play through my time series by adding and removing each individual figure from my UIAxes as I cycle through the 120 points. I realize this will take more memory, but I'd rather more memory than more time.

I hope this was clear, any suggestions would be appreciated.

1
You have a } in your code that is not matched up. Please fix it so we know what you’re doing. The XData property should contain a matrix, I don’t understand why you need num2cell. Also it looks like you’re first concatenating two vectors and then splitting them into a cell array. Why not make a cell array of these vectors right away? - Cris Luengo
Apologies -- fixed the syntax. If p1.foo1 is a handle which contains three separate lines the XData is represented as cells, which is why I handle it thus. If I wanted to pass it an array I'd have to loop through and do something like set(p1.foo1(i),'XData',[foo1.fem.nds(i,1,1) foo1.tib.nds(i,1,1)]) and loop through the first index as well.The data is used in matrix form throughout the code, so I only create a cell array to input it into the set function. It's possible I'm misunderstanding but I'm not sure how to make "a cell array .. right away". Please elaborate @CrisLuengo. - DonaldH
You have to keep the data you plan to pass to the plots in a numeric matrix format. It will be a lot faster to directly pass a double array to the plot than having to extract a double array from a cell array first. - Hoki
I guess I'm still not clear on what is going on in your code. It would help if you made a minimal reproducible example. That would also give us something to test improvements on. Back in the old days it was much faster to set all properties in one call to set, rather than 3 separate ones, not sure this is still the case. Other than that, it likely depends on the complexity of your plot. I can't imagine that updating a 3D line would be expensive. - Cris Luengo

1 Answers

1
votes

It seems as if you're asking for general advice. If you'd like more specific answers, try creating a minimum reproducible example.

Otherwise, some general tips:

  1. Don't store data in cells. The set() method for line objects can be used with standard numeric arrays: primative line documentation
  2. Struct in MATLAB has some overhead associated with it. It looks like you have multiple nested structs holding numeric arrays. Retrieving this data from that struct might be slow. You can always use tic/toc to see how slow it is. But in general, avoid structs when possible and store the numeric data as its own variable. For more info, see some advice on arrays of structs vs. structs of arrays.