• MATLAB | 你是猫猫教还是狗狗教还是ikun


    发现了俩有趣github项目,作者R CODER写了一个将散点修改为猫猫狗狗图片的的工具函数:

    • https://github.com/r-coderdotcom/ggcats
    • https://github.com/R-CoderDotCom/ggdogs

    R语言能有的MATLAB也要有,于是我将其改编了一个简简单单的MATLAB版本,效果如下:


    工具函数

    很显然没有素材包的话无法使用,素材包及完整代码请见文末提示关键词,不过当然构造起来也没难的,我将素材包的构造代码放在了最后。先展示工具函数完整代码:

    function imageHdl=scatterCanD(X,Y,type,sz)
    % @author:slandarer
    
    if nargin<4,sz=1;end
    if nargin<3,type=1;end
    
    % 调整数组大小
    X=X(:);Y=Y(:);type=type(:);sz=sz(:);
    LenRatio1=ceil(length(X)/length(type));
    LenRatio2=ceil(length(X)/length(sz));
    type=repmat(type,[LenRatio1,1]);
    sz=repmat(sz,[LenRatio2,1]);
    
    % 导入图像
    CanDSet=load('CanD.mat');
    disp(CanDSet.author);
    setC=CanDSet.CanD_C;
    setA=CanDSet.CanD_A;
    
    % 计算比例
    ax=gca;hold on
    tempScatter=scatter(X,Y);
    PRatio=ax.PlotBoxAspectRatio;
    XLen=diff(ax.XLim);
    YLen=diff(ax.YLim);
    baseLX=XLen/10;
    baseLY=YLen/10./PRatio(2).*PRatio(1);
    
    
    % 开始绘图
    for i=1:length(X)
        imageHdl(i)=image([-baseLX,baseLX].*sz(i)+X(i),...
              [-baseLY,baseLY]./size(setC{type(i)},2).*size(setC{type(i)},1).*sz(i)+Y(i),...
              setC{type(i)},'AlphaData',setA{type(i)});
    end
    
    
    delete(tempScatter)
    % axis tight
    hold off
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • X 数组:x坐标
    • Y 数组:y坐标
    • type 向量或数值:图片种类1-15为猫,26-40为狗
    • sz 向量或数值:图片大小

    使用方式

    类型为数值

    X=rand([1,30]);
    Y=rand([1,30]).*2;
    
    scatterCanD(X,Y,11,1);
    axis tight
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意请先确定好XY轴比例之后再绘图,不要绘图后再调整比例,即使未绘图前比例是1:100啥的很夸张的比例也能正常绘图,但之后再调整会比例失调:

    X=rand([1,30]);
    Y=rand([1,30]);
    
    scatterCanD(X,Y,11,1);
    axis tight
    
    set(gca,'YLim',[0,2])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    类型为向量

    会循环向量对应的图像,例如循环14,15,9对应的图像:

    X=linspace(0,2*pi,100);
    Y=sin(X);
    
    plot(X,Y,'LineWidth',4,'Color','k');
    hold on
    
    % 绘制14 15 9循环的图
    X1=X(1:5:end);
    Y1=Y(1:5:end);
    scatterCanD(X1,Y1,[14,15,9],.6);
    
    % 修饰一下
    axis tight
    ax=gca;box on;grid on
    ax.GridLineStyle='-.';
    ax.GridAlpha=.05;
    ax.LineWidth=1.4;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    随机类型

    X=linspace(0,2*pi,100);
    Y=sin(X);
    
    plot(X,Y,'LineWidth',4,'Color','k');
    hold on
    
    % 随机绘图
    X1=X(1:6:end);
    Y1=Y(1:6:end);
    L=length(X1);
    scatterCanD(X1,Y1,randi([1,40],[1,L]),.6);
    
    % 修饰一下
    axis tight
    ax=gca;box on;grid on
    ax.GridLineStyle='-.';
    ax.GridAlpha=.05;
    ax.LineWidth=1.4;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    大小为向量

    和类型设置一模一样,也会循环向量内的大小,例如:

    X=linspace(0,2*pi,100);
    Y=sin(X);
    
    plot(X,Y,'LineWidth',4,'Color','k');
    hold on
    
    X1=X(1:4:end);
    Y1=Y(1:4:end);
    scatterCanD(X1,Y1,14,[.3,.5,1]);
    
    % 修饰一下
    axis tight
    ax=gca;box on;grid on
    ax.GridLineStyle='-.';
    ax.GridAlpha=.05;
    ax.LineWidth=1.4;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    X=linspace(0,2*pi,100);
    Y=sin(X);
    
    plot(X,Y,'LineWidth',4,'Color','k');
    hold on
    
    % 绘制14越来越小
    X1=X(1:4:end);
    Y1=Y(1:4:end);
    L=length(X1);
    sz=(L:-1:1)./L.*.5+.3;
    scatterCanD(X1,Y1,14,sz);
    
    % 修饰一下
    axis tight
    ax=gca;box on;grid on
    ax.GridLineStyle='-.';
    ax.GridAlpha=.05;
    ax.LineWidth=1.4;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    有趣的效果

    弄了个有趣的动图:

    X=linspace(0,10,100);
    Y=X+rand([1,100]).*2;
    Y(1:end-1)=(Y(1:end-1)+Y(2:end))./2;
    
    % 修饰一下坐标区域
    ax=gca;hold on;box on;grid on
    ax.XLim=[0,12];
    ax.YLim=[0,14];
    ax.GridLineStyle='-.';
    ax.GridAlpha=.05;
    ax.LineWidth=1.4;
    
    % 绘制线条及俩猫头
    lineHdl=plot(X,Y,'LineWidth',2);
    C8Hdl=scatterCanD(X(1),Y(1),8,.8);
    C9Hdl=scatterCanD(X(1),Y(1),9,.8);
    
    % 记录猫头初始位置
    XData0=C8Hdl.XData-X(1);
    YData0=C8Hdl.YData-Y(1);
    
    % 初始化gif图
    DelayTime=.1;
    F=getframe(ax);
    [imind,cm]=rgb2ind(F.cdata,256);
    imwrite(imind,cm,'demo2.gif','gif','Loopcount',inf,'DelayTime',DelayTime);
    
    for i=1:length(X)
        lineHdl.XData=X(1:i);
        lineHdl.YData=Y(1:i);
        % 循环显示和隐藏俩猫头
        if mod(i,2)==0
            C8Hdl.Visible='on';
            C9Hdl.Visible='off';
        else
            C9Hdl.Visible='on';
            C8Hdl.Visible='off';
        end
        % 更新猫头坐标
        C8Hdl.XData=XData0+X(i);
        C9Hdl.XData=XData0+X(i);
        C8Hdl.YData=YData0+Y(i);
        C9Hdl.YData=YData0+Y(i);
        drawnow
        pause(.05)
    
        % 逐帧存入gif图
        F=getframe(ax);
        [imind,cm]=rgb2ind(F.cdata,256);
        imwrite(imind,cm,'demo2.gif','gif','WriteMode','append','DelayTime',DelayTime);
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    全部图片

    展示一下全部的图片都有哪些:

    [Y,X]=meshgrid(5:-1:1,1:8);
    scatterCanD(X,Y,1:40,.8);
    axis tight off
    
    • 1
    • 2
    • 3


    更换图片

    更换素材包内图片用的代码也非常简单:

    for i=1:14
        [C,~,A]=imread(['c (',num2str(i),').png']);
        C(:,:,1)=flipud(C(:,:,1));
        C(:,:,2)=flipud(C(:,:,2));
        C(:,:,3)=flipud(C(:,:,3));
    %     C=imgaussfilt(C,3);
        CanD_C{i}=C;
        CanD_A{i}=flipud(A);
    end
    author=char([20316 32773 58 32 115 108 97 110 100 97 114 101 114]);
    save CanD2.mat CanD_C CanD_A author
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    需要当前文件夹有c (i).png为名字的图片,可以改一些有意思的东西比如羊了个羊:


    完整代码及素材包:

    链接:https://pan.baidu.com/s/12PL0MhS0ytWktaUk0DRJ0A?pwd=slan
    提取码:slan

  • 相关阅读:
    Appium 点击操作梳理
    Linux基础——ELK Stack
    android so载入过程
    数值优化:经典一阶确定性算法及其收敛性分析
    NSS [HXPCTF 2021]includer‘s revenge
    力扣刷题19-删除链表的倒数第N个节点
    你们天天说的应用性能监控: Sky Walking
    计算机毕设 基于大数据的服务器数据分析与可视化系统 -python 可视化 大数据
    SpringBoot+Vue实现前后端分离的汽车配件销售管理系统
    京东二面:ElasticSearch如何解决深分页问题?
  • 原文地址:https://blog.csdn.net/slandarer/article/details/127830891