目录
前言
在MATLAB中,使用窗口对象的Color属性可以轻松地设置不同的背景颜色,但是只能设置一种单一颜色。若需要将绘图背景设置成多种颜色,比如左右两边不同的颜色,MATLAB中是不支持直接设置的。文章提供了一个分割背景并可以填充颜色的函数splitBackground,还提供了该函数的使用示例。
分割背景函数
分割背景的函数splitBackground如下,该函数必须输入一个窗口对象ax,ax通常可以赋值为gca;nx和ny表示水平方向和竖直方向的分割数量;colors表示填充的颜色,顺序为从下到上,从左到右;biasx和biasy可以设置水平方向和竖直方向分割的位置,默认为均分。
matlab
function splitBackground(ax,nx,ny,colors,biasx,biasy)
% 分割绘图背景, 并填充颜色
% ax 窗口对象,一般设置为ax = gca
% nx 水平方向的分割数量 默认:1
% ny 竖直方向的分割数量 默认:1
% colors 指定颜色(GRB数组),顺序:从左到右,从下到上 默认:jet
% biasx 水平方向的分割位置(0-1,最后一个位置需为1),数组大小为nx 默认:均分
% biasy 竖直方向的分割位置(0-1,最后一个位置需为1),数组大小为ny 默认:均分
if nargin < 2, nx = 1; end
if nargin < 3, ny = 1; end
if nargin < 4, colors = jet(nx*ny); end
if nargin < 5, biasx = cumsum(ones(nx,1)/nx); end
if nargin < 6, biasy = cumsum(ones(ny,1)/ny); end
Po = get(ax,'Position'); % 当前图窗位置坐标
set(ax,'color','none') % 设置绘图区背景为透明色
k = 0; % 记录背景数量
for i = 1:nx
for j = 1:ny
k = k + 1;
Pon = Po; % 拷贝位置坐标
% 计算水平方向的位置
if i > 1
Pon(1) = Pon(1) + Pon(3)*biasx(i-1);
Pon(3) = Pon(3)*(biasx(i)-biasx(i-1));
else
Pon(3) = Pon(3)*biasx(i);
end
% 计算竖直方向的位置
if j > 1
Pon(2) = Pon(2) + Pon(4)*biasy(j-1);
Pon(4) = Pon(4)*(biasy(j)-biasy(j-1));
else
Pon(4) = Pon(4)*biasy(j);
end
% 设置背景
axbg = axes('Position',Pon,'Color',colors(k,:),'XColor','none','YColor','none');
set(axbg,'XTick', [],'YTick', []); % 去掉xy轴刻度
% 背景置底
uistack(axbg,'bottom') % 设置新绘图区位于最底层
end
end
end
示例
基本绘图
下面这是基本的绘图代码,具体细节可以参考前面的文章(点击转跳)。
matlab
clc;clear;close all
set(0,'defaultfigurecolor','w');
%% 数据
x = 0:0.01:1; % 产生0到1, 步长为0.01的序列
y = 2*x + 1; % y为x一次函数
rng(100) % 随机数种子,使每次随机数都是一样的
r = (rand(1,length(x)) - 0.5) * 2; %产生-1到1的随机数
y1 = y + r*0.5; %对y施加扰动(为了模拟数据)
%% 绘图
f = figure(1);
ax = gca; % 将当前坐标区实例化
plot(x,y,'-k',x,y1,'ok','LineWidth',1.3)
hold on
set(gca,'FontName','Times New Roman','FontSize',13)
xlabel('\fontname{宋体} 位移\fontname{Times New Roman} \it x/\rm mm')
ylabel('\fontname{宋体} 力\fontname{Times New Roman} \it y/\rm N')
% 图例
le = legend('拟合数据','原始数据','FontName','宋体','Location','northwest');
% legend('boxoff') %取消图例边框
le.EdgeColor = 'none';
le.Color = 'none';
le.LineWidth = 1.3;
% 设置次刻度线
set(gca,'XMinorTick',true)
set(gca,'YMinorTick',true)
% 去除上边框、右边框刻度线
box off % 取消边框
ax1 = axes('Position',get(ax,'Position'),'XAxisLocation','top',...
'YAxisLocation','right','Color','none','XColor','k','YColor','k'); % 设置坐标区
set(ax1,'XTick', [],'YTick', []); % 去掉xy轴刻度
hold off
运行代码后得到下面的结果图。
分割背景函数的使用
可以通过colors自定义颜色,注意只能输入RGB颜色数组。接着调用分割背景函数splitBackground,注意ax在前面已经赋值了,见上一个代码块。
- 将绘图背景按水平方向分割为两区域。
matlab
colors = [1,0.81,0.81;
0.79,0.81,1;
0.8,1,0.79;
1,0.99,0.79];
splitBackground(ax,2,1,colors)
将上面的代码放在第一个代码块的末尾,运行后即可得到下面的结果图。
- 将绘图背景按竖直方向分割为两区域。
matlab
splitBackground(ax,1,2,colors)
- 将绘图背景按水平方向分割为两区域,并设置分割位置为0.7。
matlab
splitBackground(ax,2,1,colors,[0.7,1])
- 将绘图背景按水平方向和竖直方向分割为四个区域,并设置分割位置为0.7和0.6。
matlab
splitBackground(ax,2,2,colors,[0.7,1],[0.6,1])
保存图片
使用了分割背景函数splitBackground后,通过代码保存图片的方式(比如print、exportgraphics和saveas等)出现了一些问题(具体原因未知,可能是bug),会导致背景颜色缺失或者出现白边的情况,而通过手动保存可以避免这些问题。
- 首先点击"文件"。
- 接着点击"导出设置"。
- 点击"导出"。
- 设置"保存类型"以及"文件名",点击确定即可。
总代码
总代码如下,后续还会继续更新一些MATLAB绘图的技巧和细节,制作不易,别忘了关注和点赞喔。
matlab
clc;clear;close all
set(0,'defaultfigurecolor','w');
%% 数据
x = 0:0.01:1; % 产生0到1, 步长为0.01的序列
y = 2*x + 1; % y为x一次函数
rng(100) % 随机数种子,使每次随机数都是一样的
r = (rand(1,length(x)) - 0.5) * 2; %产生-1到1的随机数
y1 = y + r*0.5; %对y施加扰动(为了模拟数据)
%% 绘图
f = figure(1);
ax = gca; % 将当前坐标区实例化
plot(x,y,'-k',x,y1,'ok','LineWidth',1.3)
hold on
set(gca,'FontName','Times New Roman','FontSize',13)
xlabel('\fontname{宋体} 位移\fontname{Times New Roman} \it x/\rm mm')
ylabel('\fontname{宋体} 力\fontname{Times New Roman} \it y/\rm N')
% 图例
le = legend('拟合数据','原始数据','FontName','宋体','Location','northwest');
% legend('boxoff') %取消图例边框
le.EdgeColor = 'none';
le.Color = 'none';
le.LineWidth = 1.3;
% 设置次刻度线
set(gca,'XMinorTick',true)
set(gca,'YMinorTick',true)
% 去除上边框、右边框刻度线
box off % 取消边框
ax1 = axes('Position',get(ax,'Position'),'XAxisLocation','top',...
'YAxisLocation','right','Color','none','XColor','k','YColor','k'); % 设置坐标区
set(ax1,'XTick', [],'YTick', []); % 去掉xy轴刻度
hold off
% 分割背景并填充颜色
% 颜色
colors = [1,0.81,0.81;
0.79,0.81,1;
0.8,1,0.79;
1,0.99,0.79];
% 将绘图背景按水平方向分割为两区域
% splitBackground(ax,2,1,colors)
% 将绘图背景按竖直方向分割为两区域
% splitBackground(ax,1,2,colors)
% 将绘图背景按水平方向分割为两区域,并设置分割位置为0.7
% splitBackground(ax,2,1,colors,[0.7,1])
% 将绘图背景按水平和竖直方向分割为两区域,并设置分割位置为0.7和0.6
splitBackground(ax,2,2,colors,[0.7,1],[0.6,1])
function splitBackground(ax,nx,ny,colors,biasx,biasy)
% 分割绘图背景, 并填充颜色
% ax 窗口对象,一般设置为ax = gca
% nx 水平方向的分割数量 默认:1
% ny 竖直方向的分割数量 默认:1
% colors 指定颜色(GRB数组),顺序:从左到右,从下到上 默认:jet
% biasx 水平方向的分割位置(0-1,最后一个位置需为1),数组大小为nx 默认:均分
% biasy 竖直方向的分割位置(0-1,最后一个位置需为1),数组大小为ny 默认:均分
if nargin < 2, nx = 1; end
if nargin < 3, ny = 1; end
if nargin < 4, colors = jet(nx*ny); end
if nargin < 5, biasx = cumsum(ones(nx,1)/nx); end
if nargin < 6, biasy = cumsum(ones(ny,1)/ny); end
Po = get(ax,'Position'); % 当前图窗位置坐标
set(ax,'color','none') % 设置绘图区背景为透明色
k = 0; % 记录背景数量
for i = 1:nx
for j = 1:ny
k = k + 1;
Pon = Po; % 拷贝位置坐标
% 计算水平方向的位置
if i > 1
Pon(1) = Pon(1) + Pon(3)*biasx(i-1);
Pon(3) = Pon(3)*(biasx(i)-biasx(i-1));
else
Pon(3) = Pon(3)*biasx(i);
end
% 计算竖直方向的位置
if j > 1
Pon(2) = Pon(2) + Pon(4)*biasy(j-1);
Pon(4) = Pon(4)*(biasy(j)-biasy(j-1));
else
Pon(4) = Pon(4)*biasy(j);
end
% 设置背景
axbg = axes('Position',Pon,'Color',colors(k,:),'XColor','none','YColor','none');
set(axbg,'XTick', [],'YTick', []); % 去掉xy轴刻度
% 背景置底
uistack(axbg,'bottom') % 设置新绘图区位于最底层
end
end
end
总结
这只是一个基础的示例,实际中还会有更具体的、更细致的要求,这就需要再做额外调整;另外本人也仍在学习中,这只是个人的学习笔记,可能还有一些不足之处,欢迎指正。