文章目录
本博客主要记录一下如何用 Matlab 画图,以及一些画图的技巧。
Part.I 基础知识
Chap.I 传送门
下面是一些传送门:
- 主博客:Matlab 使用笔记
- Matlab 颜色、线型、标记符号和希腊字母表
- 利用 matlab 构建自己的 colormap
- colormap-contourf 函数
- 给 colorbar 加单位的几种方式
- Matlab 让多图排版更美观
Chap.II annotation函数
(1) annotation(annotation_type)
% 以指定的对象类型,使用默认属性值建立注释对象。
(2) annotation('line',x,y)
% 建立从(x(1), y(1))到(x(2), y(2))的线注释对象。
(3) annotation('arrow',x,y)
% 建立从(x(1), y(1))到(x(2), y(2))的箭头注释对象。
(4) annotation('doublearrow',x,y)
% 建立从(x(1), y(1))到(x(2), y(2))的双箭头注释对象。
(5) annotation('textarrow',x,y)
% 建立从(x(1),y(1))到(x(2),y(2))的带文本框的箭头注释对象
(6) annotation('textbox',[x y w h])
% 建立文本框注释对象,左下角坐标(x,y),宽w,高h.
(7) annotation('ellipse',[x y w h])
% 建立椭圆形注释对象。
(8) annotation('rectangle',[x y w h])
% 建立矩形注释对象。
(9) annotation(figure_handle,…)
% 在句柄值为figure_handle的图形窗口建立注释对象。
(10) annotation(…,'PropertyName',PropertyValue,…)
% 建立并设置注释对象的属性。
(11) anno_obj_handle = annotation(…)
% 返回注释对象的句柄值。
Chap.III Legend 终极使用
巧用 legend 函数主要可以实现下面的一些功能
- 图例横向排列(可设置图例的列数固定)
- 去掉图例边框
- 只显示部分图例
- 指定图例位置
data = rand(25)+repmat(1:25,25,1);
H = plot(data); %现在H中有25条线
h1=legend([H(2),H(4)],'2','4'); %部分图例显示:第2条,第4条
set(h1,'Orientation','horizon'); %横排
set(h1,'Box','off'); %不显示边框
legend('Location','SouthEast'); %位置显示在东南(右下)
legend('Location','Best'); %自动选择合适的位置
% 多图例
ah=axes('position',get(gca,'position'),'visible','off');
legend(p1,{legend_tick1},'FontSize',10,'Orientation','horizontal','Box','off','Location','Best');
legend(ah,p2,{legend_tick2},'FontSize',10,'Orientation','horizontal','Box','off','Location','Best');
用上面的代码绘图如下所示:
其实关于 location
,有如下选择:
位置 | 解释 |
---|---|
North | Inside plot box near top |
South | Inside bottom |
EastI | nside right |
West | Inside left |
NorthEast | Inside top right (default) |
NorthWest | Inside top left |
SouthEast | Inside bottom right |
SouthWest | Inside bottom left |
NorthOutside | Outside plot box near top |
SouthOutside | Outside bottom |
EastOutside | Outsideright |
WestOutside | Outside left |
NorthEastOutside | Outside top right |
NorthWestOutside | Outside top left |
SouthEastOutside | Outside bottom right |
SouthWestOutside | Outside bottom left |
Best | Least conflict with data in plot |
BestOutside | Least unused space outside plot |
横排指定列数:'NumColumns',10
legend(p,Name,'FontSize',8,'Orientation','horizontal','Box','off','Location','Best','NumColumns',10);
Chap.IV gcf、gca 和gco 的区别用法
补于2021.3.23
参考:Matlab_GUI gcf、gca 以及gco 的区别用法
https://blog.csdn.net/u013346007/article/details/54377602
目前对gco了解不是很多遍,它们三个的含义如下:
名称 | 含义 |
---|---|
gcf | 返回当前Figure 对象的句柄值 |
gca | 返回当前axes 对象的句柄值 |
gco | 返回当前鼠标单击的句柄值,该对象可以是除root 对象外的任意图形对象,并且Matlab 会把当前图形对象的句柄值存放在Figure 的CurrentObject属性中。 |
下面是笔者简单的理解:
gcf,gca,gco和ans一样,是matlab中的保留字,但又和ans不一样的地方是,它不会存在于workspace中,但是在command window中输入gcf(即使你之前没有调用过figure),它就会返回一个值,这个值就指向一个figure。
句柄就相当于C中的指针(C中也有句柄好像,奈何笔者只是个半吊子C程序编写者,对句柄的理解还不是很到位)比如笔者运行一个figure
指令,那么此时的gcf
就会指向这个figure,然后gca就指向这个figure的坐标系(这个figure中此时只有一个图,换句话说,就是只有一个坐标系),倘若笔者再调用指令subplot(2,1,2)
,那么此时gcf还是指向这个图,gca指向的是这个图中两行一列第二行的那个子图的坐标系;再调用指令subplot(3,1,1)
,那么此时gcf还是指向这个图,gca指向的是这个图中三行一列第一行的那个子图的坐标系。
Matlab这样的设计真实爽爆了,笔者可以调用函数画图,返回这个图的句柄gcf,然后,可以通过subpolt,gca修改图中元素,最后再通过gcf来保存这个图。非常方便,实用,非常nice!调用函数的时候一般不会直接返回gcf,而是返回一个其他的量,比如pgcf(主要是为了避免和gcf重名,为后续操作带来便利)。这样做的好处在于,我保留了figure1的句柄pgcf1,然后不影响我画其他的图,比如我再画个figure2,pgcf2=gcf
,然后我还想回来改figure1中的标注等,这时候就有妙用了gcf=pgcf1
,然后subplot,gca随便改。
这是笔者刚领悟到这点所码的,不知道笔者所言各位看懂没有,笔者刚产生这种想法,还没来得及实践,反正笔者当前很激动。
经实践,确实可行,只是要注意一点:换gcf之后,gca还停滞在之间的状态,这时候需要subplot一下,若换后的gcf中只有一个图,就subplot(1,1,1)
。
Chap.V 杂记
xticklabel 的旋转
实际上,xticklabel 并不能旋转,视觉上的旋转是通过text实现的。
set(gca,'xticklabel', '');
xt = get(gca, 'XTick');
yt = get(gca, 'YTick');
xtextp = xt;
ytextp = (-0.01*(yt(end)-yt(1)) + yt(1)) * ones(1, length(xt));
text(xtextp, ytextp, satc, 'HorizontalAlignment', 'right', 'rotation', 30, 'fontsize', 10);
//字体
%set(gca,'FontName','Times New Roman','FontSize',14,'FontWeight','bold','FontAngle','italic' )%设置坐标轴刻度字体名称,大小,加粗 ,斜体;
title('图形名称') //(都放在单引号内)
xlabel('x轴说明')
ylabel('y轴说明')
text(x,y,'图形说明')
legend('图例1','图例2',…)
//除legend函数外,其他函数同样适用于三维图形,在三维中z坐标轴说明用zlabel函数。
axis([xmin xmax ymin ymax zmin zmax])
axis equal //纵横坐标轴采用等长刻度
axis square //产生正方形坐标系(默认为矩形)
axis auto //使用默认设置
axis off //取消坐标轴
axis on //显示坐标轴
grid on/off //命令控制画还是不画网格线
box on/off //给坐标加边框还是不加边框
hold on/off //命令是保持原有图形还是刷新原有图形
//上述几个 不带参数 就是在两者之间切换
subplot(m,n,p)
/*该函数把当前窗口分成m×n个绘图区,m行,每行n个绘图区,
区号按行优先编号。其中第p个区为当前活动区。
每一个绘图区允许以不同的坐标系单独绘制图形。*/
上述函数中的说明文字,除了使用标准的ASCII字符外,还可以使用LaTex(一种流行的数学排版软件)格式的控制字符,这样就可以在图形上添加希腊字符,数学符号和公式等内容。在Matlab支持的LaTex字符串中,用/bf
, /it
, /rm
控制字符分别定义黑体、斜体和正体字符,受LaTex字符串控制部分要加大括号{}括起来。例如,text(0.3,0.5,'the usful {/bf MATLAB}')
,将使MATLAB一词黑体显示。一些常用的LaTex字符见表,各个字符可以单独使用也可以和其他字符及命令配合使用。如text(0.3,0.5,'sin({/omega}t+{/beta})')
Part.II 画图实例
Chap.I 传送门
下面是一些好用的传送门
Chap.II plot 函数画曲线图
plot(x,y); //其中x,y为长度相同的向量,存储x坐标和y坐标。
plot(x1,y1,x2,y2,…,xn,yn); //包含若干组向量对,每一组可以绘制出一条曲线.
//若x,y都是含有三列的矩阵,它们组成输入参数对,则绘制三条曲线;
plot(M); //M是一个m*n矩阵,绘图时以 列数 为x 坐标,以矩阵值为 y 坐标,绘制出 n 条曲线,每条曲线上有m 个点。
为了让图形更加美观,可以添加一些辅助元素:
还可以进一步设置包括线的宽度(LineWidth
),标记点的边缘颜色
(MarkerEdgeColor
),填充颜色(MarkerFaceColor
)及标记点的大小(MarkerSize
)等其它绘图属性.
使用示例:
plot(x,y,'b:p') //先后顺序无关紧要
plot(x,y,'--rs','LineWidth',2,... //线型-颜色-线宽
'MarkerEdgeColor','k',...//边缘颜色,仨点为续航符
'MarkerFaceColor','g',...//填充颜色
'MarkerSize',10) //标记点大小
之后还可以加点图例等:
使用示例1
x=linspace(0,2*pi,100);
y1=sin(x);
plot(x,y1,':r');
title('使用示例');
text(1,0,'0');%标注(1,0)点
ylabel('\Gamma');
xlabel('\theta');
axis equal %纵横坐标轴采用等长刻度
grid on
box on
hold on
使用示例2
代码:
x=(2003:5:2022);%
x1=sprintfc('%g',x);%转成字符串数组
plot(Time,CHLAmean');
axis([2002 2022 2.5 4.5]);%here!!
y=(3:0.5:4.5);%here!!
set(gca,'XTick',x,'XTicklabel',x1);
set(gca,'YTick',y);
set(gca,'FontName','Times New Roman');
xlabel('(b) T/year');
ylabel('CHLA/mg\cdotm^{-3}');
结果:
Chap.III 画堆积柱状图
出处:https://www.csdn.net/gather_2e/MtzaUg0sNzk0LWJsb2cO0O0O.html
实现函数:
function [] = plotBarStackGroups(stackData, groupLabels)
%% Plot a set of stacked bars, but group them according to labels provided.
%%
%% Params:
%% stackData is a 3D matrix (i.e., stackData(i, j, k) => (Group, Stack, StackElement))
%% groupLabels is a CELL type (i.e., { 'a', 1 , 20, 'because' };)
%%
%% Copyright 2011 Evan Bollig (bollig at scs DOT fsu ANOTHERDOT edu
%%
%%
NumGroupsPerAxis = size(stackData, 1);
NumStacksPerGroup = size(stackData, 2);
% Count off the number of bins
groupBins = 1:NumGroupsPerAxis;
MaxGroupWidth = 0.65; % Fraction of 1. If 1, then we have all bars in groups touching
groupOffset = MaxGroupWidth/NumStacksPerGroup;
figure
hold on;
for i=1:NumStacksPerGroup
Y = squeeze(stackData(:,i,:));
% Center the bars:
internalPosCount = i - ((NumStacksPerGroup+1) / 2);
% Offset the group draw positions:
groupDrawPos = (internalPosCount)* groupOffset + groupBins;
h(i,:) = bar(Y, 'stacked');
set(h(i,:),'BarWidth',groupOffset);
set(h(i,:),'XData',groupDrawPos);
end
hold off;
set(gca,'XTickMode','manual');
set(gca,'XTick',1:5:NumGroupsPerAxis);
set(gca,'XTickLabelMode','manual');
set(gca,'XTickLabel',groupLabels);
end
调用实例:
Fmean=(1:72);
F=reshape(Fmean,4,18);
A=reshape(F',[18 1 4]);
plotBarStackGroups(A,x1);
set(gca,'FontName','Times New Roman');
legend('Jan.','Feb.','Mar.','Apr.');
xlabel('(b) T/year');
ylabel('F/\mumol\cdotm^{-2}\cdoth^{-1}');
结果:
Chap.IV 分段拟合
代码:
figure(2)
x2=(1:12*40+4);
x21=x2(1:12*13);XCO21=XCO2(1:12*13,1); %第一段
x22=x2(12*16:end);XCO22=XCO2(12*16:end); %第二段
a=polyfit(x21',XCO21,1);%得到拟合参数a 1x2
b=a(1,2);
a1=a(1,1);
y1=a1.*x21+b;
a=polyfit(x22',XCO22,1);%得到拟合参数a 1x2
b=a(1,2);
a=a(1,1);
y2=a.*x22+b;
plot(x2',XCO2,x21,y1,'r:',x22,y2,'r:');
x0=(3:5*12:12*41);
x=(1980:5:2022);%
x1=sprintfc('%g',x);%转成字符串数组
set(gca,'XTick',x0,'XTicklabel',x1);
set(gca,'FontName','Times New Roman');
xlabel('T/year');
annotation('arrow',[0.3,0.25],[0.3,0.35]);%箭头标注
text(36,359,'a1=1.5');%文字标注
annotation('arrow',[0.75,0.80],[0.7,0.65]);%箭头标注
text(440,390,'a1=2.0');%文字标注
ylabel('XCO2/ppm');
结果:
Chap.V 画箱形图
参考:https://blog.csdn.net/wokaowokaowokao12345/article/details/92718896
箱型图是我最近才学到的一种图,它主要是用于描述统计量的。它主要由五根横线表示一组统计数据的分布,这五根横线分别为最小值、下四分位数、中位数、上四分位数、最大值,有时还会有异常值。异常值也可以表示为位于分布的整体之外的值,因此可以影响整个数据系列。
异常值通常被认为是由于存在可能低估或高估研究的极值而导致测量误差的原因,因为它与来自群体的随机样本中的其他值具有异常距离。根据所有统计学家遵循的基本标准,对异常值的通用定义是落在第三个四分位数之上或低于第一个四分位数的四分位数距的1.5倍以上。
下面看个例子:
X = [1.2 1.8 3.2 3.8 5.2 5.8];
Y = rand(100, 6);
boxplot(Y, 'positions', X, 'labels', X)
结果:
原博文文尾有两个求最值、中位数的函数,啥时候可能用可以去看看。