MATLAB | 怎样绘制更有立体感的柱状图

之前写了一篇文章说明了MATLAB图例可以自己diy,这次又有了diy的机会,我开发了一个简单的小工具,能够实现绘制伪3d的柱状图,大概效果如下:


使用说明

由于涉及的代码比较接近MATLAB底层的图形对象,有点东西还是没倒腾明白,目前使用起来还是有以下几个点要注意:

  • 如果是R2024a版本,绘制结束后请勿大幅度改变画布大小,否则图例会被刷掉(因此也最好在最后使用工具函数),应该会需要通过addlistener解决但目前还未完成倒腾出来,R2024a之前版本不会出这个Bug(属实是不知道新版本改了什么地方引起的这个Bug)
  • 请使用至少R2019b版本,以前版本柱状图会缺一点属性
  • 柱状图请绘制在最下方(为了使最新版也能顺利使用用了一些不得已的手段,导致柱状图必须绘制在最下方)

另外本文中一部分图片使用了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柱状图工具放在文末,现在先来讲解一下用法:


使用教程

1 基本使用

假如绘制了柱状图:

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')


2 支持的柱状图格式

基本上所有类型柱状图均可支持:

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')


3 更换颜色

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,:);
endlegend({'A','B','C'}, 'FontSize',13);
SAxes()
bar2_5D(barHdl, 'k')


4 有误差棒示例

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';


5 有区域高亮示例

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,:);
endlegend()
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,:);
endlegend()
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 < 2style = 'w';
end% 基础属性计算
if Ver < 24GroupWidth = 2/3;
elseGroupWidth = barHdl(1).GroupWidth;
end
if length(barHdl) > 1 && ~strcmp(barHdl(1).BarLayout, 'stacked')BarWidth = GroupWidth.*barHdl(1).BarWidth./length(barHdl);
elseBarWidth = 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));elseCMesh = cat(3, CCC(XMesh, .3, C(1)), ...CCC(XMesh, .3, C(2)), ...CCC(XMesh, .3, C(3)));endif 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);elsetX = XMesh.*BarWidth./2 + barHdl(i).XEndPoints(j);tY = YMesh.*barHdl(i).YData(j) + barHdl(i).YEndPoints(j) - barHdl(i).YData(j);endsurfHdl = 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
endfor 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:GraphicsNumuistack(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:20newFaceHdl = 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]);elsetNewFaceHdl.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]);endtNewFaceHdl.Parent = oriEdgeHdl.Parent;end
end
for i = 1:length(barHdl)oriEdgeHdl = iconSet{end + 1 - i};oriEdgeHdl.Visible = 'off';
end
lgdHdl.AutoUpdate = 'off';
end
end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/600698.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt使用iostream的cout

在QT想使用iostream的cout。 参考以下博客&#xff1a; &#xff08;转载&#xff09;Qt中使用cout输出的方法 pro里加上; CONFIG console勾选 Run in Terminal clean工程&#xff0c;重新构建 上面是cout的&#xff0c;下面是我的另一个函数的qDebug输出的。

Set及其实现类与常用方法

1.Set及其常用实现类 Set接口是java.util.Collection接口的子接口.用来存储一个一个的数据.后面学习到的Map接口则用来存储key-value键值对. Set : 存储无序的,不可重复的数据|----->HashSet : 主要实现类 : 底层使用的是HashMap,即使用数组单向链表红黑树来存储。|-----&…

数据挖掘及其近年来研究热点介绍

&#x1f380;个人主页&#xff1a; https://zhangxiaoshu.blog.csdn.net &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️&#xff0c;如有错误敬请指正! &#x1f495;未来很长&#xff0c;值得我们全力奔赴更美好的生活&…

如何实现异地公网环境访问本地部署的支付宝沙箱环境调试支付SDK

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

OpenHarmony实战:轻量系统STM32F407芯片移植案例

介绍基于STM32F407IGT6芯片在拓维信息Niobe407开发板上移植OpenHarmony LiteOS-M轻量系统&#xff0c;提供交通、工业领域开发板解决方案。 移植架构采用Board与SoC分离方案&#xff0c;使用arm gcc工具链Newlib C库&#xff0c;实现了lwip、littlefs、hdf等子系统及组件的适配…

数据同步工具datax配置与示例

文章目录 前言一、部署步骤1、jdk环境2、python环境步骤一&#xff1a;安装方式一&#xff1a;官网下载安装包方式二&#xff1a;brew命令安装 步骤二&#xff1a;配置环境变量步骤三&#xff1a;验证 3、maven环境&#xff08;可选&#xff09; 二、下载安装datax1、下载datax…

前端自动化测试-Jest

前端自动化测试 Jest官网&#xff1a;https://jestjs.io 安装方式 npm install --save-dev jest yarn add --dev jest cnpm add --save-dev jest 使用方法 所有以 .test.js 结尾的都是测试文件 基础用法示例 num.js&#xff1a; export function getSum (a, b) {return a b…

【三十七】【算法分析与设计】STL 练习,凌波微步,栈和排序,吐泡泡,[HNOI2003]操作系统,优先队列自定义类型

凌波微步 链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 时间限制&#xff1a;C/C 1 秒&#xff0c;其他语言 2 秒 空间限制&#xff1a;C/C 32768K&#xff0c;其他语言 65536K 64bit IO Format: %lld 题目描述 小 Z 的体型实在是太胖了&…

24 个Intellij IDEA好用插件

24 个Intellij IDEA好用插件 一. 安装插件 Codota 代码智能提示插件 只要打出首字母就能联想出一整条语句&#xff0c;这也太智能了&#xff0c;还显示了每条语句使用频率。 原因是它学习了我的项目代码&#xff0c;总结出了我的代码偏好。 Key Promoter X 快捷键提示插件 …

【随笔】Git 高级篇 -- 提交的技巧(上) rebase commit --amend(十八)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

TCP三次握手,四次挥手

TCP为什么四次挥手&#xff1f;而不是三次&#xff1f; 正常流程&#xff1a;服务接收到 客户端的 FIN请求后&#xff0c;会发送一个ACK响应&#xff0c;等待系统资源释放后&#xff0c;再发送FIN 请求给客户端&#xff0c;客户端再发送一个ACK响应。 若为三次&#xff1a;就是…

Stable Diffusion文生图技术详解:从零基础到掌握CLIP模型、Unet训练和采样器迭代

文章目录 概要Stable Diffusion 底层结构与原理文本编码器&#xff08;Text Encoder&#xff09;图片生成器&#xff08;Image Generator&#xff09; 那扩散过程发生了什么&#xff1f;stable diffusion 总体架构主要模块分析Unet 网络采样器迭代CLIP 模型 小结 概要 Stable …