赞
踩
之前写了一篇文章说明了MATLAB图例可以自己diy,这次又有了diy的机会,我开发了一个简单的小工具,能够实现绘制伪3d的柱状图,大概效果如下:
由于涉及的代码比较接近MATLAB底层的图形对象,有点东西还是没倒腾明白,目前使用起来还是有以下几个点要注意:
addlistener
解决但目前还未完成倒腾出来,R2024a之前版本不会出这个Bug(属实是不知道新版本改了什么地方引起的这个Bug)另外本文中一部分图片使用了SAxes
这个函数美化了一下,这个函数长这样:
function SAxes
ax = gca;
ax.NextPlot = 'add';
ax.Box = 'on';
ax.XGrid = 'on';
ax.YGrid = 'on';
ax.XMinorTick = 'on';
ax.YMinorTick = 'on';
ax.LineWidth = .8;
ax.GridLineStyle = '-.';
ax.FontSize = 13;
ax.FontName = 'Times New Roman';
ax.GridAlpha = .05;
% ax.TickDir = 'out';
end
伪3d柱状图工具放在文末,现在先来讲解一下用法:
假如绘制了柱状图:
y = [1 2 3 6 3 9];
bHdl = bar(y);
legend()
SAxes()
只需要在最后面简单加上一行代码,变成:
y = [1 2 3 6 3 9];
bHdl = bar(y);
legend()
SAxes()
bar2_5D(bHdl, 'w')
就是打光风格的,如果第二个参数是k
就是阴影风格的:
bar2_5D(bHdl, 'k')
基本上所有类型柱状图均可支持:
y = [2 2 3; 2 5 6; 2 8 9; 2 11 12]; figure('Units','normalized', 'Position',[.1,.1,.6,.7]); bHdl = bar(y); legend() SAxes() bar2_5D(bHdl, 'w') figure('Units','normalized', 'Position',[.1,.1,.6,.7]); bHdl = bar(y, 'stacked'); legend() SAxes() bar2_5D(bHdl, 'w') figure('Units','normalized', 'Position',[.1,.1,.6,.7]); bHdl = barh(y); legend() SAxes() bar2_5D(bHdl, 'w') figure('Units','normalized', 'Position',[.1,.1,.6,.7]); bHdl = barh(y, 'stacked'); legend() SAxes() bar2_5D(bHdl, 'w')
y = [2 2 3; 2 5 6; 2 8 9; 2 11 12];
CList = [133,131,169; 202,139,168; 160,189,213]./255;
barHdl = barh(y);
for i = 1:length(barHdl)
barHdl(i).FaceColor = CList(i,:);
end
legend({'A','B','C'}, 'FontSize',13);
SAxes()
bar2_5D(barHdl, 'k')
rng(5) Data = randi([20,35], [5,2]); err = rand([5,2]).*5; hold on barHdl = bar(Data,'BarWidth',1); % 修改柱状图颜色透明度 barHdl(1).FaceColor = [153,153,253]./255; barHdl(2).FaceColor = [255,153,154]./255; % 修饰柱状图并绘制图例 lgd = legend({'AAAAA','BBBBB'}, 'FontSize',13, 'FontName','Times New Roman'); bar2_5D(barHdl, 'w') % 绘制并修饰误差棒 errorbar(barHdl(1).XEndPoints,Data(:,1),err(:,1), 'LineStyle','none', 'Color','k', 'LineWidth',.8); errorbar(barHdl(2).XEndPoints,Data(:,2),err(:,2), 'LineStyle','none', 'Color','k', 'LineWidth',.8); % 坐标区域修饰,修改X轴标签 ax = gca; ax.YLim = [0,40]; ax.LineWidth = .8; ax.TickLength = [.005,.001]; ax.Box = 'on'; ax.XTick = 1:5; ax.XTickLabel = {'A','B','C','D','E'}; ax.FontSize = 13; ax.FontName = 'Times New Roman';
y = [2 2; 3 2; 5 6; 2 8; 9 2; 11 12];
barHdl = bar(y);
CList = [87,87,213; 138,213,95]./255;
for i = 1:length(barHdl)
barHdl(i).FaceColor = CList(i,:);
end
legend()
set(gca, 'XLim',[.5,6.5])
SAxes()
bar2_5D(barHdl, 'w')
xregion([.5,3.5], 'FaceColor',[233,241,254]./255)
xregion([3.5,6.5], 'FaceColor',[251,244,218]./255)
若是把工具函数调用放在最后,就能显示全部图例:
y = [2 2; 3 2; 5 6; 2 8; 9 2; 11 12]; barHdl = bar(y); CList = [87,87,213; 138,213,95]./255; for i = 1:length(barHdl) barHdl(i).FaceColor = CList(i,:); end legend() set(gca, 'XLim',[.5,6.5]) SAxes() xregion([.5,3.5], 'FaceColor',[233,241,254]./255) xregion([3.5,6.5], 'FaceColor',[251,244,218]./255) bar2_5D(barHdl, 'w')
function bar2_5D(barHdl, style) % Copyright (c) 2024, Zhaoxu Liu / slandarer hold on CCC = @(x, C1, C2) C2.*sqrt(1 - x.^2) + C1.*(1 - sqrt(1 - x.^2)); Ver = version; Ver = str2double(Ver(1:2)); GraphicsNum = length(get(gca, 'Children')) - length(barHdl); if nargin < 2 style = 'w'; end % 基础属性计算 if Ver < 24 GroupWidth = 2/3; else GroupWidth = barHdl(1).GroupWidth; end if length(barHdl) > 1 && ~strcmp(barHdl(1).BarLayout, 'stacked') BarWidth = GroupWidth.*barHdl(1).BarWidth./length(barHdl); else BarWidth = barHdl(1).BarWidth; end % 柱状图上色 [XMesh, YMesh] = meshgrid(linspace(0,1,50)); XMesh = 2.*XMesh - 1; for i = 1:length(barHdl) barHdl(i).EdgeColor = 'none'; for j = 1:length(barHdl(i).XEndPoints) C = barHdl(i).CData(1,:); if strcmp(style, 'w') CMesh = cat(3, CCC(XMesh, C(1), .8 + C(1)*.2), ... CCC(XMesh, C(2), .8 + C(2)*.2), ... CCC(XMesh, C(3), .8 + C(3)*.2)); else CMesh = cat(3, CCC(XMesh, .3, C(1)), ... CCC(XMesh, .3, C(2)), ... CCC(XMesh, .3, C(3))); end if strcmp(barHdl(1).Horizontal, 'on') tY = XMesh.*BarWidth./2 + barHdl(i).XEndPoints(j); tX = YMesh.*barHdl(i).YData(j) + barHdl(i).YEndPoints(j) - barHdl(i).YData(j); else tX = XMesh.*BarWidth./2 + barHdl(i).XEndPoints(j); tY = YMesh.*barHdl(i).YData(j) + barHdl(i).YEndPoints(j) - barHdl(i).YData(j); end surfHdl = surf(tX, ... tY, XMesh.*0, ... 'CData',CMesh, 'EdgeColor','none'); surfHdl.Annotation.LegendInformation.IconDisplayStyle = 'off'; barHdl(i).Annotation.LegendInformation.IconDisplayStyle = 'off'; % uistack(surfHdl, 'bottom'); % uistack(barHdl(i), 'bottom') end end for i = 1:length(barHdl), plot([1,1],[1,1], 'Color',barHdl(i).CData(1,:), 'DisplayName',barHdl(i).DisplayName); end lgdHdl = get(gca, 'Legend'); if ~isempty(lgdHdl) pause(1e-6) % 获取图例图标 % lgdEntryChild = lgdHdl.EntryContainer.NodeChildren; % iconSet = arrayfun(@(lgdEntryChild)lgdEntryChild.Icon.Transform.Children.Children, lgdEntryChild, UniformOutput = false) childrenList = get(gca, 'Children'); for i = 1:GraphicsNum uistack(childrenList(end-length(barHdl)+1-i), 'top'); end pause(1e-6) lgdEntryChild = lgdHdl.EntryContainer.NodeChildren; iconSet = arrayfun(@(lgdEntryChild)lgdEntryChild.Icon.Transform.Children.Children, lgdEntryChild, UniformOutput = false); XX = [0,1,1,0]; YY = [1,1,0,0]; % 替换图例图标 for j = 1:20 newFaceHdl = matlab.graphics.primitive.world.Quadrilateral(); newFaceHdl.PickableParts = 'all'; newFaceHdl.Layer = 'middle'; newFaceHdl.ColorBinding = 'object'; newFaceHdl.ColorType = 'truecoloralpha'; newFaceHdl.VertexData = single([XX./20 + (j-1)/20; YY; XX.*0]); for i = 1:length(barHdl) oriEdgeHdl = iconSet{end + 1 - i}; tNewFaceHdl = copy(newFaceHdl); C = oriEdgeHdl.ColorData; if strcmp(style, 'w') tNewFaceHdl.ColorData = uint8([CCC((j-1)/19*2-1, double(C(1)), 204 + double(C(1)).*.2); ... CCC((j-1)/19*2-1, double(C(2)), 204 + double(C(2)).*.2); ... CCC((j-1)/19*2-1, double(C(3)), 204 + double(C(3)).*.2); 255]); else tNewFaceHdl.ColorData = uint8([CCC((j-1)/19*2-1, 76.5, double(C(1))); ... CCC((j-1)/19*2-1, 76.5, double(C(2))); ... CCC((j-1)/19*2-1, 76.5, double(C(3))); 255]); end tNewFaceHdl.Parent = oriEdgeHdl.Parent; end end for i = 1:length(barHdl) oriEdgeHdl = iconSet{end + 1 - i}; oriEdgeHdl.Visible = 'off'; end lgdHdl.AutoUpdate = 'off'; end end
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。