Subplot_In_Matlab中多图绘制之subplot函数
基于子图的多图方法
专业的论文中通常涉及到多个有逻辑关系的图拼接在一起,构成相互支持或者对照。所以很早之前,Matlab就有这个子图的函数subplot
。
这个函数的基本语义有三类:
- 在图窗上划分出一个矩形区域建立一个坐标系,并指定该坐标系为当前坐标系
- 把一个坐标系替换成另外一个坐标系,并指定为当前坐标系
- 把一个坐标系指定为当前坐标系
因为Matlab的绘图指令可以忽略坐标系参数,并利用gca
函数获取当前坐标系。所以当运行上述子图函数后,后续不指定坐标系的绘图指令就会在指定的坐标系上进行。
基于格子的多图方法
1% 基本的子图:利用subplot函数,并用函数语法画图
2figure;
3% 1. 画一个2x2的子图
4subplot(2,2,1);
5plot(1:10,1:10);
6title('1');
7
8subplot(2,2,2);
9plot(1:10,1:10);
10title('2');
11
12subplot(2,2,3);
13plot(1:10,1:10);
14title('3');
15
16subplot(2,2,4);
17plot(1:10,1:10);
18title('4');
简单的说,子图的编号采取了行先的方式,下面给出一个循环的例子,可以看到,图号按照n * (i-1) + j
的方式编号,其中n
是行数,i
是行号,j
是列号。
1figure;
2
3m = 2; % 行数
4n = 3; % 列数
5
6for row = 1:m
7 for col = 1:n
8 idx = (row-1)*n + col;
9 subplot(m,n,idx);
10 plot(1:10,1:10);
11 title(['子图编号' num2str(idx)]);
12 end
13end
实际上,子图可以拼凑在一起,比如下面这个例子中,把第一行的两个图绘制完成后;再创建一个两行一列的图,把第二行的子图作为一个子图。就形成了三个子图的图像。
1% 稍微复杂的子图:利用subplot函数,并用函数语法画图
2figure;
3% 1. 画一个2x2的子图
4ax1 = subplot(2,2,1);
5plot(ax1,1:10,1:10);
6title(ax1,'1');
7
8ax2 = subplot(2,2,2);
9plot(ax2,1:10,1:10);
10title(ax2,'2');
11
12% 一个2x1的格子,横跨两列的子图
13ax3 = subplot(2,1,2);
14plot(ax3,1:10,1:10);
15title(ax3,'3');
当然,从下面的例子可以看到,当有两个子图发生重叠时,就把先绘制的那个子图删除替换成新的子图。这里,先把第一行的两个子图绘制完成后,再绘制第二列的一个子图,这样就把第一行的第二个子图删除了。当然,左下角子图也可以顺利添加进来。
1% 稍微复杂的子图:利用subplot函数,并用函数语法画图
2figure;
3% 1. 画一个2x2的子图
4ax1 = subplot(2,2,1);
5plot(ax1,1:10,1:10);
6title(ax1,'1');
7
8ax2 = subplot(2,2,2);
9plot(ax2,1:10,1:10);
10title(ax2,'2');
11
12% 一个1x2的格子,横跨两列的子图(删除了2,2,2对应的坐标系)
13ax3 = subplot(1,2,2);
14plot(ax3,1:10,1:10);
15title(ax3,'3');
16
17ax4 = subplot(2,2,3);
18plot(ax4,1:10,1:10);
19title(ax4,'4');
按照位置的多图方法
除了按照简单的行先编号的方式来创建子图坐标系,还可以直接设定子图的位置和大小还创建坐标系,这里就可以使用Position
属性来设置子图,跟所有的Position
属性一样,这里的位置包括了左下角的位置、宽度和高度。当然,这里采用的单位是归一化的单位,也就是左下角为(0, 0)
,右上角为(1, 1)
。
1figure;
2ax1 = subplot("Position", [0.1 0.1 0.4 0.4]);
3plot(1:10,1:10);
4title('1');
5
6ax2 = subplot("Position", [0.5 0.5 0.3 0.3]);
7plot(1:10,1:10);
8title('2');
9
10ax3 = subplot("Position", [0.8 0.8 0.1 0.1]);
11plot(1:10,1:10);
12title('3');
这里有同样的问题,把上面脚本中子图坐标系的位置稍微调整一下就会发现,当有两个图重叠时,后绘制的图会把先绘制的图覆盖掉。
图中图的实现方法
当然,我知道你们在想什么,那么怎么绘制多个图,相互交叉(例如绘制部分放大图)呢?这就是图中图(画中画)的概念。要实现这个也很简单。
直接调整子图坐标系
那这样一想,我们能不能先分块创建子图坐标系,然后在调整Position
属性来调整子图的位置呢?当然可以,下面的例子就是这样做的。
1figure;
2ax1 = subplot(2,2,1);
3plot(1:10,1:10);
4title('1');
5
6ax2 = subplot(2,2,2);
7plot(1:10,1:10);
8title('2');
9
10ax3 = subplot(2,2,3);
11plot(1:10,1:10);
12title('3');
13
14ax4 = subplot(2,2,4);
15plot(1:10,1:10);
16title('4');
17
18
19ax1.Position = [0.15, 0.5, 0.5, 0.3];
20ax2.Position = [0.75, 0.5, 0.2, 0.3];
21ax3.Position = [0.1, 0.1, 0.8, 0.8];
22ax3.Color = 'none';
创建子图坐标系
是否可以直接创建子图坐标系呢?当然可以,下面的例子就是这样做的。
只需要把subplot
换成axes
就可以,这个时候,就按照位置定位的方式来创建坐标系,通过把坐标系的背景颜色设置为none
,就能把一个坐标系设定为透明。下面比较了是否设置为透明的效果。
1f = figure;
2ax1 = axes("Position", [0.1 0.1 0.4 0.4]);
3plot(1:10,1:10);
4title('1');
5
6
7
8ax2 = axes("Position", [0.45 0.45 0.3 0.3], 'Color', 'y');
9plot(1:10,1:10);
10title('2');
11
12ax3 = axes("Position", [0.7 0.7 0.1 0.1], 'Color', 'g');
13plot(1:10,1:10);
14title('3');
15
16ax4 = axes("Position", [0.2 0.2 0.7 0.7]);
17x = 0:0.01:2*pi;
18y = sin(x);
19plot(x, y);
20title('4');
21
22
23ax1.Color = 'r';
24ax2.Color = 'g';
25ax3.Color = 'y';
26ax4.Color = 'none';
27
28exportgraphics(f, 'colors.png');
严肃一点,我们真正的做一个图中图,也就是对一个图的局部进行放大。
1x = 0:0.01:2*pi;
2y = sin(x);
3
4% 绘制一个图像
5figure;
6plot(x, y);
7xlabel('x');
8ylabel('y');
9title('y = sin(x)');
10
11% 增加一个坐标在pi/2处的放大图
12
13ax1 = axes("Position", [0.6 0.6 0.2 0.2]);
14idx = x >= pi/2-0.1 & x <= pi/2+0.1;
15plot(x(idx), y(idx));
16title('Zoomed view', Color='r');
17xlim([pi/2-0.1, pi/2+0.1]);
18ylim([0.9, 1.1]);
19
20% 绘制一个箭头,指向放大区域
21annotation('arrow', X=[0.58 0.35], Y=[0.75 0.9]);
22annotation('rectangle', [0.285 0.9 0.05 0.05]);
这里比较烦人的就是要手动调整标注(箭头、方框)的位置,而且这个坐标是针对整个图的,不是针对子图的,也就是左小角坐标是(0,0)
,右上角坐标(1,1)
,宽度和高度的范围都是[0, 1]
。
新的多图方法预告
从2022b开始就,一种新的、更加清晰的多图方法出现了。后面再写一个文章详细介绍这个方法。
文章标签
|-->matlab |-->tutorial |-->figure |-->subplot
- 本站总访问量:次
- 本站总访客数:人
- 可通过邮件联系作者:Email大福
- 也可以访问技术博客:大福是小强
- 也可以在知乎搞抽象:知乎-大福
- Comments, requests, and/or opinions go to: Github Repository