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,:);
end

legend({'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,:);
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
% 感谢 @明知是意外 的测试,修正了R2023a及之前版本由于CData属性不自动更新导致的上色bug

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).FaceColor(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).FaceColor(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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MVCC(解决MySql中的并发事务的隔离性)

MVCC 如何保证事务的隔离性&#xff1f; 1.排他锁&#xff1a;如一个事务获取了一个数据行的排他锁&#xff0c;其他事务就不能再获取改行的其他锁。 2.MVCC&#xff1a;多版本并发控制。 MVCC&#xff1a; 1.隐藏字段 1.DB_TRX_ID&#xff1a;最近修改事务的id。默认值从0开…

4.9总结(Stream流,方法引用概述 || 乘法逆元,组合数)

Stream流 基本概念&#xff1a;以更简便的方式操作集合数据的形式&#xff1b; Steam流的操作步骤&#xff1a; 获取Stream流 中间方法&#xff1a;去重&#xff0c;跳过&#xff0c;获取&#xff0c; 过滤&#xff0c; 合并流&#xff0c;转换类型&#xff1b; 终结方法&…

黑马鸿蒙学习5:渲染foreach

foreach是用来循环渲染界面用的&#xff0c;比如&#xff1a;语法是先定义一个数组&#xff0c;如上图&#xff1a; 其中的keygenerator&#xff0c;其实意思是说&#xff0c;如果要渲染的内容发生了变化&#xff0c;则由于有独特的标识&#xff0c;可以 减少渲染次数。 实例&a…

【linux深入剖析】深入理解基础外设--磁盘以及理解文件系统

&#x1f341;你好&#xff0c;我是 RO-BERRY &#x1f4d7; 致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 &#x1f384;感谢你的陪伴与支持 &#xff0c;故事既有了开头&#xff0c;就要画上一个完美的句号&#xff0c;让我们一起加油 目录 前言1.磁盘物理结构2.磁盘…

【数据结构】04串

串 1. 定义2. 串的比较3. 串的存储结构4. 具体实现5. 模式匹配5.1 常规思路实现5.2 KMP模式匹配算法5.2.1 next数组计算5.2.1 代码计算next数组5.2.2 KMP算法实现 1. 定义 串(string)是由零个或多个字符组成的有限序列&#xff0c;又叫字符串。 一般记为s a 1 , a 2 , . . . ,…

软件供应链安全:寻找最薄弱的环节

在当今的数字时代&#xff0c;软件占据主导地位&#xff0c;成为全球组织业务和创新的支柱。它是差异化、项目效率、成本降低和竞争力背后的驱动力。软件决定了企业如何运营、管理与客户、员工和合作伙伴的关系&#xff0c;以及充分利用他们的数据。 挑战在于&#xff0c;当今…

【MVCC】深入浅出彻底理解MVCC

MVCC概述 MVCC&#xff08;Multi-Version Concurrency Control&#xff09;即多版本并发控制。主要是为了提高数据库的并发性能而提供的&#xff0c;采用了不加锁的方式处理读-写并发冲突&#xff0c;确保了任何时刻的读操作都是非阻塞的。只需要很小的开销&#xff0c;就可以…

电视盒子哪个好?2024口碑网络电视盒子排行榜

多年来电视盒子始终占据重要地位&#xff0c;功能上并没有受到影响。在这么多品牌中哪些电视盒子的评价是最好的呢&#xff1f;小编根据各大电商平台的用户评价情况整理了口碑最好的网络电视盒子排行榜&#xff0c;跟着小编一起看看市面上的电视盒子哪个好吧。 TOP 1&#xff1…

如何访问远程MySQL数据库?

远程访问MySQL数据库是在不同设备之间实现数据交互的一种方式。通过远程访问&#xff0c;用户可以轻松地操作远程MySQL数据库&#xff0c;从而实现数据的读写、修改和查询等操作。本文将介绍远程访问MySQL数据库的原理和实现方法&#xff0c;以及一种被广泛应用的解决方案【天联…

[入门到放弃]设计模式-笔记

模块化设计 20240448 模块不包含数据&#xff0c;通过实例的指针&#xff0c;实现对实例的操作&#xff1b;唯一包含的数据是用于管理这些模块的侵入式链表模块只负责更具定义的数据结构&#xff0c;执行对应的逻辑&#xff0c;实现不同实例的功能&#xff1b; 参考资料 使用…

TCP/IP协议—UDP

TCP/IP协议—UDP UDP协议UDP通信特点 UDP头部报文UDP检验 UDP协议 用户数据传输协议 (UDP&#xff0c;User Datagram Protocol) 是一种无连接的协议&#xff0c;提供了简单的数据传输服务&#xff0c;不保证数据的顺序以及完整性。应用层很多通信协议都基于UDP进行传输&#x…

[当人工智能遇上安全] 13.威胁情报实体识别 (3)利用keras构建CNN-BiLSTM-ATT-CRF实体识别模型

《当人工智能遇上安全》系列将详细介绍人工智能与安全相关的论文、实践&#xff0c;并分享各种案例&#xff0c;涉及恶意代码检测、恶意请求识别、入侵检测、对抗样本等等。只想更好地帮助初学者&#xff0c;更加成体系的分享新知识。该系列文章会更加聚焦&#xff0c;更加学术…

最新常见的图数据库对比,选型,架构,性能对比

图数据库排名 地址&#xff1a;https://db-engines.com/en/ranking/graphdbms 知识图谱查询语言 SPARQL、Cypher、Gremlin、PGQL 和 G-CORE 语法 / 语义 / 特性SPARQLCypherGremlinPGQLG-CORE图模式匹配查询语法CGPCGPCGP(无可选)1CGPCGP语义子图同态、包 2无重复边、包 2子…

大唐极简史

唐朝&#xff08;618年-907年&#xff09;&#xff0c;是中国历史上一个强盛的朝代&#xff0c;以其疆域辽阔、政治稳重、经济繁荣、文化繁荣而著称。唐朝的开国皇帝是李渊&#xff0c;他建立了一个强大的中央集权政府&#xff0c;使得唐朝成为当时世界上最繁荣的国家之一。 唐…

vmware虚拟机补救

更新了虚拟机里面工具和资料&#xff0c;进行了磁盘整理和压缩&#xff0c;虚拟机运行进不去系统了。 网站找的修复方法均不可行。补救措施&#xff1a;利用DiskGenius.exe&#xff08;要用高版本不然复制的时候就知道了&#xff09; DG1342.rar - 蓝奏云 加载虚拟硬盘 2008x…

最新微信支付商家转账到零钱各场景怎样开通?

商家转账到零钱是什么&#xff1f; 商家转账到零钱是企业付款到零钱的升级版&#xff0c;它的功能是&#xff0c;如果系统需要对用户支付费用&#xff0c;比如发放佣金、提成、退款等&#xff0c;可以直接转账到用户的微信零钱。这个功能在 2022 年 5 月 18 日之前叫做企业付款…

2024年MathorCup数模竞赛B题问题一二三+部分代码分享

inputFolderPath E:\oracle\images\; outputFolderPath E:\oracle\process\; % 获取文件夹中所有图片的文件列表 imageFiles dir(fullfile(inputFolderPath, *.jpg)); % 设置colorbar范围阈值 threshold 120; % 遍历每个图片文件 for i 1:length(imageFiles) % 读…

个人网站制作 Part 18 提升用户体验:添加页面404错误处理 | Web开发项目

文章目录 &#x1f469;‍&#x1f4bb; 基础Web开发练手项目系列&#xff1a;个人网站制作&#x1f680; 添加404错误处理页面&#x1f528;创建404错误处理页面&#x1f527;步骤 1: 在项目根目录创建404错误处理页面&#x1f527;步骤 2: 添加404错误处理页面内容 &#x1f…

数据结构复习指导之绪论(数据结构的基本概念)

文章目录 绪论&#xff1a; 考纲内容 知识框架 复习提示 1.数据结构的基本概念 1.1基本概念和术语 1.数据 2.数据元素 3.数据对象 4.数据类型 5.数据结构 1.2数据结构三要素 1.数据的逻辑结构 2.数据的存储结构 3.数据的运算 绪论&#xff1a; 考纲内容 算法时…

计算机网络----第十天

配置vlan 广播风暴的含义&#xff1a; 含义&#xff1a;设备发出的广播帧在广播域中传播&#xff0c;占用网络带宽&#xff0c;降低设备性能 隔离广播的方式&#xff1a; 方式&#xff1a;用路由器来隔离广播 用VLN隔离广播 vlan的定义&#xff1a; 定义&#xff1a;虚拟…