Matlab实现生成箭头坐标轴详解

 更新时间:2022年03月17日 10:05:47   作者:slandarer  
这篇文章主要介绍了如何利用Matlab实现生成箭头坐标轴,为坐标轴增添箭头,文中的示例代码讲解详细,对我们学习Matlab有一定帮助,需要的可以参考一下

属实是写工具函数写上瘾了,又写了一个一行代码将坐标轴变为箭头坐标轴的函数,而且可以对其进行随意拖动和缩放(拖动需要先点击那个像手掌的符号):

功能函数的引用非常简单,就只是在最后面加上一行:

arrowAxes()或者arrowAxes(ax)

即可,以下给出几个例子:

demo1 基础使用

就像上面说的一样,编写好代码后在最后面引用一下工具函数即可:

% arrow axes demo1
% @author:slandarer

t=-pi:.2:2*pi;
stem(t,sin(t),'LineWidth',1.5);

arrowAxes()

demo2 轴方向

可以调整坐标区域的XAxisLocation属性及YAxisLocation属性来调整坐标轴的方向和位置,总共有九种组合,篇幅问题这里不一一列举

这里只列举常用的四种:

% arrow axes demo2
% @author:slandarer

t=-pi:.2:2*pi;


% 子图1
ax1=subplot(2,2,1);
plot(t,sin(t),'LineWidth',1.5);
arrowAxes(ax1)

% 子图2
ax2=subplot(2,2,2);
plot(t,sin(t),'LineWidth',1.5);
ax2.XAxisLocation='top';
ax2.YAxisLocation='right';
arrowAxes(ax2)

% 子图3
ax3=subplot(2,2,3);
plot(t,sin(t),'LineWidth',1.5);
ax3.XAxisLocation='origin';
arrowAxes(ax3)

% 子图4
ax4=subplot(2,2,4);
plot(t,sin(t),'LineWidth',1.5);
ax4.XAxisLocation='origin';
ax4.YAxisLocation='origin';
arrowAxes(ax4)

demo3 轴的其他属性

在引用工具函数前调整坐标轴的粗细和颜色,引用工具函数时,工具函数会自动提取坐标轴的属性并赋予箭头坐标轴:

% arrow axes demo3
% @author:slandarer

t=-pi:.2:2*pi;
stem(t,sin(t),'LineWidth',1.5);

% 修改坐标轴属性
ax=gca;
ax.XColor=[1,0,0];
ax.LineWidth=2;
ax.XAxisLocation='origin';

arrowAxes(ax)

后言

不管画多少子图,怎样的轴方向和位置,每个子图都能像如下这样任意调整坐标范围和图像缩放。

工具函数完整代码

function arrowAxes(ax)
%
% @author: slandarer
% @公众号: slandarer随笔
% @知乎  : hikari
% @CSDN  : slandarer
% 
% 期待您的关注!!!

help arrowAxes % 若不希望输出[作者信息],请删除这行


if nargin<1
    ax=gca;
end

ax.Box='off';
ax.UserData.arrow{1}=[];
ax.UserData.arrow{2}=[];
ax.UserData.arrow{3}=[];
ax.UserData.arrow{4}=[];

pos=ax.Position;
xm=.02;
ym=.02;
% -------------------------------------------------------------------------
switch ax.XAxisLocation
    case 'bottom'
        ax.UserData.arrow{2}=annotation('arrow');
        ax.UserData.arrow{2}.Color=ax.YColor;
        ax.UserData.arrow{2}.Position=[pos(1),pos(2),0,pos(4)+ym];
    case 'top'
        ax.UserData.arrow{4}=annotation('arrow');
        ax.UserData.arrow{4}.Color=ax.YColor;
        ax.UserData.arrow{4}.Position=[pos(1),pos(2)+pos(4),0,-pos(4)-ym];
    case 'origin'
        ax.UserData.arrow{2}=annotation('arrow');
        ax.UserData.arrow{2}.Color=ax.YColor;
        ax.UserData.arrow{2}.Position=[pos(1),pos(2),0,pos(4)+ym];
        ax.UserData.arrow{4}=annotation('arrow');
        ax.UserData.arrow{4}.Color=ax.YColor;
        ax.UserData.arrow{4}.Position=[pos(1),pos(2)+pos(4),0,-pos(4)-ym];
end
switch ax.YAxisLocation
    case 'left'
        ax.UserData.arrow{1}=annotation('arrow');
        ax.UserData.arrow{1}.Color=ax.XColor;
        ax.UserData.arrow{1}.Position=[pos(1),pos(2),pos(3)+xm,0];
    case 'right'
        ax.UserData.arrow{3}=annotation('arrow');
        ax.UserData.arrow{3}.Color=ax.XColor;
        ax.UserData.arrow{3}.Position=[pos(1)+pos(3),pos(2),-pos(3)-xm,0];
    case 'origin'
        ax.UserData.arrow{1}=annotation('arrow');
        ax.UserData.arrow{1}.Color=ax.XColor;
        ax.UserData.arrow{1}.Position=[pos(1),pos(2),pos(3)+xm,0];
        ax.UserData.arrow{3}=annotation('arrow');
        ax.UserData.arrow{3}.Color=ax.XColor;
        ax.UserData.arrow{3}.Position=[pos(1)+pos(3),pos(2),-pos(3)-xm,0];
end

if strcmp(ax.XAxisLocation,'top')
    if ~isempty(ax.UserData.arrow{1}),ax.UserData.arrow{1}.Position=[pos(1),pos(2)+pos(4),pos(3)+xm,0];end
    if ~isempty(ax.UserData.arrow{3}),ax.UserData.arrow{3}.Position=[pos(1)+pos(3),pos(2)+pos(4),-pos(3)-xm,0];end
end
if strcmp(ax.YAxisLocation,'right')
    if ~isempty(ax.UserData.arrow{2}),ax.UserData.arrow{2}.Position=[pos(1)+pos(3),pos(2),0,pos(4)+ym];end
    if ~isempty(ax.UserData.arrow{4}),ax.UserData.arrow{4}.Position=[pos(1)+pos(3),pos(2)+pos(4),0,-pos(4)-ym];end
end
for i=1:4
    if ~isempty(ax.UserData.arrow{i}),ax.UserData.arrow{i}.LineWidth=ax.LineWidth;end
end


reArrow()
% -------------------------------------------------------------------------
function reArrow(~,~)
if strcmp(ax.XAxisLocation,'origin')
    pos=ax.Position;
    ylim=ax.YLim;
    sepy=(0-ylim(1))./(ylim(2)-ylim(1)).*pos(4);
    switch true
        case ylim(2)<=0
            if ~isempty(ax.UserData.arrow{1}),ax.UserData.arrow{1}.Position=[pos(1),pos(2)+pos(4),pos(3)+xm,0];end
            if ~isempty(ax.UserData.arrow{3}),ax.UserData.arrow{3}.Position=[pos(1)+pos(3),pos(2)+pos(4),-pos(3)-xm,0];end
        case ylim(1)>=0
            if ~isempty(ax.UserData.arrow{1}),ax.UserData.arrow{1}.Position=[pos(1),pos(2),pos(3)+xm,0];end
            if ~isempty(ax.UserData.arrow{3}),ax.UserData.arrow{3}.Position=[pos(1)+pos(3),pos(2),-pos(3)-xm,0];end
        case ylim(2)>0&ylim(1)<0
            if ~isempty(ax.UserData.arrow{1}),ax.UserData.arrow{1}.Position=[pos(1),pos(2)+sepy,pos(3)+xm,0];end
            if ~isempty(ax.UserData.arrow{3}),ax.UserData.arrow{3}.Position=[pos(1)+pos(3),pos(2)+sepy,-pos(3)-xm,0];end
    end
end
if strcmp(ax.YAxisLocation,'origin')
    pos=ax.Position;
    xlim=ax.XLim;
    sepx=(0-xlim(1))./(xlim(2)-xlim(1)).*pos(3);
    switch true
        case xlim(2)<=0
            if ~isempty(ax.UserData.arrow{2}),ax.UserData.arrow{2}.Position=[pos(1)+pos(3),pos(2),0,pos(4)+ym];end
            if ~isempty(ax.UserData.arrow{4}),ax.UserData.arrow{4}.Position=[pos(1)+pos(3),pos(2)+pos(4),0,-pos(4)-ym];end
        case xlim(1)>=0
            if ~isempty(ax.UserData.arrow{2}),ax.UserData.arrow{2}.Position=[pos(1),pos(2),0,pos(4)+ym];end
            if ~isempty(ax.UserData.arrow{4}),ax.UserData.arrow{4}.Position=[pos(1),pos(2)+pos(4),0,-pos(4)-ym];end
        case xlim(2)>0&xlim(1)<0
            if ~isempty(ax.UserData.arrow{2}),ax.UserData.arrow{2}.Position=[pos(1)+sepx,pos(2),0,pos(4)+ym];end
            if ~isempty(ax.UserData.arrow{4}),ax.UserData.arrow{4}.Position=[pos(1)+sepx,pos(2)+pos(4),0,-pos(4)-ym];end
    end
end
end
set(ax.Parent,'WindowButtonMotionFcn',@reArrow);  % 设置鼠标按下回调
end

到此这篇关于Matlab实现生成箭头坐标轴详解的文章就介绍到这了,更多相关Matlab箭头坐标轴内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Cocos2d-x学习笔记之Hello World源码分析

    Cocos2d-x学习笔记之Hello World源码分析

    这篇文章主要介绍了Cocos2d-x学习笔记之Hello World源码分析,接上一篇内容,本文着重分析源码文件,需要的朋友可以参考下
    2014-09-09
  • C语言实现简易文本编译器

    C语言实现简易文本编译器

    这篇文章主要为大家详细介绍了C语言实现简易文本编译器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • C语言完整实现12种排序算法(小结)

    C语言完整实现12种排序算法(小结)

    本文主要介绍了C语言完整实现12种排序算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • c++标准库读写ini文件的实现示例

    c++标准库读写ini文件的实现示例

    本文介绍了一个完整的INI文件类的实现,包含读取和写入操作,通过IniFile.h头文件和IniFile.cpp实现文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-10-10
  • 深入理解c/c++ 内存对齐

    深入理解c/c++ 内存对齐

    这篇文章主要介绍了c/c++ 内存对齐,有需要的朋友可以参考一下
    2014-01-01
  • 详细了解C语言二叉树的建立与遍历

    详细了解C语言二叉树的建立与遍历

    这篇文章主要介绍了C中二叉树的建立和各种遍历实例代码,涉及树节点的定义,后序遍历,层序遍历,深度优先和广度优先等相关内容,具有一定借鉴价值,需要的朋友可以参考下
    2021-07-07
  • OpenCV计算图像的水平和垂直积分投影

    OpenCV计算图像的水平和垂直积分投影

    这篇文章主要为大家详细介绍了OpenCV计算图像的水平和垂直积分投影,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • 用位图排序无重复数据集实例代码(C++版)

    用位图排序无重复数据集实例代码(C++版)

    本文讲解如何用位图排序无重复的数据集,我们使用C++实现一下这个方法
    2013-11-11
  • 深入讲解C++中的构造函数

    深入讲解C++中的构造函数

    这篇文章主要介绍了C++中的构造函数,是C++入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • C++详细讲解函数调用与Struct和CLass的区别

    C++详细讲解函数调用与Struct和CLass的区别

    主调函数使用被调函数的功能,称为函数调用。在C语言/C++中,只有在函数调用时,函数体中定义的功能才会被执行,下面让我们详细来了解
    2022-05-05

最新评论