Matlab柱状图进阶:从基础bar到自定义配色与多图例布局(附实战代码)

张开发
2026/4/18 17:10:46 15 分钟阅读

分享文章

Matlab柱状图进阶:从基础bar到自定义配色与多图例布局(附实战代码)
1. Matlab柱状图基础从bar函数开始如果你是第一次接触Matlab的柱状图绘制bar函数就是你的起点。这个看似简单的函数其实蕴含着丰富的可能性就像搭积木一样基础模块越扎实后期能搭建的作品就越精彩。我刚开始用Matlab画图时最常犯的错误就是直接调用bar(y)就完事了。后来才发现这样画出来的图表在学术报告中显得太学生气。让我们先看看最基本的用法y [75 91 105 123.5 131 150 179 203 226 249 281.5]; bar(y)这段代码会生成一个简单的柱状图x轴自动从1开始编号y轴对应数据值。但实际应用中我们往往需要更精确的控制。比如指定x轴位置x 1900:10:2000; bar(x,y)这里x和y的长度必须一致否则Matlab会报错。我在处理时间序列数据时就犯过这个错误当时调试了好久才发现是数据长度不匹配的问题。bar函数还有几个常用参数值得注意width控制柱宽默认0.8大于1会使柱子重叠style可以是grouped(默认)或stacked(堆叠)color可以用字符简写(r红色)或RGB三元组([1 0 0])2. 自定义配色方案让你的图表脱颖而出科研图表最忌讳的就是千篇一律的默认配色。Matlab提供了多种自定义颜色的方法我总结了几种最实用的技巧。2.1 使用预定义颜色最简单的就是使用单色方案bar(y,r) % 红色柱子或者更精细地控制边框和填充bar(y,FaceColor,[0 .5 .5],EdgeColor,[0 .9 .9],LineWidth,1.5)这里[0 .5 .5]是RGB颜色分别代表红绿蓝分量取值0-1。我常用这个网站来挑选合适的RGB值https://rgbcolorcode.com2.2 为每个柱子单独着色有时候我们需要突出显示某个特定柱子比如最大值或异常值b bar(rand(10,1)); b.FaceColor flat; b.CData(2,:) [.5 0 .5]; % 第二个柱子紫色这个技巧在我标注显著性差异时特别有用。记得一定要先把FaceColor设为flat否则CData不会生效。2.3 使用colormap配色对于多组数据使用colormap可以让图表更专业y [1 3 5; 3 2 7; 3 4 2]; b bar(y,FaceColor,flat); colormap(parula) % 使用parula色图 for k 1:size(y,2) b(k).CData k; endMatlab内置了很多漂亮的colormap比如parula、jet、hsv等。我个人最喜欢的是parula它在黑白打印时也能保持很好的灰度对比。3. 多图例布局技巧当图表包含多组数据时合理的图例布局能让读者更快理解你的意图。我见过太多把图例随便一放就完事的例子这真的很影响图表专业性。3.1 基础图例添加最简单的图例添加方式y [2 2 3; 2 5 6; 2 8 9; 2 11 12]; bar(y) legend(算法A,算法B,算法C,Location,best)Location参数控制图例位置常用值有north - 图顶部south - 图底部east - 图右侧west - 图左侧best - 自动选择最佳位置3.2 分栏图例当图例项太多时可以考虑分栏显示lgd legend(算法1,算法2,算法3,算法4,算法5); lgd.NumColumns 2; % 两栏显示这个功能需要Matlab 2018b或更新版本。在写论文时我经常需要比较多种算法分栏图例能有效节省空间。3.3 自定义图例内容有时候自动生成的图例不够直观我们可以完全自定义h bar(rand(5,3)); legend([h(1),h(3)],{重要数据,参考数据}) % 只显示部分图例这个技巧在我需要突出显示关键数据时特别有用。你还可以用annotation函数添加更复杂的标注。4. 实战案例完整的科研级柱状图让我们把这些技巧综合起来创建一个适合发表的柱状图。假设我们要比较三种算法在四个数据集上的性能。% 准备数据 data [0.85 0.91 0.78; 0.72 0.88 0.81; 0.68 0.79 0.75; 0.92 0.95 0.89]; datasetNames {文本分类,目标检测,语义分割,实例分割}; algorithmNames {我们的方法,基准方法A,基准方法B}; % 创建图形 figure(Position,[100 100 800 500]) % 设置图形大小 % 绘制柱状图 b bar(data,FaceColor,flat); colormap(summer) % 使用summer色图 % 自定义柱子颜色 for k 1:size(data,2) b(k).CData k; end % 添加标签和标题 set(gca,XTickLabel,datasetNames,FontSize,12) ylabel(准确率,FontSize,14) title(三种算法在不同任务上的性能比较,FontSize,16) % 添加图例 lgd legend(algorithmNames,Location,northeast); lgd.FontSize 12; % 调整坐标轴 ylim([0.6 1]) grid on % 添加数值标签 for i 1:length(b) xtips b(i).XEndPoints; ytips b(i).YEndPoints; labels string(round(b(i).YData,2)); text(xtips,ytips,labels,HorizontalAlignment,center,... VerticalAlignment,bottom,FontSize,10) end这段代码展示了几个关键技巧明确设置图形大小确保导出图片尺寸合适使用有区分度的colormap添加清晰的轴标签和标题在柱子上方显示具体数值使用网格线提高可读性导出图片时我推荐使用exportgraphics函数(需要R2020a)exportgraphics(gcf,result.png,Resolution,300) % 300dpi高清图或者传统的print函数print(-dpng,-r300,result.png)5. 常见问题与解决方案在实际使用中我遇到过不少坑这里分享几个典型问题的解决方法。5.1 柱子宽度不一致当x值不均匀时柱子宽度可能会出现异常x [1 2 4 8 16]; % 不均匀的x值 y rand(size(x)); bar(x,y) % 柱子宽度会不一致解决方法是指定绝对宽度bar(x,y,0.8) % 固定宽度或者改用stem函数绘制针状图。5.2 堆叠柱状图的标签问题堆叠柱状图的数值标签容易重叠y [2 2 3; 2 5 6; 2 8 9; 2 11 12]; b bar(y,stacked);解决方法是为每个部分单独添加标签for k 1:length(b) xpos b(k).XEndPoints; ypos b(k).YEndPoints; labels string(b(k).YData); text(xpos,ypos,labels,HorizontalAlignment,center,... VerticalAlignment,bottom) end5.3 大数量柱子的显示问题当柱子数量很多时(比如超过50个)默认显示会很拥挤y rand(100,1); bar(y) % 非常拥挤几种解决方案使用旋转x轴标签set(gca,XTickLabelRotation,45)减小字体大小set(gca,FontSize,8)考虑改用折线图或热图6. 高级技巧交互式柱状图Matlab还支持创建交互式图表这在演示时特别有用。6.1 数据提示自定义y rand(5,3); b bar(y); % 自定义数据提示 for i 1:length(b) b(i).DataTipTemplate.DataTipRows(1).Label 数据集; b(i).DataTipTemplate.DataTipRows(2).Label 准确率; b(i).DataTipTemplate.DataTipRows(1).Value string(1:5); b(i).DataTipTemplate.DataTipRows(2).Value b(i).YData; b(i).DataTipTemplate.DataTipRows(1).Format %.0f; b(i).DataTipTemplate.DataTipRows(2).Format %.2f; end现在当鼠标悬停在柱子上时会显示更丰富的信息。6.2 添加回调函数我们可以让柱子点击时执行特定操作function barClickCallback(src,event) disp([你点击了第 num2str(event.DataIndex) 个柱子]); end y rand(10,1); b bar(y); b.ButtonDownFcn barClickCallback;这个技巧在我开发数据探索工具时非常有用可以关联其他图表实现联动更新。6.3 创建动态更新图表对于实时数据监控我们需要动态更新柱状图figure h bar(nan(5,1)); % 预分配 xlabel(传感器) ylabel(读数) for i 1:100 newData rand(5,1); % 模拟新数据 h.YData newData; drawnow pause(0.5) % 0.5秒更新一次 end这种动态图表在展示实时实验结果时特别有效。记得使用drawnow强制刷新图形。

更多文章