Несколько сюжетов на одной фигуре - PullRequest
20 голосов
/ 08 января 2012

У меня есть следующий код, и я хочу объединить графики фазового пространства в одну фигуру.

Я закодировал функции, но я не знаю, как заставить MATLAB сложить их в одну фигуру.Как видите, изменяются переменные r, a, b и d.Как мне их объединить?

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

%function lotkavolterra
% Plots time series and phase space diagrams.
clear all; close all;
t0 = 0;
tf = 20;
N0 = 20;
P0 = 5;

% Original plot
r = 2;
a = 1;
b = 0.2;
d = 1.5;

% Time series plots
lv = @(t,x)(lv_eq(t,x,r,a,b,d));
[t,NP] = ode45(lv,[t0,tf],[N0 P0]);
N = NP(:,1); P = NP(:,2);
figure
plot(t,N,t,P,' --');
axis([0 20 0 50])
xlabel('Time')
ylabel('predator-prey')
title(['r=',num2str(r),', a=',num2str(a),', b=',num2str(b),', d=',num2str(d)]);
saveas(gcf,'predator-prey.png')
legend('prey','predator')

% Phase space plot

figure
quiver(N,P);
axis([0 50 0 10])
%axis tight


% Change variables
r = 2;
a = 1.5;
b = 0.1;
d = 1.5;

%time series plots
lv = @(t,x)(lv_eq(t,x,r,a,b,d));
[t,NP] = ode45(lv,[t0,tf],[N0 P0]);
N = NP(:,1); P = NP(:,2);
figure
plot(t,N,t,P,' --');
axis([0 20 0 50])
xlabel('Time')
ylabel('predator-prey')
title(['r=',num2str(r),', a=',num2str(a),', b=',num2str(b),', d=',num2str(d)]);
saveas(gcf,'predator-prey.png')
legend('prey','predator')


% Phase space plot
figure
plot(N,P);
axis([0 50 0 10])

% Change variables
r = 2;
a = 1;
b = 0.2;
d = 0.5;

% Time series plots
lv = @(t,x)(lv_eq(t,x,r,a,b,d));
[t,NP] = ode45(lv,[t0,tf],[N0 P0]);
N = NP(:,1); P = NP(:,2);
figure
plot(t,N,t,P,' --');
axis([0 20 0 50])
xlabel('Time')
ylabel('predator-prey')
title(['r=',num2str(r),', a=',num2str(a),', b=',num2str(b),', d=',num2str(d)]);
saveas(gcf,'predator-prey.png')
legend('prey','predator')


% Phase space plot
figure
plot(N,P);
axis([0 50 0 10])

% Change variables
r = 0.5;
a = 1;
b = 0.2;
d = 1.5;

% Time series plots
lv = @(t,x)(lv_eq(t,x,r,a,b,d));
[t,NP] = ode45(lv,[t0,tf],[N0 P0]);
N = NP(:,1); P = NP(:,2);
figure
plot(t,N,t,P,' --');
axis([0 20 0 50])
xlabel('Time')
ylabel('predator-prey')
title(['r=',num2str(r),', a=',num2str(a),', b=',num2str(b),', d=',num2str(d)]);
saveas(gcf,'predator-prey.png')
legend('prey','predator')

% Phase space plot
figure
plot(N,P);
axis([0 50 0 10])

% FUNCTION being called from external .m file

%function dx = lv_eq(t,x,r,a,b,d)
%N = x(1);
%P = x(2);
%dN = r*N-a*P*N;
%dP = b*a*P*N-d*P;
%dx =  [dN;dP];

Ответы [ 2 ]

29 голосов
/ 08 января 2012

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

Я буду использовать небольшой примерный набор данных вместе с соответствующими цветами:

%% Data
t  = 0:100;
f1 = 0.3;
f2 = 0.07;
u1 = sin(f1*t);   cu1 = 'r'; %red
u2 = cos(f2*t);   cu2 = 'b'; %blue
v1 = 5*u1.^2;     cv1 = 'm'; %magenta
v2 = 5*u2.^2;     cv2 = 'c'; %cyan

Прежде всего, когда вы хотите, чтобы все было на одной оси, вам понадобится функция hold:

%% Method 1 (hold on)
figure;
plot(t, u1, 'Color', cu1, 'DisplayName', 'u1'); hold on;
plot(t, u2, 'Color', cu2, 'DisplayName', 'u2'); 
plot(t, v1, 'Color', cv1, 'DisplayName', 'v1'); 
plot(t, v2, 'Color', cv2, 'DisplayName', 'v2'); hold off;
xlabel('Time t [s]');
ylabel('u [some unit] and v [some unit^2]');
legend('show');

Method 1

Вы видите, чтоэто правильно во многих случаях, однако, это может стать громоздким, когда динамический диапазон обеих величин сильно различается (например, значения u меньше 1, а значения v намного больше).

Во-вторых, когда у вас много данных или разных количеств, также можно использовать subplot для разных осей.Я также использовал функцию linkaxes, чтобы связать оси в направлении х.Когда вы увеличиваете один из них в MATLAB, другой отображает тот же диапазон x, что позволяет легче просматривать большие наборы данных.

%% Method 2 (subplots)
figure;
h(1) = subplot(2,1,1); % upper plot
plot(t, u1, 'Color', cu1, 'DisplayName', 'u1'); hold on;
plot(t, u2, 'Color', cu2, 'DisplayName', 'u2'); hold off;

xlabel('Time t [s]');
ylabel('u [some unit]');
legend(gca,'show');

h(2) = subplot(2,1,2); % lower plot
plot(t, v1, 'Color', cv1, 'DisplayName', 'v1'); hold on;
plot(t, v2, 'Color', cv2, 'DisplayName', 'v2'); hold off;

xlabel('Time t [s]');
ylabel('v [some unit^2]');
legend('show');

linkaxes(h,'x'); % link the axes in x direction (just for convenience)

Method 2

Субплоты делаюттратить некоторое пространство, но они позволяют хранить некоторые данные вместе, не перенасыщая график.

Наконец, в качестве примера для более сложного метода построения разных количеств на одном и том же рисунке с использованием plotyy функция (или еще лучше: функция yyaxis начиная с R2016a)

%% Method 3 (plotyy)
figure;
[ax, h1, h2] = plotyy(t,u1,t,v1);
set(h1, 'Color', cu1, 'DisplayName', 'u1');
set(h2, 'Color', cv1, 'DisplayName', 'v1');
hold(ax(1),'on');
hold(ax(2),'on');
plot(ax(1), t, u2, 'Color', cu2, 'DisplayName', 'u2');
plot(ax(2), t, v2, 'Color', cv2, 'DisplayName', 'v2');

xlabel('Time t [s]');
ylabel(ax(1),'u [some unit]');
ylabel(ax(2),'v [some unit^2]');

legend('show'); 

Method 3

Это, конечно, выглядит многолюдно, но может прийтиудобно, когда у вас большая разница в динамическом диапазоне сигналов.

Конечно, ничто не мешает вам использовать комбинацию этих методов вместе: hold on вместе с plotyy и subplot.

edit:

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

function [u,v] = plotode(func,x,t,style)
% [u,v] = PLOTODE(func,x,t,[style])
%    plots the slope lines ODE defined in func(x,t)
%    for the vectors x and t
%   An optional plot style can be given (default is '.b')

if nargin < 4
    style = '.b';
end;
% http://ncampbellmth212s09.wordpress.com/2009/02/09/first-block/
[t,x] = meshgrid(t,x);

v  = func(x,t);
u  = ones(size(v));
dw = sqrt(v.^2 + u.^2);

quiver(t,x,u./dw,v./dw,0.5,style);
xlabel('t'); ylabel('x');

При вызове:

logistic = @(x,t)(x.* ( 1-x )); % xdot = f(x,t)
t0 = linspace(0,10,20);
x0 = linspace(0,2,11);

plotode(@logistic,x0,t0,'r'); 

это приводит к: Quiver plot

Если вы хотите большеруководство, я нашел эту ссылку в моем источнике очень полезной (хотя и плохо отформатированной).

Кроме того, вы можете взглянуть на справку MATLAB, это действительно здорово.Просто введите help quiver или doc quiver в MATLAB или используйте ссылки, которые я предоставил выше (они должны содержать то же содержимое, что и doc).

3 голосов
/ 08 января 2012

Если вы хотите, чтобы все графики были на одной фигуре, вызывайте команду фигурки только один раз.Используйте команду hold on после первого вызова команды plot, чтобы последующие вызовы plot не перезаписывали предыдущие графики.

...