赞
踩
看到阿昆的科研日常
写了一篇如何将轴线隐藏而不隐藏刻度的推送,使用了XRuler中的Axle对象来实现,但我试了一下R2023A版本中不太能直接用,解决了一下,同时讲一下这些有趣的隐藏对象及其其他的用法。
假设我们编写了如下代码:
rng(12) % 生成随机点 mu = [2 3; 6 7; 8 9]; S = cat(3,[1 0; 0 2],[1 0; 0 2],[1 0; 0 1]); r1 = abs(mvnrnd(mu(1,:),S(:,:,1),100)); r2 = abs(mvnrnd(mu(2,:),S(:,:,2),100)); r3 = abs(mvnrnd(mu(3,:),S(:,:,3),100)); % 绘制散点图 hold on propCell={'LineWidth',1.2,'MarkerEdgeColor',[.3,.3,.3],'SizeData',60}; scatter(r1(:,1),r1(:,2),'filled','CData',[0.40 0.76 0.60],propCell{:}); scatter(r2(:,1),r2(:,2),'filled','CData',[0.99 0.55 0.38],propCell{:}); scatter(r3(:,1),r3(:,2),'filled','CData',[0.55 0.63 0.80],propCell{:}); % 增添图例 lgd=legend('scatter1','scatter2','scatter3'); lgd.Location='northwest'; lgd.FontSize=14; % 半透明图例 pause(1e-6) lgd.BoxFace.ColorType='truecoloralpha'; lgd.BoxFace.ColorData=uint8(255*[1;1;1;.8]); % 坐标区域基础修饰 ax=gca; grid on ax.FontName = 'Cambria'; ax.Color = [0.9,0.9,0.9]; ax.Box = 'off'; ax.TickDir = 'out'; ax.GridColor = [1 1 1]; ax.GridAlpha = 1; ax.LineWidth = 1; ax.XColor = [0.2,0.2,0.2]; ax.YColor = [0.2,0.2,0.2]; ax.TickLength = [0.015 0.025];
在代码最后加入以下代码即可隐藏轴线:
% 隐藏轴线
ax=gca;
pause(1e-6)
ax.XRuler.Axle.LineStyle='none';
ax.YRuler.Axle.LineStyle='none';
注意对于比较新的版本,Axle不会直接被显示为XRuler的子对象,需要pause一下过段时间才会生成对象并被添加为XRuler的子对象,这是与老版本不同的地方。当然不设置线条格式,直接将其可见性调成否也是一种方法:
% 隐藏轴线
ax=gca;
pause(1e-6)
ax.XRuler.Axle.Visible='off';
ax.YRuler.Axle.Visible='off';
而如果设置线条格式,不仅仅可以设置为’none’还可以设置为’solid’ | ‘dashed’ | ‘dotted’ | ‘dashdot’ | 'none’等类型(注意观察下图x 轴)
一般绘制对数坐标轴图可以使用下面几个函数,但是绘制出来的都是线图:
怎么样其他绘图类型也使用对数刻度呢??还是使用上面那段代码,比如我们在最后加上如下代码即可将x轴变成对数刻度(y 轴同理):
ax=gca;
ax.XRuler.Scale='log';
有个更简单的等价方法:
ax=gca;
ax.XScale='log';
再比如填充图的对数坐标轴:
x = logspace(-1,2,1000);
y = 5 + 3*sin(x);
fill([x x(end)],[y y(1)],[0.40 0.76 0.60],'FaceAlpha',.2,...
'LineWidth',1,'EdgeColor',[0.40 0.76 0.60])
% 坐标区域基础修饰
ax=gca; grid on;
ax.FontName = 'Cambria';
ax.TickDir = 'out';
ax.LineWidth = .8;
ax.Box = 'off';
% 对数坐标轴
ax=gca;
ax.XScale='log';
我们box on
操作后显示的框上也有刻度:
t = linspace(pi/100,4*pi,500);
y1 = cos(t).^2;
y2 = sin(t).^2./t;
% 基础绘图
hold on
area(y1,'LineWidth',.8,'FaceColor',[0,0,.9],'FaceAlpha',.2)
area(y2,'LineWidth',.8,'FaceColor',[.8,0,0],'FaceAlpha',.2)
% 坐标区域基础修饰
ax=gca; grid on; box on
ax.FontName = 'Cambria';
ax.TickDir = 'out';
ax.LineWidth = 1.2;
有没有啥办法不显示这个刻度呢??虽然我们能够获取BoxFrame但这玩意并没有刻度属性,因此我们想到了直接画直线,同时为了拖动图像时直线的位置依旧在边框应该待的地方,我们为当前坐标区域增添监听,大概这样:
function testBox t = linspace(pi/100,4*pi,500); y1 = cos(t).^2; y2 = sin(t).^2./t; % 基础绘图 hold on area(y1,'LineWidth',.8,'FaceColor',[0,0,.9],'FaceAlpha',.2) area(y2,'LineWidth',.8,'FaceColor',[.8,0,0],'FaceAlpha',.2) % 坐标区域基础修饰 ax=gca; grid on; box on ax.FontName = 'Cambria'; ax.TickDir = 'out'; ax.LineWidth = 1; % 绘制可跟随移动的框线 ax=gca; box off XLineHdl=plot(ax,ax.XLim([1,2]),ax.YLim([2,2]),'LineWidth',1,'Color',[0,0,0]); YLineHdl=plot(ax,ax.XLim([2,2]),ax.YLim([1,2]),'LineWidth',1,'Color',[0,0,0]); addlistener(ax,'MarkedClean',@changeLinePos) function changeLinePos(~,~) set(XLineHdl,'XData',ax.XLim([1,2]),'YData',ax.YLim([2,2])) set(YLineHdl,'XData',ax.XLim([2,2]),'YData',ax.YLim([1,2])) end end
当然我们这么用不咋方便,我们可以将其封装为函数:
function addBox
ax=gca; box off
XLineHdl=plot(ax,ax.XLim([1,2]),ax.YLim([2,2]),'LineWidth',ax.LineWidth,'Color',ax.XColor);
YLineHdl=plot(ax,ax.XLim([2,2]),ax.YLim([1,2]),'LineWidth',ax.LineWidth,'Color',ax.YColor);
addlistener(ax,'MarkedClean',@changeLinePos)
function changeLinePos(~,~)
set(XLineHdl,'XData',ax.XLim([1,2]),'YData',ax.YLim([2,2]))
set(YLineHdl,'XData',ax.XLim([2,2]),'YData',ax.YLim([1,2]))
end
end
这样画完图之后在最后加一行addBox()即可,框的颜色及粗细会和轴的颜色相图:
t = linspace(pi/100,4*pi,500); y1 = cos(t).^2; y2 = sin(t).^2./t; % 基础绘图 hold on area(y1,'LineWidth',.8,'FaceColor',[0,0,.9],'FaceAlpha',.2) area(y2,'LineWidth',.8,'FaceColor',[.8,0,0],'FaceAlpha',.2) % 坐标区域基础修饰 ax=gca; grid on; box on ax.FontName = 'Cambria'; ax.TickDir = 'out'; ax.LineWidth = 1; ax.XColor = [0,0,.8]; ax.YColor = [.8,0,0]; addBox()
假设我们编写了如下代码:
% 获取数据 X1=normrnd(2,2,1,50); X2=[normrnd(4,4,1,50),normrnd(5,2,1,50)]; X3=[normrnd(6,2,1,50),normrnd(8,4,1,50)]; X4=[normrnd(12,1,1,50),normrnd(12,4,1,50)]; X5=[normrnd(10,2,1,50),normrnd(10,4,1,50)]; X6=[normrnd(7,2,1,50),normrnd(7,4,1,50)]; X7=[normrnd(4,2,1,50),normrnd(4,4,1,50)]; Data={X1,X2,X3,X4,X5,X6,X7}; Y=zeros(7,500); for i=1:length(Data) tX=Data{i};tX=tX(:)'; [F,Xi]=ksdensity(tX,linspace(-5,10,500)); Y(i,:)=F; end X=Xi; YLim=[min(min(Y)),max(max(Y))]; % 构造并绘制网格 [XMesh,YMesh]=meshgrid(X,linspace(YLim(1),YLim(2),1000)); hold on for i=1:size(Y,1) YMeshA=repmat(Y(i,:),[1000,1]); CMesh=nan.*XMesh; YMeshD=YMeshA-YLim(1); CMesh(YMesh>=YLim(1)&YMesh<=YMeshA)=YMeshD(YMesh>=YLim(1)&YMesh<=YMeshA); surf(XMesh,XMesh.*0+i,YMesh,'EdgeColor','none','CData',CMesh,'FaceColor','flat','FaceAlpha',.8) end % 绘制折线图 for i=1:size(Y,1) plot3(X,X.*0+i,Y(i,:),'LineWidth',1,'Color',[0,0,0,.8]) end % 设置配色 colorList=turbo(64); % colorList=slanCM(110,64); colormap(colorList) colorbar % 坐标区域修饰 ax=gca;hold on;box on ax.XGrid='on'; ax.YGrid='on'; ax.XMinorTick='on'; ax.YMinorTick='on'; ax.LineWidth=.8; ax.GridLineStyle='-.'; ax.FontName='Cambria'; ax.FontSize=12; ax.GridAlpha=.03; ax.Projection='perspective'; ax.GridAlpha=.05; ax.BoxStyle='full'; view(16,36)
可以通过boxFrame属性设置每个框线的颜色:
% 设置框线颜色
ax=gca;
pause(1e-6);
ax.BoxFrame.XColor=[1,0,0];
ax.BoxFrame.YColor=[0,1,0];
ax.BoxFrame.ZColor=[0,0,1];
可以看到仅仅框线变色,轴线不变色,此属性仅仅为显示属性,保存时无法保留颜色,因此建议绘制折线硬画:
把之前写的一小部分东西拿过来再提一下:
对于hAxes=gca
一个实例:
N = 49;
X = linspace(-10,10,N);
Z = peaks(N);
mesh(X,X,Z);
hAxes=gca;
hAxes.LineWidth=1.5;
hAxes.XRuler.FirstCrossoverValue = 0; % X轴在Y轴上的位置
hAxes.YRuler.FirstCrossoverValue = 0; % Y轴在X轴上的位置
hAxes.ZRuler.FirstCrossoverValue = 0; % Z轴在X轴上的位置
hAxes.ZRuler.SecondCrossoverValue = 0; % Z轴在Y轴上的位置
我们知道可以通过设置
set(gca,'Color',[1,0,0])
类似的形式设置背景颜色,但这只是纯色,那么有啥办法把背景色换成渐变色?
t=0.2:0.01:3*pi; hold on plot(t,cos(t)./(1+t),'LineWidth',4) plot(t,sin(t)./(1+t),'LineWidth',4) plot(t,cos(t+pi/2)./(1+t+pi/2),'LineWidth',4) plot(t,cos(t+pi)./(1+t+pi),'LineWidth',4) legend ax=gca;pause(1e-16);% Backdrop建立需要一定时间因此pause一下很重要 % 四列分别为四个角的颜色 % 使用4xN大小颜色矩阵 % 四行分别是R,G,B,和透明度 colorData = uint8([255, 150, 200, 100; ... 255, 100, 50, 200; ... 0, 50, 100, 150; ... 102, 150, 200, 50]); set(ax.Backdrop.Face, 'ColorBinding','interpolated','ColorData',colorData);
t=0.2:0.01:3*pi;
hold on
plot(t,cos(t)./(1+t),'LineWidth',4)
plot(t,sin(t)./(1+t),'LineWidth',4)
plot(t,cos(t+pi/2)./(1+t+pi/2),'LineWidth',4)
plot(t,cos(t+pi)./(1+t+pi),'LineWidth',4)
hLegend=legend();
% 设置图例为半透明
pause(1e-16)
set(hLegend.BoxFace,'ColorType','truecoloralpha','ColorData',uint8(255*[1;1;1;.5]));
set(gca,'Color',[0,0,.18]);
当然也可以花里胡哨:
t=0.2:0.01:3*pi;
hold on
plot(t,cos(t)./(1+t),'LineWidth',4)
plot(t,sin(t)./(1+t),'LineWidth',4)
plot(t,cos(t+pi/2)./(1+t+pi/2),'LineWidth',4)
plot(t,cos(t+pi)./(1+t+pi),'LineWidth',4)
hLegend=legend();
% 设置图例为渐变色
pause(1e-16)
colorData = uint8([255, 150, 200, 100; ...
255, 100, 50, 200; ...
0, 50, 100, 150; ...
102, 150, 200, 50]);
set(hLegend.BoxFace,'ColorBinding','interpolated','ColorData',colorData)
我们想将刻度值用科学计数法表示咋办,假如编写了如下代码:
rng(5) % 随机生成数据 X=1.5+rand(4,4); % 基础绘图 ax=gca;hold on; bHdl=bar(X,'LineWidth',.8); % 修改配色 CList=[0.4078 0.5647 0.8157 0.9098 0.7843 0.6588 0.9725 0.8784 0.7216 0.9725 0.9725 0.9725]; bHdl(1).FaceColor=CList(1,:); bHdl(2).FaceColor=CList(2,:); bHdl(3).FaceColor=CList(3,:); bHdl(4).FaceColor=CList(4,:); % 坐标区域修饰 ax.FontName='Times New Roman'; ax.LineWidth=.8; ax.FontSize=12; ax.YGrid='on'; ax.GridLineStyle='-.'; ax.XTick=1:4;
在最后编写如下代码使用科学计数法:
ax=gca;
ax.XRuler.Exponent=-5;
ax=gca;
ax.XRuler.Exponent=5;
刻度标签也可以改成支持latex,还是上面的绘图函数,在最后加上:
ax.XRuler.TickLabelInterpreter='latex';
ax.XTickLabel={'$\Delta A B C$','$\frac{n!}{r!(n-r)!} $','$\left(\begin{array}{cc}A& B\\C& D\end{array}\right)$','$E = n{{ \Delta \Phi } \over {\Delta {t} }} $'}
最后讲一下如何显示X轴及Y轴次标签:
x = linspace(0,100,1000); y = 5 + 3*sin(x./2); fill([x x(end)],[y y(1)],[0.40 0.76 0.60],'FaceAlpha',.2,... 'LineWidth',1,'EdgeColor',[0.40 0.76 0.60]) % 坐标区域基础修饰 ax=gca; grid on; ax.FontName = 'Cambria'; ax.TickDir = 'out'; ax.LineWidth = .8; ax.Box = 'off'; % 显示次标签 ax=gca; % X轴主次标签 xlabel('XXXX1111') ax.XRuler.SecondaryLabel.String='XXXX2222'; ax.XRuler.SecondaryLabel.Visible='on'; % Y轴主次标签 ylabel('YYYY1111') ax.YRuler.SecondaryLabel.String='YYYY2222'; ax.YRuler.SecondaryLabel.Visible='on';
本期已经足够长了,等有下期可能会补充其他的MATLAB中的离谱操作!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。