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

news2024/11/28 18:55:27

之前写了一篇文章说明了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
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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL学习笔记------事务

事务 事务是一组操作的集合&#xff0c;他是一个不可分割的单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败 事务操作 create table account(id int comment ID,name varchar(10) …

怎样恢复已删除的照片?教你3个方法,一键恢复!

很多人喜欢以拍照的形式记录生活&#xff0c;手机里的照片就很容易堆积成山&#xff0c;但当内存不够用时就不得不选择删除。可是这些美好的照片始终是很多人心中抹不去的记忆&#xff0c;那么该怎样恢复已删除的照片呢&#xff1f;下面几招&#xff0c;教你一键恢复&#xff0…

基于opencv的猫脸识别模型

opencv介绍 OpenCV的全称是Open Source Computer Vision Library&#xff0c;是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起并参与开发&#xff0c;以BSD许可证授权发行&#xff0c;可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理、计算机视觉以及…

使用美化方法设计项目主窗体(二)

使用美化方法设计项目主窗体 分析效果图的实现 效果图&#xff1a; 新建 Windows 窗体 新窗体命名&#xff1a;FrmMain.cs修改窗体的位置&#xff1a;StartPosition&#xff1a;CenterScreen窗体的无边框设计&#xff1a;FormBorderStyle&#xff1a;none修改窗体的大小&a…

JDK下载及安装说明

1&#xff0e;JDK下载 访问oracle官网&#xff1a;http://www.oracle.com 在首页点击Downloads&#xff0c;进入oracle软件下载页。 在下载页面&#xff0c;点击Java。 选择Java (JDK) for Developers&#xff0c;点击。 在 Java SE Downloads 页面&#xff0c;点击中间的DO…

如何挂载img镜像以及lvm分区

上一章节&#xff0c;我在win10下利用qemu安装了一个aarch64的 kylin-server-v10的ISO系统镜像包。安装时将系统安装到了虚拟硬盘kylin-server-v10.img 里&#xff0c;现在有个需求&#xff0c;要读出kylin-server-v10.img中文件系统的内容。 通过fdisk命令可以看到 kylin-ser…

Docker容器(六)网络配置与数据卷

一、高级网络配置 1.1概述 当 Docker 启动时&#xff0c;会自动在主机上创建一个 docker0 虚拟网桥&#xff0c;实际上是 Linux 的一个 bridge&#xff0c;可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。 同时&#xff0c;Docker 随机分配一个本地未占用的私有…

位置编码学习

基本概念 关于位置编码的一切&#xff1a;https://kexue.fm/archives/8130#T5%E5%BC%8F 残差连接 Post Norm 关注深度 残差的意思是给前面的层搞一条“绿色通道”&#xff0c;让梯度可以更直接地回传&#xff0c;但是在Post Norm中&#xff0c;这条“绿色通道”被严重削弱…

助贷行业的业务增长工具:CRM客户管理系统的核心作用与应用流程

在当前助贷行业&#xff0c;企业如何更好地抓住客户需求、提高业务效率、优化服务体验一直是助贷企业关注的焦点。在这个背景下&#xff0c;一款优秀的CRM客户管理系统无疑成为了实现这些目标的关键。本文将探讨这样一款专为助贷行业打造的CRM客户管理系统&#xff0c;看它是如…

极市平台 | 综述:一文详解50多种多模态图像融合方法

本文来源公众号“极市平台”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;综述&#xff1a;一文详解50多种多模态图像融合方法 0 极市导读 本工作总结了50篇论文中Lidar和camera的多模态融合的一些概念方法。笔者结合原文以及自…

重庆餐饮设计公司排行榜曝光,这些企业值得关注!

在如今饮食文化多元化、餐饮产业蓬勃发展的时代&#xff0c;餐饮设计企业扮演着至关重要的角色。一个好的餐厅设计可以为顾客提供舒适、美观的用餐环境&#xff0c;也能够提升餐厅的整体形象和竞争力。重庆作为中国西南地区的经济中心和旅游胜地&#xff0c;餐饮业发展迅速&…

用二八定律分析零售数据,不就更直观了吗?

20%的商品贡献了80%的销售金额&#xff0c;你会不会想知道这些商品的销售金额、毛利、销售金额累计占比、毛利累计占比&#xff0c;会不会想知道这些商品在各个门店的销售表现&#xff1f;看是否能进一步提高销售金额&#xff0c;提高毛利。这样的报表该怎么做&#xff1f;奥威…

JVM高级篇之GC

文章目录 版权声明垃圾回收器的技术演进ShenandoahShenandoah GC体验Shenandoah GC循环过程 ZGCZGC简介ZGC的版本更迭ZGC体验&使用ZGC的参数设置ZGC的调优 版权声明 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明&#xff0c;所有版权属于黑马…

Vue - 你知道Vue中computed和watch的区别吗

难度级别:中高级及以上 提问概率:70% 二者都是用来监听数据变化的,而且在日常工作中大部分时候都只是局限于简单实用,所以到了面试中很难全面说出二者的区别。接下来我们看一下,二者究竟有哪些区别呢? 先说computed,它的主要用途是监听…

Java中网络编程,Junit单元测试详解

文章目录 软件结构C/S结构B/S结构 概述三要素IP &#xff08;银行的位置&#xff09;端口 (银行中某个柜台号)协议 (填写取款单的规则)TCP通信程序TCP通信原理客户端发送数据服务端接收数据过程图三次握手 Junit单元测试概述常见的注解使用断言概述使用 软件结构 C/S结构 客户…

Windows深度学习环境----Cuda version 10.2 pytorch3d version 0.3.0

Requirements Python version 3.8.5Pytorch version: pytorch1.6.0 torchvision0.8.2 torchaudio0.7.0 cudatoolkit10.2.89pytorch3d version 0.3.0Cuda version 10.2 感觉readme文件里的不适配&#xff0c;跟pytorch官网不同 以前的 PyTorch 版本 |PyTorch的 # CUDA 10.2 c…

HDLbits 刷题 --Popcount255

A "population count" circuit counts the number of 1s in an input vector. Build a population count circuit for a 255-bit input vector. 译&#xff1a; 一个“population count”电路用于计算输入向量中1的数量。为一个255位的输入向量构建一个人口计数电路…

【免费使用AI工具】国内AI网站集合

文章目录 文心一言腾讯混元助手讯飞星火认知大模型:文心一格(绘图)云雀大模型(文本对话)智谱AI:(GLM大模型)百川智能(百川大模型)MiniMax(ABAB大模型)万维天工ChatGPT3.5镜像网站通义千问文心一言 https://yiyan.baidu.com/ 腾讯混元助手 微信搜索【腾讯混元助手】小…

金蝶BI方案的报表,主打做得快、易理解

金蝶做数据分析报表慢、步骤多、数据不够直观&#xff1f;但奥威-金蝶BI方案的报表就不一样了&#xff0c;不仅做得快&#xff0c;还十分好理解&#xff0c;因为它做出来的是随时可以按需自助的BI智能数据可视化分析报表。 有多快&#xff1f; 注册奥威BI SaaS平台&#xff0…

提升Python网络编程效率:深入学习furl库

&#x1f340; 前言 博客地址&#xff1a; CSDN&#xff1a;https://blog.csdn.net/powerbiubiu &#x1f44b; 简介 furl 是一个 Python 库&#xff0c;用于处理 URL。它提供了一个简洁而强大的接口&#xff0c;用于构建、解析和操作 URL。本文章介绍下 furl 库的使用。 &a…