Как сделать анимацию в матлабе
Перейти к содержимому

Как сделать анимацию в матлабе

  • автор:

Анимация графика

на графике выводятся все состояния точек,подскажите, пожалуйста, а как можно было бы сделать, чтобы предыдущее исчезало (ну то есть некую анимацию движения этой точки на графике) и как соединить эти точки последовательно в траекторию?

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Построение графика производной для каждого графика из 3 режимов
Дорогие друзья, прошу помочь доделать три программы. В каждой программе выводится по одному графику.

3d графика и анимация в JS
Подскажите в каком направлении думать. Фронт проекта будет писаться на JS, в проекте.

Графика. Анимация
анимацию еще углубленно не проходили так что если кто может, сделайте программу в которой шарик.

Анимация Графика
Здравствуйте. Подскажите пожалуйста литературу по анимации,Кварц Кору в Кокоа, только на.

5236 / 3564 / 378
Регистрация: 02.04.2012
Сообщений: 6,471
Записей в блоге: 17
нужно убрать hold on и воткнуть pause (без нее ты увидишь только последний кадр )

1 2 3 4 5 6
for t=0:10 x=10*t^2; y=100*t; plot(x,y,'o'); pause(0.01) end

Еще было бы неплохо зафиксировать пределы осей графика (в данном случае axis([0 1000 0 1000])) иначе у тебя не точка будет двигаться, а значения по осям

а продвинутые матлабофилы не рисуют новую точку на каждом кадре, а двигают уже имеющуюся

1 2 3 4 5 6 7 8
h = plot(NaN,NaN,'o'); % получаем указатель (handle) точки axis([0 1000 0 1000]) % задаем границы области графика for t = 0:0.1:10; x=10*t^2; y=100*t; set(h, 'XData',x, 'YData',y); pause(0.01) end

Создание анимированных графиков с помощью Matlab

Всем здравствуйте! Иногда у меня возникает потребность в анимированных графиках. Они помогают сделать подачу информации красивее и, что самое главное, нагляднее. Matlab позволяет создавать такие графики, причём с помощью всего нескольких функций. В данной статье будут рассмотрены основные принципы создания анимации — мы сделаем парочку графиков и сохраним всё это в GIF-файлы. Вот один из примеров, чтобы вы понимали, какой можно получить результат:

Как получить кадр и куда-нибудь его записать?

Я думаю, что ни для кого не секрет, что анимация — это последовательность кадров. Чем больше кадров отображается за секунду, тем более плавной нам кажется картинка. Для получения кадра в Matlab есть функция getframe. На кадре может быть только сам график, а может быть и всё графическое окно. Пока что просто построим график привычным нам способом:

x = 0 : 0.01 : 3; y = 2*x.^3 - 2*sin(tan(x)) + 25*cos(x.^-3); fh = figure; plot(x, y) grid on

Получим кадр всего графического окна и запишем его в JPEG-файл:

frame = getframe(fh); image = frame2im(frame); [X, cmap] = rgb2ind(image, 256); imwrite(X, cmap, 'myframe.jpeg', 'jpeg');

myframe.jpeg

Разберёмся, что происходит в этом коде. С помощью первой строки мы получили кадр. На второй строке мы конвертировали его в картинку с помощью функции frame2im. На третьей строке мы получили индексированное изображение X и его палитру cmap с помощью функции rgb2ind. При этом можно задать, сколько максимум цветов будет в изображении (с помощью второго аргумента функции rgb2ind) — мне кажется, что 256 хватит для любого графика. На четвёртой строке мы используем полученные данные и функцию imwrite, чтобы записать наш график в файл myframe.jpeg. Поменяем первую строку таким образом, чтобы получить график без графического окна:

frame = getframe(gca);

myframe.jpeg

Заметим, что идентичный результат можно было получить и с помощью кода ниже:

frame = getframe;

Если у вас несколько графиков и вы хотите получить кадр каких-то конкретных осей, то использовать нужно, разумеется, предыдущий вариант, передавая в функцию getframe интересующие вас оси (с окнами, естественно, работает та же логика).

Попробуем создать первый анимированный график

Давайте сделаем так, чтобы синусоида вечно двигалась вправо:

x = 0 : 0.01 : 2; for i = 0 : 0.1 : 2 plot(x, sin(2*pi*x - pi*i)) xlim([0 2]) frame = getframe; image = frame2im(frame); [X, cmap] = rgb2ind(image, 256); if i == 0 imwrite(X, cmap, 'myanim.gif', 'gif', 'LoopCount', Inf, . 'DelayTime', 1/24); else imwrite(X, cmap, 'myanim.gif', 'gif', 'WriteMode', 'append', . 'DelayTime', 1/24); end end

Тут я, конечно, воспользовался тем фактом, что сдвиг синусоиды по фазе на два пи равносилен отсутствию её сдвига. Мы плавно повышаем сдвиг фазы от нуля до двух пи, после чего анимация начинается заново (хоть нам и кажется, что она продолжается).

В цикле for на каждой итерации мы получаем новый кадр, после чего сразу записываем его в GIF-файл. Отдельное внимание уделим строкам 9-14 листинга. По умолчанию функция imwrite записывает кадр поверх всего файла, то есть если не менять никакие параметры, на выходе мы получим GIF-файл с одним кадром (последним). При добавлении первого кадра мы ждём именно такого поведения функции, поэтому параметр WriteMode мы не трогаем. С помощью параметра LoopCount мы устанавливаем количество повторений анимации (в данном случае — бесконечное), а с помощью параметра DelayTime — длину кадра (в данном случае это , т.к. желаемая частота кадров анимации — 24 кадра в секунду). Все остальные кадры должны записываться в конец файла, для этого мы изменяем параметр WriteMode на ‘append’. Изменяя шаг для переменной i и длину кадра можно менять скорость и плавность анимации.

Создание анимированной линии

Теперь попробуем сделать так, чтобы синусоида рисовалась постепенно (слева направо). Конечно, можно сначала рассчитать вектор со всеми значениями функции, а потом в цикле for постепенно его отрисовывать — сначала только первый элемент, потом первые два элемента, потом первые три и т.д., пока не выведем весь вектор. Этот вариант, конечно, сработает, но в Matlab есть функции animatedline и addpoints, которые можно использовать в подобных ситуациях. Перейдём к примеру:

lh = animatedline; for i = 0 : 0.01 : 2 addpoints(lh, i, sin(2*pi*1*i)); xlim([0 2]) ylim([-1 1]) frame = getframe; image = frame2im(frame); [X, cmap] = rgb2ind(image, 256); if i == 0 imwrite(X, cmap, 'myanim.gif', 'gif', 'LoopCount', Inf, . 'DelayTime', 1/60); else imwrite(X, cmap, 'myanim.gif', 'gif', 'WriteMode', 'append', . 'DelayTime', 1/60); end end

На первой строке мы создаём объект анимированной линии. В цикле мы добавляем к нашей линии по одной точке с помощью функции addpoints. Первым аргументом передаём объект анимированной линии, вторым и третьим аргументами — координаты x и y новой точки соответственно. Удалить все точки из объекта анимированной линии можно с помощью функции clearpoints. Получить все его точки можно с помощью функции getpoints.

Пример 1

В начале статьи я приводил пример анимированного графика. Попробуем его, наконец, реализовать:

%% Плавное появление синусоиды fileName = 'habr1.gif'; figure('Position', [0, 0, 1280, 720]) grid on sine = animatedline; sine.Color = 'blue'; f = 1; %Частота синусоиды for i = 0 : 0.01 : 1 addpoints(sine, i, sin(2*pi*f*i - pi/12)); xlim([0, 1]) ylim([-1.1, 1.1]) [A, map] = GetIndImage; if i == 0 imwrite(A, map, fileName, 'gif', 'LoopCount', Inf, . 'DelayTime', 1/60); else imwrite(A, map, fileName, 'gif', 'WriteMode', 'append', . 'DelayTime', 1/60); end end %% Раздвоение и сдвиг синусоиды [sine_x, sine_y] = getpoints(sine); x = 0 : 0.01 : 1; for phi = 0 : 0.02 : pi/2 sine_offset_y = sin(2*pi*f*x - pi/12 - phi); hAx = plot(sine_x, sine_y, 'r', . x, sine_offset_y, 'b'); grid on box off xlim([0, 1]) ylim([-1.1 1.1]) [A, map] = GetIndImage; imwrite(A, map, fileName, 'gif', 'WriteMode', 'append', 'DelayTime', 1/60); end %% Плавное появление вертикальных линий left_line = animatedline; right_line = animatedline; for i = 1.1 : -0.05 : -1.1 addpoints(left_line, 1/24, i); addpoints(right_line, 0.4166, i); xlim([0, 1]) ylim([-1.1, 1.1]) [A, map] = GetIndImage; imwrite(A, map, fileName, 'gif', 'WriteMode', 'append', 'DelayTime', 1/60); end %% Плавное закрашивание области rh = rectangle('Position', [1/24 -1.2 0.4166-1/24 2.4], 'FaceColor', [0 0 0 0]); for i = 0 : 0.01 : 0.3 rh.FaceColor = [0 0 0 i]; [A, map] = GetIndImage; imwrite(A, map, fileName, 'gif', 'WriteMode', 'append', 'DelayTime', 1/60); end imwrite(A, map, fileName, 'gif', 'WriteMode', 'append', 'DelayTime', 1.5); %% Функция получения индексированного изображения function [A, map] = GetIndImage frame = getframe; image = frame2im(frame); [A, map] = rgb2ind(image, 256); end 

Сразу обращу внимание, что получение индексированного изображения из кадра я вынес в отдельную функцию, её определение на строках 69-73. До 22 строки всё, как мне кажется, должно быть понятно — это плавное появление синусоиды, которое мы делали и в предыдущем разделе. На строке 26 происходит преобразование получившейся синусоиды в набор точек, который потом используется для построения этой же синусоиды с помощью функции plot в следующем цикле. С плавным появлением вертикальных линий, как мне кажется, тоже всё должно быть понятно. Плавное закрашивание области реализовано с помощью плавного понижения прозрачности прямоугольника. Делать так можно, кстати, далеко не со всеми объектами. К сожалению, менять прозрачность текста нельзя. Строка 65 нужна для задержки кадра в конце анимации. То есть на протяжении анимации частота обновления кадров может быть разной.

Пример 2

Напоследок приведу анимацию, которая реально помогает нагляднее представить информацию. Она показывает, что такое эффект «растекания спектра», который возникает при применении дискретного преобразования Фурье.

fileName = 'habr2.gif'; fh = figure('Position', [0 0 1280 720]); x = -0.1 : 0.01 : 1.5; y = sin(2*pi*1*x); counter = 0; %% Движение вправо for i = 0.8 : 0.01 : 1.2 subplot(2, 1, 1) plot(x, y, 'LineWidth', 1.5) grid on rectangle('Position', [0 -1.2 i 2.4], . 'FaceColor', [204/255 153/255 255/255 0.3], . 'LineWidth', 0.01) xline(1, 'r--', 'LineWidth', 1.3) xlim([-0.01 1.21]) ylim([-1.1 1.1]) subplot(2, 1, 2) stem(abs(fft(y(11 : 90 + counter)))) xlim([0, 121]) ylim([0, 60]) counter = counter + 1; frame = getframe(fh); image = frame2im(frame); [A, map] = rgb2ind(image, 256); if i == 0.8 imwrite(A, map, fileName, 'gif', 'LoopCount', Inf, 'DelayTime', 1/24); else imwrite(A, map, fileName, 'gif', 'WriteMode', 'append', 'DelayTime', 1/15); end end %% Движение влево counter = counter - 1; for i = 1.2 : -0.01 : 0.8 subplot(2, 1, 1) plot(x, y, 'LineWidth', 1.5) grid on rectangle('Position', [0 -1.2 i 2.4], . 'FaceColor', [204/255 153/255 255/255 0.3], . 'LineWidth', 0.01) xline(1, 'r--', 'LineWidth', 1.3) xlim([-0.01 1.21]) ylim([-1.1 1.1]) subplot(2, 1, 2) stem(abs(fft(y(11 : 90 + counter)))) xlim([0, 121]) ylim([0, 60]) counter = counter - 1; frame = getframe(fh); image = frame2im(frame); [A, map] = rgb2ind(image, 256); imwrite(A, map, fileName, 'gif', 'WriteMode', 'append', 'DelayTime', 1/15); end

Все приёмы, что есть в приведённом выше коде, мы с вами уже обсудили. Надеюсь, что статья была для вас полезной!

  • matlab
  • построение графиков
  • анимированный график
  • gif
  • gif-анимация
  • график matlab
  • анимация matlab
  • анимация
  • 2d-графика

Как сделать анимацию в MATLAB и сохранить её в формате GIF

В прошлой заметке мы с вами создавали видеролик при помощи MATLAB. Иногда полезно иметь анимацию не в видео формате, а в виде популярного в интернете формата GIF.

За основу мы возьмём код и данные, которые использовали в вышеупомянутой заметке:

for n =1:365 worldmap('world') setm(gca,'Origin', [0 180 0]) geoshow(lat,lon,air(. n),'displaytype','texture') geoshow('landareas.shp','FaceColor','none','EdgeColor','w') caxis([-80 40]) cmocean('thermal') colorbar title(datestr(t(n))) frame(n) = getframe(gcf); close(gcf) end v = VideoWriter('air_temp2018.mp4','MPEG-4'); v.FrameRate = 10; open(v) writeVideo(v,frame) close(v)

Напомню, что первая часть строит все нужные нам картинки (отдельные кадры будущего видео) и записывает их в переменную frame. Затем, используя эту самую переменную frame во второй части кода мы создаём их этих кадров видеоролик. Сейчас эта вторая часть нам не понадобится, мы теперь используем переменную frame для создания GIF. Давайте я сначала сразу приведу здесь готовый код, а уже потом сделаю некоторые пояснения:

for n = 1:size(frame,2) [A,map] = rgb2ind(frame2im(frame(n)),256); if n == 1 imwrite(A,map,'test1.gif','gif','LoopCount',Inf,'DelayTime',1); else imwrite(A,map,'test1.gif','gif','WriteMode','append','DelayTime',1); end end

Если вы не хотите разбираться, то можете прямо его использовать и не задумываться о деталях.

Итак, как вы наверное поняли, gif создаётся при помощи функции imwrite, которая создана, вообще говоря, для записи разных типов графических файлов, не только gif (png, jpg и т.п.).

GIF файл создаётся в несколько этапов, сначала создаётся первый кадр (он может остаться единственным, если нам не нужна анимация), в коде это отражено в строке, идущей сразу после «if n == 1». Затем остальные кадры анимации записываются в наш файл при помощи опции ‘WriteMode’,’append’.

Поскольку формат gif работает с индексированными цветами, то нам нужно перевести изображения из RGB в эти самые индексированные цвета, т.е. получить в нашем случае само изображение, которое будет записано в переменную A и карту цветов (т.е. какому цвету соответствует каждое число в переменной A), записанную в переменную map. Делает это всё функция rgb2ind. У нас, как вы видите, в качестве второго входного аргумента этой функции стоит число 256, это количество цветов, которые мы будем иметь в изображении. Если вам нужно уменьшить размер итогового файла, то вы может пожертвовать палитрой и создать гифку, состоящую из меньшего количества цветов. Например, так будет выглядить наша анимация, если мы оставим всего 8 цветов:

Также обратите внимание, что функция rgb2ind не поймёт, если вы попытаетесь скормить ей наши кадры, которые мы записывали в переменную frame, поэтому для начала мы должны перевести из в изображение при помощи функции frame2im.

Осталось только сказать, что ‘LoopCount’,Inf — означает, что наше изображение будет зацикленное, т.е. повторяться снова и снова, а ‘DelayTime’,1 — устанавливает задержку по времени между кадрами (в секундах).

Чтобы не пропустить новые материалы с рецептами по работе с океанологическими данными, подпишитесь на канал в Telegram: https://t.me/koldunovaleksey

Данные для заметки:

NCEP Reanalysis data provided by the NOAA/OAR/ESRL PSD, Boulder, Colorado, USA, from their Web site at https://www.esrl.noaa.gov/psd/

Kalnay et al., The NCEP/NCAR 40-year reanalysis project, Bull. Amer. Meteor. Soc., 77, 437-470, 1996

Как сделать анимацию в MATLAB и сохранить видео в формате mp4

Как сделать анимацию в MATLAB и сохранить видео в формате mp4

Часто учёным намного проще анализировать данные, когда они представлены в виде анимации. Сегодня мы сделаем простую анимацию в MATLAB и сохраним её в виде видео-файла в формате MPEG-4.

Для построения картинок мы будем использовать NCEP/NCAR Reanalysis с этого сайта. Я скачал ежедневные значения температуры воздуха у поверхности для 2018 года. Если хотите себе такие же, прямая ссылка вот.

Для начала загрузим наши данные в рабочую область Matlab:

air = ncread('air.sig995.2018.nc','air')-273.15; lat = ncread('air.sig995.2018.nc','lat'); lon = ncread('air.sig995.2018.nc','lon');

Обратите внимание, что мы вычли 273.15 из значений температуры, для того чтобы перевести их в градусы Цельсия (исходные данные в Кельвинах). Для последующих построений нам нужно будет перевести векторы lat и lon в матрицы:

[lon,lat]=ndgrid(lon,lat);

Вектор с датами проще будет создать вручную:

t = datetime(2018,01,01):datetime(2018,12,31);

Теперь можно построить карту. Пока, всё что мы делаем и дальнейшие построения карт не должны вызывать сложностей, так как всё уже было описано здесь на сайте. Однако на всякий случай сделаю некоторые краткие комментарии.

Строим карту (подложку) и ориентируем её так, чтобы по центру располагался 180 градус долготы:

worldmap('world') setm(gca,'Origin', [0 180 0])

Строим карту распределения температуры для первой даты нашего массива и добавляем на рисунок colorbar:

geoshow(lat,lon,air(. 1),'displaytype','texture') colorbar

Строим для ориентировки береговую черту и закрашиваем её белым цветом (белый только контур, сами берега прозрачные):

geoshow('landareas.shp','FaceColor','none','EdgeColor','w')

В качестве заголовка к рисунку используем дату:

title(datestr(t(1)))

Ну и при желании заменяем цветовую шкалу (сработает только если у вас установлен пакет cmocean):

cmocean('thermal')

Все строки кода для построения выглядят так:

worldmap('world') setm(gca,'Origin', [0 180 0]) geoshow(lat,lon,air(. 1),'displaytype','texture') geoshow('landareas.shp','FaceColor','none','EdgeColor','w') cmocean('thermal') colorbar title(datestr(t(1)))

и приводят к следующему результату:

Допустим, вам нужно посмотреть на картину в динамике, т.е. в нашем случае — посмотреть, как изменяется температура со временем. Можно создать цикл и просто смотреть, как постепенно строятся картинки одна за одной. Если у вас не слишком мощный компьютер, то этот вариант будет выглядеть как анимация. Если же у вас мощный компьютер, которые строит карты слишком быстро, вы можете в середине цикла поставить паузу. Например, это может выглядеть так:

for n =1:365 worldmap('world') setm(gca,'Origin', [0 180 0]) geoshow(lat,lon,air(. n),'displaytype','texture') geoshow('landareas.shp','FaceColor','none','EdgeColor','w') caxis([-80 40]) cmocean('thermal') colorbar title(datestr(t(n))) pause(0.5) end

В данном коде pause(0.5) означает паузу 0.5 секунд. Кроме того, я добавил caxis([-80 40]) — это жёсткое ограчинение границ цветов, чтобы они не менялись от карты к карте.

Однако, такая анимация годится только для быстрого анализа при работе с данными. Если же вы хотите получить анимацию в виде видео-файла, то сделать это можно следующим образом. На каждом витке цикла построенная картинка записывается в виде отдельного кадра при помощи специальной функции getframe. Например, мы создадим переменную frame, куда запишем все 365 построенных карт.

for n =1:10 worldmap('world') setm(gca,'Origin', [0 180 0]) geoshow(lat,lon,air(. n),'displaytype','texture') geoshow('landareas.shp','FaceColor','none','EdgeColor','w') caxis([-80 40]) cmocean('thermal') colorbar title(datestr(t(n))) frame(n) = getframe(gcf); close(gcf) end

Обратите внимание, что кроме строки frame(n) = getframe(gcf) мы добавили ещё и close(gcf). В нашем случае это было делать не обязательно, так как функция worldmap закроет предыдущую карту в начале каждого цикла. Однако вы можете столкнуться с проблемой, когда все ваши кадры останутся открытыми, так что пусть будет.

Теперь, для того, чтобы записать анимацию в видео-файл нужно сделать следующее. Во-первых создать видеофайл и присвоить резултат этого действия какой-нибудь переменной (у нас это v), с помощью которой мы затем будем к нему обращаться:

v = VideoWriter('air_temp2018.mp4','MPEG-4');

При желании можно внести некоторые изменения в свойства файла, настроить всё под себя. Например, мне часто приходится менять частоту кадров:

v.FrameRate = 10; %10 frames per second

После всех настроек осталось открыть ваш созданный видео-файл, записать туда все кадры и закрыть файл:

open(v) writeVideo(v,frame) close(v)

Целиком весь код выглядит так:

for n =1:365 worldmap('world') setm(gca,'Origin', [0 180 0]) geoshow(lat,lon,air(. n),'displaytype','texture') geoshow('landareas.shp','FaceColor','none','EdgeColor','w') caxis([-80 40]) cmocean('thermal') colorbar title(datestr(t(n))) frame(n) = getframe(gcf); close(gcf) end v = VideoWriter('air_temp2018.mp4','MPEG-4'); v.FrameRate = 10; open(v) writeVideo(v,frame) close(v)

Чтобы не пропустить новые материалы с рецептами по работе с океанологическими данными, подпишитесь на канал в Telegram: https://t.me/koldunovaleksey

Данные для заметки:

NCEP Reanalysis data provided by the NOAA/OAR/ESRL PSD, Boulder, Colorado, USA, from their Web site at https://www.esrl.noaa.gov/psd/

Kalnay et al., The NCEP/NCAR 40-year reanalysis project, Bull. Amer. Meteor. Soc., 77, 437-470, 1996

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *