필터 지우기
필터 지우기

Save graphical objects in .mat file for later use

조회 수: 21 (최근 30일)
Frank
Frank 2024년 7월 18일 20:02
댓글: Voss 2024년 7월 19일 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?

채택된 답변

Voss
Voss 2024년 7월 18일 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
Frank
Frank 2024년 7월 19일 16:51
이동: Voss 2024년 7월 19일 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 2024년 7월 19일 16:55
You're welcome!

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Annotations에 대해 자세히 알아보기

제품


릴리스

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by