凯鲁嘎吉
用书写铭记日常,最迷人的不在远方
posts - 291,comments - 409,views - 138万
回到顶部(go to top)

MATLAB实例:截断坐标轴(Broken Axis)

作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/

更多请看:随笔分类 - MATLAB作图

    有时候,用MATLAB绘制坐标图时会出现有的曲线值都特别大,有的曲线值都很小,但是又想在同一幅图中将他们展示出来,于是需要截断坐标轴的刻度或者改变纵轴的刻度,使其不均匀。本博客写了截断横坐标纵坐标,以及横纵坐标都截断的实例(基本思路是超过截断位置的曲线通通向下或向左平移,在坐标轴上加双斜杠,最后只截取平移后位置之前的曲线,其余部分抛弃掉),并给出了mathworks上两个函数的实例,同时,纵轴刻度不均匀采用对数刻度来解决,也给出了相应的实例,一起看看效果。

1. 原始图像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
clear; clc; close all;
% 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/
% 原始图片
data=[2.3   2.1 1.9 1.8 1.7 1.7 1.7 1.7 1.7 1
3   2.5 2.1 2   1.9 1.9 1.9 1.9 1.9 1.2
3.4 3.3 3.2 3.1 3   3   3   3   3   2.5
10.8    10.6    10.5    10.2    10.1    10.1    10.1    10.1    10.1    9.1
];
x_min=0.1; %横坐标刻度最小值
x_interval=0.1; %横坐标刻度间隔距离
x_max=1; %横坐标刻度最大值
 
X=x_min:x_interval:x_max;
h=plot(X, data(1, :), 'k*-', X, data(2, :), 'g^-', X, data(3, :), 'r-s', X, data(4, :), 'b-x', 'MarkerFaceColor','y', 'MarkerSize',7);
 
set(gcf,'color','w') %后面背景变白
 
xlim([x_min x_max]); %横坐标范围
xlabel('x');
string='y';
ylabel(string);
legend('Line-1', 'Line-2', 'Line-3', 'Line-4', 'Location', 'east');  %图例
saveas(gcf,sprintf('Original image.jpg'),'bmp'); %保存图片

2. 截断横坐标

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
52
53
clear; clc; close all;
% 横轴截断后图像
% 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/
% 数据
format short g
data=[2.3   2.1 1.9 1.8 1.7 1.7 1.7 1.7 1.7 1
3   2.5 2.1 2   1.9 1.9 1.9 1.9 1.9 1.2
3.4 3.3 3.2 3.1 3   3   3   3   3   2.5
10.8    10.6    10.5    10.2    10.1    10.1    10.1    10.1    10.1    9.1
];
% 参数设置
x_min=0.1; %横轴刻度最小值
x_interval=0.1;  %横坐标两个刻度间隔距离
x_break_start=0.5; % 截断的开始值
x_break_end=0.9; % 截断的结束值
 
x_break_end=x_break_end-x_interval;
x_max=length(data(1, :))*x_interval+x_min-x_interval; %横轴刻度最大值
X=x_min:x_interval:x_max;
adjust_value=0.4*x_interval; %微调截断处x坐标
 
% 超过截断结束位置的那些曲线统统向左平移uptate_num个长度
data(:, find(abs(X-x_break_start)<eps)+1:(end-round((x_break_end-x_break_start)/x_interval)))=data(:, X>x_break_end+eps);
 
x_max_new=x_max-x_break_end+x_break_start;
X=x_min:x_interval:x_max_new;
new_range=round(x_max_new/x_interval);
% 根据曲线的个数进行修改,这里曲线是4条
h=plot(X, data(1, 1:new_range), 'k*-', X, data(2, 1:new_range), 'g^-', X, data(3, 1:new_range), 'r-s', X, data(4, 1:new_range), 'b-x', 'MarkerFaceColor','y', 'MarkerSize',7);
 
set(gcf,'color','w') %后面背景变白
 
xlim([x_min x_max_new]); %横坐标范围
xlabel('x');
string='y';
ylabel(string);
legend('Line-1', 'Line-2', 'Line-3', 'Line-4''Location', 'east');  %图例 根据曲线个数修改
 
% 横坐标截断设置
xlimit=get(gca,'xlim');
location_X=(x_break_start+adjust_value-xlimit(1))/diff(xlimit);
t1=text(location_X, 0,'//','sc','BackgroundColor','w','margin',eps, 'fontsize',13);
t2=text(location_X, 1,'//','sc','BackgroundColor','w','margin',eps, 'fontsize',13);
 
% 重新定义横坐标刻度
xtick=x_min:x_interval:x_max_new;
set(gca,'xtick',xtick);
xtick(xtick>x_break_start+eps)=xtick(xtick>x_break_start+eps)+x_break_end-x_break_start;
for i=1:length(xtick)
   xticklabel{i}=sprintf('%.1f',xtick(i));
end
set(gca,'xTickLabel', xticklabel, 'FontSize', 12, 'FontName', 'Times New Roman'); %修改坐标名称、字体
saveas(gcf,sprintf('Break_X_Axis.jpg'),'bmp'); %保存图片

3. 截断纵坐标

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
52
53
54
55
56
57
clear; clc; close all;
% 纵轴截断后图像
% 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/
% 数据
data=[2.3   2.1 1.9 1.8 1.7 1.7 1.7 1.7 1.7 1
3   2.5 2.1 2   1.9 1.9 1.9 1.9 1.9 1.2
3.4 3.3 3.2 3.1 3   3   3   3   3   2.5
10.8    10.6    10.5    10.2    10.1    10.1    10.1    10.1    10.1    9.1
];
% 参数设置
x_min=0.1; %横坐标刻度最小值
x_interval=0.1; %横坐标刻度间隔距离
x_max=1; %横坐标刻度最大值
y_interval=1;  %纵坐标两个刻度间隔距离
y_max=11; %纵轴刻度最大值
y_break_start=4; % 截断的开始值
y_break_end=9; % 截断的结束值
 
X=x_min:x_interval:x_max;
adjust_value=0.4*y_interval; %微调截断处y坐标
uptate_num=y_break_end-y_break_start-y_interval; %最高处曲线向下平移大小
 
% 超过截断结束位置的那些曲线统统向下平移uptate_num个长度
for i=1:length(data(:, 1))
    if data(i, :)>y_break_end
        data(i, :)=data(i, :)-uptate_num;
    end
end
 
% 根据曲线的个数进行修改,这里曲线是4条
h=plot(X, data(1, :), 'k*-', X, data(2, :), 'g^-', X, data(3, :), 'r-s', X, data(4, :), 'b-x', 'MarkerFaceColor','y', 'MarkerSize',7);
 
set(gcf,'color','w') %后面背景变白
 
xlim([x_min x_max]); %横坐标范围
xlabel('x');
string='y';
ylabel(string);
legend('Line-1', 'Line-2', 'Line-3', 'Line-4''Location', 'east');  %图例 根据曲线个数修改
 
% 纵坐标截断设置
ylimit=get(gca,'ylim');
location_Y=(y_break_start+adjust_value-ylimit(1))/diff(ylimit);
t1=text(0, location_Y,'//','sc','BackgroundColor','w','margin',eps, 'fontsize',13);
set(t1,'rotation',90);
t2=text(1, location_Y,'//','sc','BackgroundColor','w','margin',eps, 'fontsize',13);
set(t2,'rotation',90);
 
% 重新定义纵坐标刻度
ytick=0:y_interval:y_max;
set(gca,'ytick',ytick);
ytick(ytick>y_break_start+eps)=ytick(ytick>y_break_start+eps)+uptate_num;
for i=1:length(ytick)
   yticklabel{i}=sprintf('%d',ytick(i));
end
set(gca,'yTickLabel', yticklabel, 'FontSize', 12, 'FontName', 'Times New Roman'); %修改坐标名称、字体
saveas(gcf,sprintf('Break_Y_Axis.jpg'),'bmp'); %保存图片

4. 截断横纵坐标

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
clear; clc; close all;
% 横轴截断后图像
% 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/
% 数据
data=[2.3   2.1 1.9 1.8 1.7 1.7 1.7 1.7 1.7 1
3   2.5 2.1 2   1.9 1.9 1.9 1.9 1.9 1.2
3.4 3.3 3.2 3.1 3   3   3   3   3   2.5
10.8    10.6    10.5    10.2    10.1    10.1    10.1    10.1    10.1    9.1
];
% 参数设置
x_min=0.1; %横轴刻度最小值
x_interval=0.1;  %横坐标两个刻度间隔距离
x_break_start=0.5; % 截断的开始值
x_break_end=0.9; % 截断的结束值
y_interval=1;  %纵坐标两个刻度间隔距离
y_max=11; %纵轴刻度最大值
y_break_start=4; % 截断的开始值
y_break_end=9; % 截断的结束值
 
x_break_end=x_break_end-x_interval;
x_max=length(data(1, :))*x_interval+x_min-x_interval; %横轴刻度最大值
X=x_min:x_interval:x_max;
adjust_value_x=0.4*x_interval; %微调截断处x坐标
adjust_value_y=0.4*y_interval; %微调截断处y坐标
uptate_num=y_break_end-y_break_start-y_interval; %最高处曲线向下平移大小
 
% 超过截断结束位置的那些曲线统统向左平移uptate_num个长度
data(:, find(abs(X-x_break_start)<eps)+1:(end-round((x_break_end-x_break_start)/x_interval)))=data(:, X>x_break_end+eps);
% 超过截断结束位置的那些曲线统统向下平移uptate_num个长度
for i=1:length(data(:, 1))
    if data(i, :)>y_break_end
        data(i, :)=data(i, :)-uptate_num;
    end
end
 
x_max_new=x_max-x_break_end+x_break_start;
X=x_min:x_interval:x_max_new;
new_range=round(x_max_new/x_interval);
% 根据曲线的个数进行修改,这里曲线是4条
h=plot(X, data(1, 1:new_range), 'k*-', X, data(2, 1:new_range), 'g^-', X, data(3, 1:new_range), 'r-s', X, data(4, 1:new_range), 'b-x', 'MarkerFaceColor','y', 'MarkerSize',7);
 
set(gcf,'color','w') %后面背景变白
 
xlim([x_min x_max_new]); %横坐标范围
xlabel('x');
string='y';
ylabel(string);
legend('Line-1', 'Line-2', 'Line-3', 'Line-4''Location', 'east');  %图例 根据曲线个数修改
 
% 横坐标截断设置
xlimit=get(gca,'xlim');
location_X=(x_break_start+adjust_value_x-xlimit(1))/diff(xlimit);
t1=text(location_X, 0,'//','sc','BackgroundColor','w','margin',eps, 'fontsize',13);
t2=text(location_X, 1,'//','sc','BackgroundColor','w','margin',eps, 'fontsize',13);
 
% 重新定义横坐标刻度
xtick=x_min:x_interval:x_max_new;
set(gca,'xtick',xtick);
xtick(xtick>x_break_start+eps)=xtick(xtick>x_break_start+eps)+x_break_end-x_break_start;
for i=1:length(xtick)
   xticklabel{i}=sprintf('%.1f',xtick(i));
end
 
% 纵坐标截断设置
ylimit=get(gca,'ylim');
location_Y=(y_break_start+adjust_value_y-ylimit(1))/diff(ylimit);
t1=text(0, location_Y,'//','sc','BackgroundColor','w','margin',eps, 'fontsize',13);
set(t1,'rotation',90);
t2=text(1, location_Y,'//','sc','BackgroundColor','w','margin',eps, 'fontsize',13);
set(t2,'rotation',90);
 
% 重新定义纵坐标刻度
ytick=0:y_interval:y_max;
set(gca,'ytick',ytick);
ytick(ytick>y_break_start+eps)=ytick(ytick>y_break_start+eps)+uptate_num;
for i=1:length(ytick)
   yticklabel{i}=sprintf('%d',ytick(i));
end
 
set(gca,'xTickLabel', xticklabel, 'yTickLabel', yticklabel, 'FontSize', 12, 'FontName', 'Times New Roman'); %修改坐标名称、字体
saveas(gcf,sprintf('Break_X_Y_Axis.jpg'),'bmp'); %保存图片

    如果改变截断参数值导致程序运行不出来,多半是逻辑运算符出的Bug,所以我在X>x_break_end+eps这种不等判断后加了eps,等式判断符X==x_break_start出Bug改为(X-x_break_start)<eps。欢迎一起交流学习~

5. 别人家的程序

    在mathworks官网找了两个程序,分别截断横坐标与纵坐标,但还没有同时截断这两个的程序。而且,使用了这两个函数之后,图例显式竟然变暗了,不知道是什么原因,一起看看效果。

    代码来源:www.mathworks.com/matlabcentral/fileexchange/42905-break-x-axiswww.mathworks.com/matlabcentral/fileexchange/45760-break-y-axis

breakxaxis.m

breakyaxis.m

demo.m

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
clear; clc; close all;
% 纵轴截断后图像
% 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/
% 数据
data=[2.3   2.1 1.9 1.8 1.7 1.7 1.7 1.7 1.7 1
3   2.5 2.1 2   1.9 1.9 1.9 1.9 1.9 1.2
3.4 3.3 3.2 3.1 3   3   3   3   3   2.5
10.8    10.6    10.5    10.2    10.1    10.1    10.1    10.1    10.1    9.1
];
% 参数设置
x_min=0.1; %横坐标刻度最小值
x_interval=0.1; %横坐标刻度间隔距离
x_max=1; %横坐标刻度最大值
 
X=x_min:x_interval:x_max;
h=plot(X, data(1, :), 'k*-', X, data(2, :), 'g^-', X, data(3, :), 'r-s', X, data(4, :), 'b-x', 'MarkerFaceColor','y', 'MarkerSize',7);
 
set(gcf,'color','w') %后面背景变白
 
xlim([x_min x_max]); %横坐标范围
xlabel('x');
string='y';
ylabel(string);
legend('Line-1', 'Line-2', 'Line-3', 'Line-4', 'Location','northoutside', 'NumColumns',4);  %图例
% 调用已有的代码,两个函数只能调用一个,不能同时调用,出错
breakyaxis([4 9]);  % 截断纵坐标
% breakxaxis([0.5 0.9]);  %截断横坐标
saveas(gcf,sprintf('Other_Break_Axis.jpg'),'bmp'); %保存图片

6. 纵轴刻度值不均匀

    如果想要纵轴刻度值不均匀,可以在plot();后面加一句set(gca,'yscale','log')即可,但是对于不是对数取值的图像来说,效果并不是很好,如下图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
clear; clc; close all;
% 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/
% 原始图片
data=[2.3   2.1 1.9 1.8 1.7 1.7 1.7 1.7 1.7 1
3   2.5 2.1 2   1.9 1.9 1.9 1.9 1.9 1.2
3.4 3.3 3.2 3.1 3   3   3   3   3   2.5
10.8    10.6    10.5    10.2    10.1    10.1    10.1    10.1    10.1    9.1
];
x_min=0.1; %横坐标刻度最小值
x_interval=0.1; %横坐标刻度间隔距离
x_max=1; %横坐标刻度最大值
 
X=x_min:x_interval:x_max;
h=plot(X, data(1, :), 'k*-', X, data(2, :), 'g^-', X, data(3, :), 'r-s', X, data(4, :), 'b-x', 'MarkerFaceColor','y', 'MarkerSize',7);
set(gca,'yscale','log')
set(gcf,'color','w') %后面背景变白
 
xlim([x_min x_max]); %横坐标范围
xlabel('x');
string='y';
ylabel(string);
legend('Line-1', 'Line-2', 'Line-3', 'Line-4', 'Location','northoutside', 'NumColumns',4);  %图例
saveas(gcf,sprintf('Log image.jpg'),'bmp'); %保存图片

posted on   凯鲁嘎吉  阅读(11671)  评论(2编辑  收藏  举报
编辑推荐:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
阅读排行:
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!
· 用 C# 插值字符串处理器写一个 sscanf

点击右上角即可分享
微信分享提示