Matlab进阶绘图第13期—带填充纹理的堆叠图
Posted 阿昆的科研日常
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Matlab进阶绘图第13期—带填充纹理的堆叠图相关的知识,希望对你有一定的参考价值。
带填充纹理的堆叠图是通过在原始堆叠图的基础上添加不同的纹理得到的,可以很好地解决由于颜色区分不够而导致的对象识别困难问题。
由于Matlab中未收录提供填充纹理选项,因此需要大家自行设法解决。
本文使用hatchfill2工具(Kesh Ikuma. Matlab Central, 2023)进行带填充纹理的堆叠图的绘制,先来看一下成品效果:
特别提示:本期内容『数据+代码』已上传资源群中,加群的朋友请自行下载。有需要的朋友可以关注同名公号【阿昆的科研日常】,后台回复关键词【绘图桶】查看加入方式。
1. 数据准备
此部分主要是读取原始数据,并初始化绘图参数。
% 读取数据
load data.mat
% 初始化绘图参数
x = X;
y = A;
2. 颜色定义
作图不配色就好比做菜不放盐,总让人感觉少些味道。
但颜色搭配比较考验个人审美,需要多加尝试。
这里直接使用TheColor配色工具中的SCI权威配色库:
%% 颜色定义
map = TheColor('sci',2064,'map',10);
map = flipud(map);
C1 = map(1,1:3);
C2 = map(2,1:3);
C3 = map(3,1:3);
C4 = map(6,1:3);
3. 带填充纹理的堆叠图绘制
利用‘bar’和‘hatchfill2’命令,绘制初始的带填充纹理的堆叠图。
GO = bar(x,y',0.8,'stacked','EdgeColor','k');
hatchfill2(GO(1),'cross','HatchAngle',45,'HatchDensity',40,'HatchColor','k');
hatchfill2(GO(2),'single','HatchAngle',45,'HatchDensity',40,'HatchColor','k');
hatchfill2(GO(3),'single','HatchAngle',0,'HatchDensity',40,'HatchColor','k');
hatchfill2(GO(4),'single','HatchAngle',-45,'HatchDensity',40,'HatchColor','k');
hTitle = title('Texture filled stacked bar chart');
hXLabel = xlabel('Samples');
hYLabel = ylabel('RMSE (m)');
4. 细节优化
为了插图的美观,将初始堆叠图赋上之前选择的颜色:
% 赋色
GO(1).FaceColor = C1;
GO(2).FaceColor = C2;
GO(3).FaceColor = C3;
GO(4).FaceColor = C4;
进一步,对坐标轴细节等进行美化,设置完毕后,以期刊所需分辨率、格式输出图片:
%% 图片输出
exportgraphics(figureHandle,'test1.png','Resolution',300)
以上。
MATLAB | 特殊绘图小合集 | 渐变面积图环形树状图不规则等高线填充图
这是第一期特殊绘图小合集文章,主要把一些绘制比较有技巧但是篇幅太短不适合单出文章的绘图拿过来放在一起,估计很久之后才能攒出这么多特殊绘图出第二期。。
1 渐变面积图
写了个小工具可以用来生成渐变面积图:
function areah(varargin)
% @author : slandarer
if isa(varargin1,'matlab.graphics.axis.Axes')
ax=varargin1;varargin(1)=[];
else
ax=gca;
end
hold on
X=varargin1;Y=varargin2;
XList=linspace(min(X(:)),max(X(:)),1000);
YList=linspace(min(Y(:)),max(Y(:)),1000);
[~,YMesh]=meshgrid(XList,YList);
YY=interp1(X(:),Y(:),XList);
coe.Color=lines(ax.ColorOrderIndex);
coe.LineWidth=2;
for i=3:2:length(varargin)
coe.(varargini)=varargini+1;
end
CMesh=zeros(1000,1000,3);
CMesh(:,:,1)=ones(1000,1000).*coe.Color(1);
CMesh(:,:,2)=ones(1000,1000).*coe.Color(2);
CMesh(:,:,3)=ones(1000,1000).*coe.Color(3);
AMesh=linspace(0,.5,1000)'.*ones(1,1000);
AMesh(YMesh>YY)=0;
image(ax,[min(X(:)),max(X(:))],[min(Y(:)),max(Y(:))],CMesh,'AlphaData',AMesh)
plot(ax,X(:),Y(:),'Color',coe.Color,'LineWidth',coe.LineWidth)
ax.ColorOrderIndex=ax.ColorOrderIndex+1;
end
使用方法:
% areahDemo
% 生成数据
x=linspace(-8,12,100);
y1=normpdf(x,4,6);
y2=normpdf(x,0,1).*0.5+normpdf(x,4,2).*0.5;
y3=normpdf(x,-3,2);
% 绘制渐变面积图
hold on
areah(gca,x,y1,'Color',[144,69,70]./255,'LineWidth',1.5);
areah(x,y2,'Color',[74,156,167]./255,'LineWidth',1.5);
areah(x,y3,'Color',[102,140,123]./255,'LineWidth',1.5);
% 简单修饰坐标区域
ax=gca;
ax.XLim=[-8,12];
ax.Box='on';
2 特殊形状填充等高线图
实用contourf
绘制填充等高线图时,可以将矩阵一部分设置为nan,绘制效果就会将这部分省缺为空白:
% nanContourfDemo
Z=peaks(500);
[X,Y]=meshgrid(1:size(Z,2),1:size(Z,1));
Z(Y>sin(X/40).*100+350)=nan;
contourf(X,Y,Z,20,'EdgeColor','none')
3 环形饼状图
就饼状图中心画个白色的圆就好了:
% circularPieDemo
X=[1,2,1,4,5];
pieHdl=pie(X);
hold on
% 颜色列表,修改颜色和标签位置
colorList=[0.8858 0.8500 0.8880
0.6173 0.7311 0.7864
0.4041 0.5218 0.7440
0.3668 0.2640 0.6465
0.2589 0.0720 0.3397];
for i=2:2:length(pieHdl)
pieHdl(i).Position=pieHdl(i).Position.*.57;
pieHdl(i).Color=[1,1,1];
pieHdl(i-1).FaceColor=colorList(i/2,:);
end
legend('AutoUpdate','off')
% 画个圆
t=linspace(0,2*pi,200);
fill(cos(t).*.5,sin(t).*.5,'w')
4 三维组合图
就是一个散点密度图,不过组合的形式变成了三维:
% densityDemo
pntSet=mvnrnd([2 3],[1 .5;.5 2],500);
scatter(pntSet(:,1),pntSet(:,2),40,'.','MarkerEdgeColor',[.5,.5,.5]);
% 计算中心点,协方差矩阵
Mu=mean(pntSet);
Y=pntSet-repmat(Mu,size(pntSet,1),1);
Sigma=(Y'*(ones(size(pntSet,1),1).*Y))./size(pntSet,1);
ax=gca;view(3)
hold on;box on;grid on
ax.XLim=[-2,10];
ax.YLim=[-2,10];
%ax.DataAspectRatio=[1,1,1];
% 绘制置信椭圆
[X,Y]=getEllipse(Mu,Sigma,9.21,100);
plot(X,Y,'Color',[0,0,.8],'LineWidth',2);
% 绘制直方图
H1Hdl=histogram(pntSet(:,1));
for i=1:length(H1Hdl.Values)
fill3([H1Hdl.BinEdges([i,i+1,i+1,i])],[1,1,1,1].*ax.YLim(2),...
[0,0,H1Hdl.Values([i,i])],[.7,.7,.7])
end
H2Hdl=histogram(pntSet(:,2));
for i=1:length(H2Hdl.Values)
fill3([1,1,1,1].*ax.XLim(2),[H2Hdl.BinEdges([i,i+1,i+1,i])],...
[0,0,H2Hdl.Values([i,i])],[.7,.7,.7])
end
ax.ZLim=[0,max([H1Hdl.Values,H2Hdl.Values])];
% 绘制核密度曲线
[f,xi]=ksdensity(pntSet(:,1));
plot3(xi,ones(size(xi)).*ax.YLim(2),f.*size(pntSet,1).*H1Hdl.BinWidth,'Color',[0,0,.8],'LineWidth',2)
[f,yi]=ksdensity(pntSet(:,2));
plot3(ones(size(yi)).*ax.XLim(2),yi,f.*size(pntSet,1).*H2Hdl.BinWidth,'Color',[0,0,.8],'LineWidth',2)
delete(H1Hdl)
delete(H2Hdl)
% 置信椭圆定位函数
function [X,Y]=getEllipse(Mu,Sigma,S,pntNum)
% 置信区间 | 95%:5.991 99%:9.21 90%:4.605
% (X-Mu)*inv(Sigma)*(X-Mu)=S
invSig=inv(Sigma);
[V,D]=eig(invSig);
aa=sqrt(S/D(1));
bb=sqrt(S/D(4));
t=linspace(0,2*pi,pntNum);
XY=V*[aa*cos(t);bb*sin(t)];
X=(XY(1,:)+Mu(1))';
Y=(XY(2,:)+Mu(2))';
end
5 每组不同数量三维柱状图
也写了个工具函数:
function hdlSet=bar3n(X)
ax=gca;
ax.Projection='perspective';
for i=1:length(X)
SE=nan(length(X),length(Xi));
SE(i,:)=Xi;
hdlSeti=bar3(SE,'grouped');
if i==1
hold on;
end
end
for i=1:length(X)
for j=1:length(hdlSeti)
% 删掉多余的柱状图
tXData=hdlSeti(j).XData;
hdlSeti(j).XData=nan.*ones(size(hdlSeti(j).XData));
hdlSeti(j).XData((i-1)*6+1:i*6,:)=tXData((i-1)*6+1:i*6,:);
end
end
end
非常简单的使用方法:
% bar3nDemo
X1=[1 4 6 4 1];
X2=[1 5 10 10 5 1];
X3=[1 6 15 20 15 6 1];
bar3n(X);
6 环形树状图
需要安装Statistics and Machine Learning Toolbox即统计与机器学习工具箱!!!
自己写的工具函数:
function [treeHdl,txtHdl]=ringTree(Data,Name)
% @author : slandarer
fig=gcf;
fig.Color=[1,1,1];
ax=gca;hold on
ax.XLim=[-1.2,1.2];
ax.YLim=[-1.2,1.2];
ax.DataAspectRatio=[1,1,1];
ax.XColor='none';
ax.YColor='none';
ax.Tag='author : slandarer';
disp(ax.Tag);
fig1=figure();
tree1=linkage(Data,'average');
[以上是关于Matlab进阶绘图第13期—带填充纹理的堆叠图的主要内容,如果未能解决你的问题,请参考以下文章
MATLAB | 特殊绘图小合集 | 渐变面积图环形树状图不规则等高线填充图