我有一个MATLAB GUI,它调用外部函数来绘制图(make_ethogram_plot
)。
这个想法是让一个外部数字不断更新图中的输出值。每次数据更新时,它都应重新绘制值,它以~10 Hz更新。我选择了gramm
(https://github.com/piermorel/gramm/tree/master/%40gramm),因为制作光栅图非常容易。
这是被调用的函数。我有问题
1)使其仅在具有特定名称的父图中更新,而不是在GUI中绘图(这是活动图)。
2)让它不崩溃。它将打开许多数字或以10 Hz打开或关闭相同的数字直到崩溃。
在此配置中,它会出错,因为它在第一个绘图后没有找到g
。制作g
,f
和p1
全局变量会使其崩溃(每次调用时都会打开)
function make_ethogram_plot(datastructure)
% if the figure doesn't exists create it
if(isempty(findobj(0, 'Name', 'My_gramm_ethogram')))
f=figure('Name', 'My_gramm_ethogram');
p1 = uipanel('Parent',f,'BackgroundColor',[1 1 1],'BorderType','none');
g = gramm('x', datastructure.final_data.frameID, 'color', categorical(datastructure.final_data.behavior));
g.geom_raster();
g.set_parent(p1);
g.draw()
else
% defining f,p1, g here (or having them global) works but crashes
% due to refresh rate
g.update()
end
end
答案 0 :(得分:1)
我写了这段代码试图复制你的问题:
function animate_random_data
N = 10000;
data = [cumsum(rand(N,1)),randn(N,1)];
for ii=0:1000
% Plot the data
make_ethogram_plot(data);
drawnow
% Compute new data
data(:,1) = cumsum(rand(N,1));
data(:,2) = randn(N,1);
end
function make_ethogram_plot(data)
fig = findobj(0, 'Name', 'My_gramm_ethogram');
if(isempty(fig))
% If the figure doesn't exists create it
fig = figure('Name', 'My_gramm_ethogram');
ax = axes(fig);
plot(ax,data(:,1),data(:,2));
drawnow
set(ax,'xlimmode','manual','ylimmode','manual');
else
% If it does, update it
line = findobj(fig,'type','line');
set(line,'xdata',data(:,1));
set(line,'ydata',data(:,2));
end
在这里,我遵循了寻找命名图形窗口的概念,如果它不存在则创建一个。但是,如果确实存在,我只需替换已存在的行的XData
和YData
属性。这是动画图形的最快方式,比删除现有绘图和创建新绘图要快得多。绘图后,我使用drawnow
更新显示。我将XLimMode
和YLimMode
设置为manual
,以防止重新计算轴限制并随后重新绘制轴。
该功能花了17秒来绘制所有1000帧,这意味着它每秒绘制约60帧。它不会(也不应该)使MATLAB崩溃。
您可以使用drawnow limitrate
将显示速率限制为20帧/秒。如果帧太快,它将跳过更新显示。
我不知道gramm/update
方法做了什么,这个类太复杂了,无法快速查看发生了什么,但我敢说它会删除轴并从头开始创建一个新的情节。这不应该导致MATLAB崩溃,它可能值得submit a bug report。但是,您可能希望按照我上面演示的方法更有效地更新图形。
请注意,此方法可用于更新绘图中的任何图形元素。例如,我使用此方法为图像设置动画。