【问题标题】:Creating animation with multiple plots - Octave/Matlab使用多个绘图创建动画 - Octave/Matlab
【发布时间】:2015-04-07 13:41:56
【问题描述】:

我正在使用 Octave 编写一个在不同时间段绘制函数的脚本。我希望创建情节的动画,以便查看随着时间的变化。

有没有办法做到这一点,以便可能以某种方式保存每个情节,以便可以组合每个情节来创建这个动画?

提前感谢您的建议!

【问题讨论】:

  • 在 MATLAB 中有 getframe 函数。这在 Octave 中也存在吗?
  • 使用循环并在每次迭代时更新绘图?
  • 我正在这样做,但我只是将每个函数绘制在同一个图上(不是动画)。此外,这不允许我将顺序图另存为动画

标签: matlab animation plot octave


【解决方案1】:

这有点杂乱无章,但您可以执行以下操作(此处适用于 octave 4.0.0-rc2):

x = (-5:.1:5);
for p = 1:5
  plot (x, x.^p)
  print animation.pdf -append
endfor
im = imread ("animation.pdf", "Index", "all");
imwrite (im, "animation.gif", "DelayTime", .5)

基本上,将所有绘图打印成 pdf,每页一个。然后将 pdf 作为图像读取并以 gif 格式打印回来。这在 Matlab 上不起作用(它的 imread 实现无法处理 pdf)。

【讨论】:

  • 好的,我试试看。
  • 嗯,好吧,这不是我要找的……我想把它保存到某种电影文件中,也可以添加到演示文稿中
  • @user3460758 定义视频文件?你没有声音,只有图像,所以 gif 应该做得很好。它还应该在演示文稿中显示为动画。请注意,您可以使用 LoopCount 这样它就不会循环动画,甚至可以将数组用作不同时间间隔的 DelayTime。您的解决方案到底有什么问题?
  • 我发现这似乎是一种简单的方法是使用两行:drawnow; pause(1/20);
  • @user3460758 读取后,你会得到一个 4d 矩阵。第 3 维是 RGB 通道,第 4 维是时间。只需根据需要旋转它。您也可以调整时间,延迟时间使用 1/20。此外,它在我的系统上运行良好,因此这可能是您的 graphics_ttolkit 或 Octave 版本的问题。我使用的是 octave 4.0.0-rc2,而我的 graphics_toolkit 是 qt。
【解决方案2】:

这将创建一个动画 gif

data=rand(100,100,20); %100 by 100 and 20 frames

%data go from 0 to 1, so lets convert to 8 bit unsigned integers for saving
data=data*2^8;
data=uint8(data);

%Write the first frame to a file named animGif.gif
imwrite(data(:,:,1),'/tmp/animGif.gif','gif','writemode','overwrite',...
        'LoopCount',inf,'DelayTime',0);

%Loop through and write the rest of the frames
for ii=2:size(data,3)
     imwrite(data(:,:,ii),'/tmp/animGif.gif','gif','writemode','append','DelayTime',0)
end

【讨论】:

    【解决方案3】:

    不得不在这里插话,因为当我寻求帮助时,这是我在 Google 上的最高搜索结果。我对这两个答案都有问题,还有其他一些问题。值得注意的是:

    1. 对于Rick T's answer,截断的代码不会写出绘图图形,它只是写矩阵数据。获取绘图窗口很痛苦。
    2. 对于 carandraug's answer,写入 PDF 花费了很长时间,并制作了一个巨大的 PDF。
    3. 在我自己的机器上,我非常确定我使用 apt-install 来获取 Octave,但是我在其他答案中找到的 getframe 函数没有找到。原来我安装了 4.4 版,它是 2018 年(>3 岁)的版本。

    我删除了旧版本的 Octave sudo apt remove octave,然后使用 snap 安装了新版本。如果您在未安装终端的情况下尝试 octave,它应该会提示您进行 snap install - 请务必包含 # 6.4.0 或命令中包含的任何内容。

    一旦我安装了当前版本,我就可以访问getframe 命令,这使您可以直接从图形句柄转换为图像数据 - 这绕过了@carandraug 答案中的 hackey(但以前必要的步骤)您必须在其中写入 PDF 或其他图像作为占位符。

    我使用@RickT 的答案制作了我自己的MakeGif 函数,我将在这里与大家分享。请注意,MakeGif 将文件名存储在一个持久变量中,这意味着它会在调用之间保留。如果您更改文件名,它将生成(或覆盖!!)新文件。如果您需要覆盖当前文件(即多次运行相同的脚本并想要新的结果),那么您可以在调用之间使用clear MakeGif,这将重置persistentFilename。

    这是 MakeGif 函数的代码;在此之后提供了测试它的代码:

    function MakeGif(figHandle, filename)
      persistent persistentFilename = [];
      if isempty(filename)
        error('Can''t have an empty filename!');
      endif
      if ~ishandle(figHandle)
        error('Call MakeGif(figHandle, filename); no valid figHandle was passed!');
      endif
      writeMode = 'Append';
      if isempty(persistentFilename)|(filename!=persistentFilename)
        persistentFilename = filename;
        writeMode = 'Overwrite';
      endif
      imstruct = getframe(figHandle);
      imwrite(imstruct.cdata, filename, 'gif', 'WriteMode',writeMode,'DelayTime',0);
    endfunction
    

    这是测试功能的代码。在蓝色和绿色之间有一个对clear MakeGif 的注释调用。如果您将其注释掉,它会将绿色正弦波附加到蓝色正弦波上,从而在每个周期后产生交替颜色 - 文件名再次在函数中保持不变。如果您取消注释该调用,则 MakeGif 函数会将绿色的调用视为“新”并触发蓝色正弦波的覆盖,您将看到的只是绿色。

    clear all;
    time = 0:0.1:2*pi;
    nSamples = numel(time);
    figHandle = figure(1);
    for i=1:nSamples
      plot(time,sin(time + time(i)),'Color','blue');
      drawnow;
      MakeGif(figHandle, 'test.gif');
    endfor
    
    % Uncomment the 'clear' command below to clear the MakeGif persistent
    % memory, which will trigger the green sine wave to overwrite the blue.
    % Default behavior is to APPEND a green sine wave because the filename
    % is the same.
    %clear MakeGif;
    
    for i=1:nSamples
      plot(time,sin(time + time(i)),'Color','green');
      drawnow;
      MakeGif(figHandle, 'test.gif');
    endfor
    

    在对延迟的屏幕截图非常不满意后,我花了几个小时在这上面,所以我真的希望这对未来的人有所帮助!祝你好运和来自 Covid 时代的良好祝愿哈哈。

    【讨论】:

    • 这里的最后一点(不想一直用编辑来影响答案)-getframe 函数需要 figure 句柄,而不是 plot 处理。请注意,测试框架函数使用的是figHandle = figure(1),而不是figHandle = plot(time, ...
    猜你喜欢
    • 2013-05-10
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多