Effacer les filtres
Effacer les filtres

Save graphical objects in .mat file for later use

21 vues (au cours des 30 derniers jours)
Frank
Frank le 18 Juil 2024 à 20:02
Commenté : Voss le 19 Juil 2024 à 16:55
I have been writing matlab apps that visualize field experimental data involving movements of instrumented people and physical objects, tracking of released vapor clouds, data from referee instrumentation, and data from cfd simulations. The apps typically involve time sequenced and synchronized plotting of points and lines in uiaxes, contourf plotting of vapor concentrations, synchronized time lapsed photos or sometimes videos frame by frame. They typically wind up having between 5 and 10 axes containg plots or images which are updated with data synchronized in time on a second by second basis for a few thousand seconds.
I often need to present the visualizations to groups of people and for that I need for the app to run as quickly as it can to maintain their attention and still present the important details. I try to minimize numerical calculations in the app by pre-processing and synchronizing all the data and imagery beforehand so that the app largely involves just managing display of the graphical objects. I found that even simple graphical displays of the data (such as calls to scatter, plot, patch, contourf, etc), which I do for a few dozen sets of data every second for the thousands of seconds covered, progressively slows the real-time display as more and more data sets are involved, even with generous application of drawnows.
I have been trying to generate the displays as arrays of graphical objects and then sequence the display by adjusting object properties like visibility, alpha, etc instead of calling the scatter, plot, patch, etc functions. That allows me to control the speed of the display much better, but generating the graphical object arrays seems to be generating a delay when the app is doing it. Sorry for the long-winded description, but my question is fairly simple I think.
Instead of calling scatter at each second for all the different data streams i have been doing something like this example (the x and y here are just nominal examples of a dataset):
x = (1:50);
y = x.^1.5;
i = (1:50);
ax = axes;
xlim(ax,[0 50]);
ylim(ax,[0 360]);
hold(ax,"on");
H = arrayfun(@(i) scatter(ax,x(i),y(i),"filled","black","Visible","off"),i);
[Then I control which points are displayed when by something like the following]
for j=1:50
H(j).Visible = "on";
pause(0.05);
end
I can make points appear as a sequence of points (or other objects), or appear as a single point moving by toggling the visibility properties or alphas if needed.
Finally my question. The multiple arrayfun calls for arrays of a few thousands of elements seem to take a bit of time in the real time running of the app, but after they are done things are very fast. I think I would like to preprocess the graphical objects (eg. the H above) and then store the graphical objects in a .mat file and simply load them when the app starts up. I have been able to save them (eg H above) into a .mat file and then load them back in to the workspace, but then how do I add them to the axes that I want to add them to? For example if I try
saveobj('H.mat','H');
Then delete H by hand with a right click (for some reason delete(H) doesn't work at the moment), create new axes as above, how do I add the just-loaded H to the newly created axes?

Réponse acceptée

Voss
Voss le 18 Juil 2024 à 21:01
You can use copyobj to copy an existing graphical object (e.g., scatter plot) to another parent (e.g., axes).
Here's an example of creating, saving to mat, deleting, and restoring a scatter plot:
f1 = figure();
H = scatter(1:10,1:10);
save('H.mat','H');
delete(f1)
f2 = figure();
ax = gca();
S = load('H.mat');
copyobj(S.H,ax)
Another option: rather than creating 50 scatter objects and making them visible one-by-one, you can create one scatter object (or one line object), and set its XData and YData incrementally. Example:
figure()
x = 1:50;
y = x.^1.5;
ax = axes();
xlim(ax,[0 50]);
ylim(ax,[0 360]);
H = scatter(ax,[],[],"filled","black");
for j=1:50
H.XData = x(1:j);
H.YData = y(1:j);
drawnow()
end
Or you could use an animatedline object.
Reducing the number of graphics objects generally reduces the time it takes to render them.
  2 commentaires
Frank
Frank le 19 Juil 2024 à 16:51
Déplacé(e) : Voss le 19 Juil 2024 à 16:54
Thanks. That does what I wanted (at least what I thought I wanted). I am already using animated lines for data I plot in simple x,y plots. I thought I needed this for the plots of the positions moving as a function of time in an x-y domain where I need to disappear the last positions. I had previously tried the alpha fading of recent points to show movement but this audience does not seem to care for that. I use the latter in smaller animations I do for the physics classes I teach.
Voss
Voss le 19 Juil 2024 à 16:55
You're welcome!

Connectez-vous pour commenter.

Plus de réponses (0)

Produits


Version

R2024a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by