1. 前言
在数学建模、数据分析以及方案评价过程中,我们经常需要同时考虑多个评价指标。例如在物资配送方案选择中,可能需要综合考虑成本、运输距离、风险水平、调度难度以及实施周期等因素。
如果直接使用传统的柱状图、折线图展示这些信息,当指标较多、方案较多时,图表容易显得比较杂乱。
因此,本文使用 MATLAB 绘制一种比较直观的可视化图表——华夫图(Waffle Chart),将不同配送方案在多个评价指标下的等级情况进行可视化展示。
最终实现的效果可以直观反映:
- 不同方案的成本等级;
- 不同方案的运输距离;
- 不同方案的风险水平;
- 不同方案的调度难度;
- 不同方案的实施周期。
2. 什么是华夫图?
华夫图(Waffle Chart)是一种由大量规则小方格组成的可视化图表。
它最常用于表示:
- 比例;
- 占比;
- 分类结果;
- 等级信息;
- 多类别数据。
与饼图相比,华夫图具有更加规整的视觉效果;而与传统柱状图相比,它也能够更加直观地表现不同类别之间的对应关系。
本文中的数据并不是百分比数据,而是将不同方案在不同评价指标下的定性等级信息转换为颜色,从而利用华夫图进行可视化。
3. 数据准备
首先构造原始数据:
rawData = {
'方案1','中成本','远距离','中风险','难度中等','中期';
'方案2','高成本','近距离','高风险','难度大','短期';
'方案3','低成本','近距离','低风险','难度小','长期';
'方案4','高成本','远距离','中风险','难度大','中期';
'方案5','中成本','近距离','中风险','难度中等','短期';
'方案6','低成本','远距离','低风险','难度小','长期';
'方案7','极高成本','远距离','高风险','难度大','中期';
};
这里每一行代表一个配送方案,每一列代表一个评价指标。
数据结构如下:
| 方案 | 成本 | 运输距离 | 风险水平 | 调度难度 | 实施周期 |
|---|---|---|---|---|---|
| 方案1 | 中成本 | 远距离 | 中风险 | 难度中等 | 中期 |
| 方案2 | 高成本 | 近距离 | 高风险 | 难度大 | 短期 |
| 方案3 | 低成本 | 近距离 | 低风险 | 难度小 | 长期 |
| 方案4 | 高成本 | 远距离 | 中风险 | 难度大 | 中期 |
| 方案5 | 中成本 | 近距离 | 中风险 | 难度中等 | 短期 |
| 方案6 | 低成本 | 远距离 | 低风险 | 难度小 | 长期 |
| 方案7 | 极高成本 | 远距离 | 高风险 | 难度大 | 中期 |
然后提取评价指标数据:
data = rawData(:,2:6);
这里的 rawData(:,2:6) 表示提取第 2 列到第 6 列,也就是去掉第一列的方案名称,只保留评价指标。
4. 设置图表颜色
为了让不同等级能够通过颜色进行区分,首先定义颜色矩阵:
C = [
0 0.2745 0.5451
0.9294 0 0
0.2588 0.7098 0.2510
0 0.6000 0.7059
0.5725 0.3686 0.6235
0.9922 0.6863 0.5686
0.6784 0 0.1647
0.6784 0.7137 0.7137
0.1059 0.0980 0.0980
];
MATLAB 中的 RGB 颜色通常使用:
[R G B]
表示。
例如:
[1 0 0]
表示红色;
[0 1 0]
表示绿色;
[0 0 1]
表示蓝色。
这里使用的是 0~1 范围内的 RGB 数值,因此可以根据需要自定义更加适合论文和博客的配色。
5. 设置图片尺寸
为了让最终生成的图片适合论文、CSDN博客以及其他文档使用,这里将图片尺寸设置为 16 cm × 9 cm:
figureUnits = 'centimeters';
figureWidth = 16;
figureHeight = 9;
然后设置 MATLAB 窗口:
figureHandle = figure;
set(gcf, ...
'Units', figureUnits, ...
'Position', [0 0 figureWidth figureHeight]);
这里:
Units:设置单位;Position:设置窗口的位置和大小;gcf:获取当前 Figure 窗口。
6. 绘制华夫图
核心代码如下:
[h_surf,u1,u2,u3] = waffle(data,2);
这里使用了 waffle() 函数绘制华夫图。
需要注意的是,waffle 并不是 MATLAB 最基础的内置绘图函数,如果运行代码时 MATLAB 提示找不到 waffle 函数,需要先将对应的 waffle.m 文件加入 MATLAB 当前路径。
同时设置横纵坐标:
hXLabel = xlabel('评价指标');
hYLabel = ylabel('备选方案');
最终图中的横轴对应评价指标,纵轴对应不同的备选方案。
7. 设置颜色映射
前面定义了颜色矩阵 C,这里通过索引调整颜色的使用顺序:
idx = [2 1 3 5 4 6 7 8 9];
map = C(idx,1:3);
colormap(map)
其中:
C(idx,1:3)
相当于按照 idx 指定的顺序重新排列颜色。
这样做的好处是,可以根据实际数据类别的顺序调整图中的颜色,而不需要重新修改整个颜色矩阵。
8. 设置坐标轴
为了让图表更加规整:
axis tight equal
其中:
tight:让坐标轴范围尽可能贴合数据;equal:让横纵坐标单位长度保持相同。
然后进一步设置坐标轴位置:
set(gca, ...
'xaxislocation','bottom', ...
'yaxislocation','left', ...
'YDir','reverse', ...
'xtick',1:5, ...
'ytick',1:7, ...
'Xticklabel',{'成本等级','运输距离','风险水平','调度难度','实施周期'}, ...
'Yticklabel',{'方案1','方案2','方案3','方案4','方案5','方案6','方案7'})
这里的 gca 表示获取当前坐标轴。
其中:
'xtick',1:5
表示横坐标设置 5 个刻度。
对应的标签为:
{'成本等级','运输距离','风险水平','调度难度','实施周期'}
纵坐标则对应 7 个配送方案。
另外:
'YDir','reverse'
可以将纵坐标方向反转,使方案1显示在最上方,更符合阅读习惯。
9. 设置图例
图例是华夫图中非常重要的一部分。
代码如下:
hLegend = legend(h_surf(u2(idx)),u1(idx), ...
'FontWeight','normal', ...
'FontSize',9, ...
'Box','off', ...
'Location', 'eastoutside', ...
'Orientation','vertical');
这里主要设置了:
FontWeight:字体不加粗;FontSize:字体大小;Box:取消图例边框;Location:将图例放在图形右侧;Orientation:设置为纵向排列。
同时:
hLegend.ItemTokenSize = [10 10];
用于调整图例中颜色标识的大小。
这样可以避免图例中的色块过大或者过小,使整体更加协调。
10. 设置中文字体
MATLAB 绘图时,如果没有正确设置中文字体,有时会出现中文乱码或者字体显示异常。
这里使用黑体:
set(gca, 'FontSize', 9, 'FontName', 'SimHei')
set([hXLabel, hYLabel], ...
'FontSize', 11, ...
'FontName', 'SimHei')
其中:
'FontName','SimHei'
表示使用黑体。
如果电脑没有安装 SimHei,也可以根据自己的电脑情况修改为:
'Microsoft YaHei'
或者其他已经安装的中文字体。
11. 画布美化
为了让最终图片的背景更加简洁:
set(gcf,'Color',[1 1 1])
将 Figure 背景设置为白色。
然后:
set(gca,'LooseInset',get(gca,'TightInset'))
用于调整坐标轴周围的留白。
这样可以减少图形周围不必要的空白区域,使导出的图片更加紧凑。
12. 高清图片导出
最后将图片导出为 PNG:
figW = figureWidth;
figH = figureHeight;
set(figureHandle,'PaperUnits',figureUnits);
set(figureHandle,'PaperPosition',[0 0 figW figH]);
fileout = '物资配送方案_华夫图';
print(figureHandle,[fileout,'.png'],'-r300','-dpng');
这里:
-r300
表示使用 300 DPI 的分辨率导出。
对于论文、数学建模报告以及 CSDN 博客配图来说,300 DPI 通常能够满足比较好的清晰度要求。
最终生成的文件名称为:
物资配送方案_华夫图.png
13. 完整代码
下面给出完整 MATLAB 代码:
clc, clear, close all
%% 数据
rawData = {
'方案1','中成本','远距离','中风险','难度中等','中期';
'方案2','高成本','近距离','高风险','难度大','短期';
'方案3','低成本','近距离','低风险','难度小','长期';
'方案4','高成本','远距离','中风险','难度大','中期';
'方案5','中成本','近距离','中风险','难度中等','短期';
'方案6','低成本','远距离','低风险','难度小','长期';
'方案7','极高成本','远距离','高风险','难度大','中期';
};
data = rawData(:,2:6);
%% 颜色定义
C = [
0 0.2745 0.5451
0.9294 0 0
0.2588 0.7098 0.2510
0 0.6000 0.7059
0.5725 0.3686 0.6235
0.9922 0.6863 0.5686
0.6784 0 0.1647
0.6784 0.7137 0.7137
0.1059 0.0980 0.0980
];
%% 图片尺寸设置(单位:厘米)
figureUnits = 'centimeters';
figureWidth = 16;
figureHeight = 9;
%% 窗口设置
figureHandle = figure;
set(gcf, ...
'Units', figureUnits, ...
'Position', [0 0 figureWidth figureHeight]);
%% 华夫图绘制
[h_surf,u1,u2,u3] = waffle(data,2);
hXLabel = xlabel('评价指标');
hYLabel = ylabel('备选方案');
%% 配色顺序
idx = [2 1 3 5 4 6 7 8 9];
map = C(idx,1:3);
colormap(map)
%% 坐标轴美化
axis tight equal
set(gca, ...
'xaxislocation','bottom', ...
'yaxislocation','left', ...
'YDir','reverse', ...
'xtick',1:5, ...
'ytick',1:7, ...
'Xticklabel',{'成本等级','运输距离','风险水平','调度难度','实施周期'}, ...
'Yticklabel',{'方案1','方案2','方案3','方案4','方案5','方案6','方案7'})
%% 图例设置
hLegend = legend(h_surf(u2(idx)),u1(idx), ...
'FontWeight','normal', ...
'FontSize',9, ...
'Box','off', ...
'Location','eastoutside', ...
'Orientation','vertical');
hLegend.ItemTokenSize = [10 10];
%% 字体配置
set(gca, ...
'FontSize',9, ...
'FontName','SimHei')
set([hXLabel,hYLabel], ...
'FontSize',11, ...
'FontName','SimHei')
%% 画布美化
set(gcf,'Color',[1 1 1])
set(gca, ...
'LooseInset',get(gca,'TightInset'))
%% 高清图片导出
figW = figureWidth;
figH = figureHeight;
set(figureHandle,'PaperUnits',figureUnits);
set(figureHandle, ...
'PaperPosition',[0 0 figW figH]);
fileout = '物资配送方案_华夫图';
print(figureHandle, ...
[fileout,'.png'], ...
'-r300', ...
'-dpng');
14. 最后
通过这次华夫图的绘制,可以看到 MATLAB 不仅可以绘制常见的折线图、柱状图、散点图等,也可以通过自定义函数实现更加丰富的可视化效果。
在实际的数学建模和数据分析中,图表并不是越复杂越好,而是要让数据表达更加清晰。对于本文的物资配送方案数据,华夫图能够将多个方案和多个评价指标放在同一张图中进行展示,从而更加直观地观察不同方案之间的差异。
当然,本文代码主要是根据自己的学习和实践进行整理,如果其中存在理解不到位、代码不完善或者表述不准确的地方,欢迎大家指出和交流。
如果本文对你有所帮助,欢迎 点赞、收藏、评论,一键三连!
感谢大家的支持,我们下篇文章继续!

167

被折叠的 条评论
为什么被折叠?



