【问题标题】:Update gramm plot matlab crashing更新 gramm plot matlab 崩溃
【发布时间】:2018-04-19 22:43:23
【问题描述】:

我有一个 MATLAB GUI,它调用外部函数来绘制图形 (make_ethogram_plot)。

我们的想法是有一个外部图形,该图形会随着图形的输出值不断更新。每次数据更新时,它都应该重新绘制值,它以 ~10 Hz 的频率更新。我选择了gramm (https://github.com/piermorel/gramm/tree/master/%40gramm),因为制作光栅图真的很容易。

这是被调用的函数。我有问题

1) 使其仅在具有特定名称的父图形中更新,而不是在 GUI(即活动图形)中绘制。
2)让它不会崩溃。它会以 10 Hz 的频率打开多个图形或打开或关闭同一个图形,直到崩溃。

在这个配置中,它给出了错误,因为它在第一次绘图后没有找到g。使 gfp1 成为全局变量会使其崩溃(每次调用时都会打开)

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

【问题讨论】:

  • datastructure 中有什么内容?如果不知道生成什么类型​​的图、它有多少数据点等,就很难复制这个问题。
  • @CrisLuengo datastructure 是一个包含 final_data 表的结构,该表有约 10000 行 x 2 列
  • 所以这会生成一个线图?
  • 确实,如果我使用数据结构从控制台逐步运行它,此函数会生成准确的绘图(假设它找到fp1g)。它由 GUI 中的循环/侦听器函数调用

标签: matlab plot matlab-figure


【解决方案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

在这里,我遵循了您的概念,即寻找一个命名的图形窗口,如果它不存在则创建一个。但是,如果它确实存在,我只需替换已经存在的行的XDataYData 属性。这是动画图形的最快方法,比删除现有绘图并创建新绘图要快得多。绘图后,我使用drawnow 更新显示。我将 XLimModeYLimMode 设置为 manual 以防止重新计算轴限制并随后重新绘制轴。

该函数需要 17 秒来绘制所有 1000 帧,这意味着它每秒绘制大约 60 帧。它不会(也不应该)使 MATLAB 崩溃。

您可以使用drawnow limitrate 将显示速率限制为 20 帧/秒。如果帧来得太快,它将跳过更新显示。

我不知道gramm/update 方法的作用,该类太复杂,无法快速查看发生了什么,但我敢假设它会删除轴并从头开始创建新图。并不是说这会使 MATLAB 崩溃,submit a bug report 可能值得。但是,您可能希望按照我上面演示的方法以更有效的方式更新图形。

请注意,此方法可用于更新绘图中的任何图形元素。例如,我使用这种方法为图像设置动画。

【讨论】:

  • 谢谢!这确实可能有效,我熟悉“CData”/“Ydata”/“Xdata”的方式,我想我懒得制作分类图和栅格图来使用它。我会看看我能不能适应它。
  • 请注意,我建议您更新由gramm 创建的绘图的属性,您无需停止使用它。如果导致崩溃,请不要使用 update 方法... :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 2016-08-20
相关资源
最近更新 更多