MATLAB 作动态图

MATLAB 作动态图

本文谨记录笔者探索MATLAB作动态图后的心得,希望能帮到大家

动态线图

生成数据

首先打开MATLAB,生成一组数据。
以下是笔者在练习数学建模中的导弹追踪模型所写的一段代码
由于这段代码涉及的其他知识点较多,也不属于这篇文章的重点,有兴趣的读者可以看看,没有兴趣的可以用后文的替代代码

[x,y]=ode45(@df1,[0:1e-3:0.1],[20 0 0 0],[],200,45);

distance=sqrt((y(:,1)-y(:,3)).^2+(y(:,2)-y(:,4)).^2);
length1=sqrt((y(2:end,3)-y(1:end-1,3)).^2+(y(2:end,4)-y(1:end-1,4)).^2);
length1=cumsum(length1);
choose=min(find(distance<=1e-1))-1;
length1(choose)

plot(y(:,1),y(:,2),y(:,3),y(:,4),y(choose,1),y(choose,2),'bo',y(choose,3),y(choose,4),'ro')
% axis([0,max(y(:,1)),0,max(y(:,1))]

function dy=df1(t,y,v,si)
%     v=200;
    dy=zeros(4,1);
    dy(1)=cos(si/180*pi)*v;
    dy(2)=sin(si/180*pi)*v;
    dy(3)=3*v*(y(1)-y(3))/sqrt((y(1)-y(3))^2+(y(2)-y(4))^2);
    dy(4)=3*v*(y(2)-y(4))/sqrt((y(1)-y(3))^2+(y(2)-y(4))^2);
end

由于笔者使用的是实时脚本(听说是MATLAB 2016a之后才有),其可以使用局部函数,只需写在实时脚本最后即可。
而若使用普通脚本,则需在当前工作路径下新建函数文件,将其放入其中即可。
方便起见,使用普通脚本也可用下列代码代替

clear;clc
x=1:200;
y1=0.01*x;
y2=x-100;
y=[x;y1;x;y2]';
choose=100;

作动态图

方法一

有了数据之后便可以开始作图了,以下便是作图代码

for i = 1 : choose
    plot(y(i:i+1,1),y(i:i+1,2),'b','MarkerSize',1)
    plot(y(i:i+1,3),y(i:i+1,4),'r','MarkerSize',1)
    hold on 
    axis([min(y(:,3)),max(y(:,3)),min(y(:,4)),max(y(:,4))]);
    pause(0.1)
end

可以看到,这段代码先是逐段画线,然后用hold on保持图像,用pause控制画线速度,用choose控制画线的终点,这里取的是两条线的交点。

这是原代码画出来的线

Fig 1.这是原代码画出来的线

这是替代代码画出来的线

Fig 2.这是替代代码画出来的线
方法二

实际上,在MATLAB 2016 及之后的版本,其新增了一个画动态线图的函数,使用起来比方法一要方便

函数方法说明输入参数
animatedline创建动态线图的函数句柄(无输入参数)
addpoints(h,x,y)往动态线图新增点(动态线图的句柄,点的x坐标,点的y坐标)
getpoints(h)获取动态线图的所有点(动态线图的句柄)
clearpoints(h)清除动态线图的所有点(动态线图的句柄)
h=animatedline;
axis([0 4*pi -1 1])
x=linspace(0,4*pi,1000);
y=sin(x);
for k = 1:length(x)
    addpoints(h,x(k),y(k));
    pause(0.01)
end

动态点图

确定参数

先确定几个参数

n = 10; % 粒子数量
K = 10;  % 迭代的次数
vmax = [6 6]; % 粒子的最大速度
x_lb = [-15 -15]; % x的下界
x_ub = [15 15]; % x的上界

生成数据并创建函数句柄

然后笔者给出了一个实例函数,作出二维网格后计算出各点的值然后绘制出网格
其中 view([-39 45]) 是笔者认为可以较好展示此网格的角度

x1=x_lb(1):x_ub(1);
x2=x_lb(2):x_ub(2);
[x1,x2]=meshgrid(x1,x2);
y = x1.^2 + x2.^2 - x1.*x2 - 10*x1 - 4*x2 + 60;
mesh(x1,x2,y)
view([-39 45])
hold on

迭代以形成动态效果

然后迭代K次,给予一个随机数让点动起来,然后用一个for循环将点限制在绘图所在区域
然后利用函数句柄绘制散点图,即可动态展示散点
此处为了方便,用了一个函数(在实时脚本中放在最后即可,无需新建函数文件),也可用上一段代码的y来代替,其输出效果放在了实际应用后面

for d = 1:K
    x=x-vmax+2*vmax.*rand(n,narvs);
    for i = 1:narvs
        x(x(:,i)<x_lb(i),i)=x_lb(i);
        x(x(:,i)>x_ub(i),i)=x_ub(i);
    end

    pause(0.5);
    h.XData=x(:,1);
    h.YData=x(:,2);
    h.ZData=Obj_fun1(x);
end

hold off

function y=Obj_fun1(x)
    y=x(:,1).^2+x(:,2).^2-x(:,1).*x(:,2)-10*x(:,1)-4*x(:,2)+60;
end

实际应用

这其实是笔者在写粒子群算法时想到的一种动态展示散点图的方式,以下是全部代码

%% 粒子群算法(最小值)
%% 设置粒子群算法的参数
n = 10; % 粒子数量
narvs = 2; % 变量个数
c1 = 2;  % 每个粒子的个体学习因子,也称为个体加速常数
c2 = 2;  % 每个粒子的社会学习因子,也称为社会加速常数
w = 0.9;  % 惯性权重
K = 10;  % 迭代的次数
vmax = [6 6]; % 粒子的最大速度
x_lb = [-15 -15]; % x的下界
x_ub = [15 15]; % x的上界

%% 初始化粒子的位置和速度
x=x_lb+(x_ub-x_lb).*rand(n,narvs);
v=-vmax+2*vmax.*rand(n,narvs);

%% 计算适应度
fit=Obj_fun1(x);
pbest=x;
ind=find(fit==min(fit));
gbest=x(ind,:); 

%% 画图
x1=x_lb(1):x_ub(1);
x2=x_lb(2):x_ub(2);
[x1,x2]=meshgrid(x1,x2);
y = x1.^2 + x2.^2 - x1.*x2 - 10*x1 - 4*x2 + 60;
mesh(x1,x2,y)
view([-39 45])
hold on
h=scatter3(x(:,1),x(:,2),fit,'*r');

%% 更新粒子速度和位置
gbest_val_list=zeros(1,K);
for d = 1:K
    v=w*v+c1*rand(n,narvs).*(pbest-x) ...
        +c2*rand(n,narvs).*(gbest-x);
    for i = 1:narvs
        v(v(:,i)<-vmax(i),i)=-vmax(i);
        v(v(:,i)>vmax(i),i)=vmax(i);
    end
    x=x+v;
    for i = 1:narvs
        x(x(:,i)<x_lb(i),i)=x_lb(i);
        x(x(:,i)>x_ub(i),i)=x_ub(i);
    end
    fit=Obj_fun1(x);
    pbest(fit<Obj_fun1(pbest),:)=x(fit<Obj_fun1(pbest),:);
    if sum(Obj_fun1(pbest)<Obj_fun1(gbest)) > 0
        gbest=pbest(Obj_fun1(pbest) == min(Obj_fun1(pbest)),:);
    end
    gbest_val_list(d)=Obj_fun1(gbest);
    
    pause(0.5);
    h.XData=x(:,1);
    h.YData=x(:,2);
    h.ZData=fit;
end

%% 输出
hold off 
plot(1:K,gbest_val_list)
disp('最优解坐标为:')
disp(gbest)
disp('最优解值为:')
disp(Obj_fun1(gbest))

function y=Obj_fun1(x)
    y=x(:,1).^2+x(:,2).^2-x(:,1).*x(:,2)-10*x(:,1)-4*x(:,2)+60;
end

输出效果

在这里插入图片描述

Fig 3.起始点的分布情况

在这里插入图片描述

Fig 4.粒子群算法运行完毕时各点的分布情况

可以看到,这样的展示方式可以直观地看出粒子群算法寻找函数最小值的过程

本文到此结束,如有啥问题,可以留言告诉我哦

  • 10
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
动态模糊聚类图是指在模糊聚类的基础上,将数据点随时间变化而演化的聚类结果表现出来的图形。在Matlab中,可以使用fuzzy clustering函数进行模糊聚类,并使用动态图形绘制函数进行动态绘制。 具体步骤如下: 1.使用fcm函数进行模糊聚类,获取聚类中心和隶属度矩阵。 2.使用subplot创建子图,并在子图中使用scatter函数绘制数据点。 3.使用for循环迭代不同时间的聚类结果,并在每个时间点使用plot函数绘制聚类中心。 4.使用surf函数绘制隶属度矩阵的动态变化,可以使用set函数动态更新图形。 示例代码如下: ``` % 生成数据 data = rand(100, 2); % 初始化聚类中心 centers = [0.3 0.3; 0.7 0.7]; % 进行模糊聚类 [centers, U] = fcm(data, 2); % 创建子图 subplot(1, 2, 1); scatter(data(:, 1), data(:, 2), 20, U(1, :), 'filled'); hold on; scatter(centers(:, 1), centers(:, 2), 100, 'r', 'filled'); title('t = 0'); subplot(1, 2, 2); % 迭代不同时间的聚类结果 for t = 1:10 % 更新聚类中心 centers = [0.3 + t*0.01, 0.3 + t*0.01; 0.7 - t*0.01, 0.7 - t*0.01]; % 更新隶属度矩阵 U = fcm(data, 2, [NaN NaN NaN NaN; centers]); % 绘制数据点 scatter(data(:, 1), data(:, 2), 20, U(1, :), 'filled'); hold on; % 绘制聚类中心 scatter(centers(:, 1), centers(:, 2), 100, 'r', 'filled'); % 绘制隶属度矩阵的动态变化 surf(ones(size(data, 1), 1)*centers(1, 1), ones(size(data, 1), 1)*centers(1, 2), ... reshape(U(1, :), size(data, 1), []), 'EdgeColor', 'none'); surf(ones(size(data, 1), 1)*centers(2, 1), ones(size(data, 1), 1)*centers(2, 2), ... reshape(U(2, :), size(data, 1), []), 'EdgeColor', 'none'); % 更新图形 set(gca, 'ZLim', [0 1]); title(['t = ' num2str(t)]); hold off; pause(0.5); end ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值