【MATLAB学习笔记】绘图——甘特图

前言

  使用MATLAB绘制甘特图。
  甘特图(Gantt chart)又称为横道图、条状图(Bar chart)。以提出者亨利·L·甘特先生的名字命名。

  甘特图内在思想简单,即以图示的方式通过活动列表和时间刻度形象地表示出任何特定项目的活动顺序与持续时间。基本是一条线条图,横轴表示时间,纵轴表示活动(项目),线条表示在整个期间上计划和实际的活动完成情况。它直观地表明任务计划在什么时候进行,及实际进展与计划要求的对比。管理者由此可便利地弄清一项任务(项目)还剩下哪些工作要做,并可评估工作进度。

准备数据

  准备一些数据,数据包括开始的时间点和对应结束的时间点,例如x1s = [1, 3, 6, 10] 表示有4个时间节点,对应开始的时间为1、3、6和10,x1e = [2, 5, 8.5, 14] 对应这4个时间节点结束的时间分别为2、5、8.5和14。
  可以准备多组数据,每组数据在甘特图中呈现为一个进程进度,下面准备了3组数据,并且使用元胞变量dataAll将数据存储,便于后续的循环绘图。

%% 数据
dataAll = cell(3,1);    % 创建储存所有数据的元胞, 使得每一个元胞的第一列都是开始的时间,第二列为结束的时间
% 第一个进程的数据
x1s = [1, 3, 6, 10];   % 开始的时间
x1e = [2, 5, 8.5, 14]; % 结束的时间
dataAll{1} = zeros(length(x1s),2);  % 初始化
dataAll{1}(:,1) = x1s;  % 将数据存入
dataAll{1}(:,2) = x1e;

% 第二个进程的数据
x2s = [0.5, 2, 5.1, 8.2, 11];   % 开始的时间
x2e = [1.5, 4.2, 8, 10, 15];     % 结束的时间
dataAll{2} = zeros(length(x2s),2);  % 初始化
dataAll{2}(:,1) = x2s;  % 将数据存入
dataAll{2}(:,2) = x2e;

% 第三个进程的数据
x3s = [1.5, 4, 5, 7.5, 11.5];   % 开始的时间
x3e = [3.5, 5, 7, 9, 14.5];     % 结束的时间
dataAll{3} = zeros(length(x3s),2);  % 初始化
dataAll{3}(:,1) = x3s;  % 将数据存入
dataAll{3}(:,2) = x3e;

创建绘图区

   这里的变量 scrsz为屏幕的尺寸,Position’,[0 30 scrsz(3) scrsz(4)-95] 表示这是绘图区的大小为一个屏幕的大小。
   这里更改绘图区的大小是为了甘特图展示得更清晰,不改变也是没有问题的。
  变量 myColors 为自己定义的颜色,不清楚可以看这篇文章,也可以选择自己喜欢的颜色,w 是定义的甘特图形状宽度。

%% 
scrsz = get(0,'ScreenSize'); %%%% 获取屏幕的尺寸
f = figure('Name','甘特图','Position',[0 30 scrsz(3) scrsz(4)-95]); 
% 配色表
myColors = ["#9489fa"; "#f06464"; "#f7af59"; "#f0da49"; "#71c16f"; "#2aaaef";
            "#5690dd"; "#bd88f5"; "#009db2"; "#024b51"; "#0780cf"; "#765005"];
w=0.6;       %横条宽度 

绘制甘特图

  这里的 patch 函数实现,patch函数介绍如下:

  • patch(X,Y,C) 使用 X 和 Y 的元素作为每个顶点的坐标,以绘制一个或多个填充多边形区域。patch 以您指定顶点的顺序连接这些顶点。
  • 创建一个红色正方形,顶点位于 (0,0)、(1,0)、(1,1) 和 (0,1)。将 x 指定为顶点的 x 坐标,并将 y 指定为 y 坐标。patch 会自动将最后一个 (x,y) 坐标与第一个 (x,y) 坐标连接。
x = [0 1 1 0];
y = [0 0 1 1];
patch(x,y,'red')
  • 线是按x和y矩阵中点的顺序连接的,例如下图中的顺序为1(0,0)——>2(1,0)——>3(1,1)——>4(0,1)。

在这里插入图片描述
  下面代码的 time_s 表示取出开始的时间点, time_e 表示取出结束的时间点,使用 patch 函数来绘制甘特图的小矩形。
  下面代码中是按顺时针方向连接的, y = i + [-w/2 w/2 w/2 -w/2] 前面加上 i是为了让不同的数据组画在不同的行,这个例子中有三组数据,就会有三行。

n = length(dataAll);
for i = 1:n
    time_s = dataAll{i}(:,1);   % 开始的时间
    time_e = dataAll{i}(:,2);   % 结束的时间
    m = length(time_s);
    for j = 1:m
        x = [time_s(j),time_s(j),time_e(j),time_e(j)]; 
        y = i + [-w/2 w/2 w/2 -w/2];

        patch('xdata',x,'ydata',y,'facecolor',myColors(i,:),'edgecolor','k'); 

        hold on
    end
end

效果图:
在这里插入图片描述

修改Y轴标签

  从上图可以看到,Y轴标签并不是我们想要的,可以对标签进行一些调整,这里分为两步:

  1. 将非整数的刻度线去除
% 设置标签
yticks(1:n);
  1. 将标签替换为自己所需要的文字
yticklabelsName = cell(n,1);
for i = 1:n
    yticklabelsName{i} = ['Group ',num2str(i)];
end
yticklabels(yticklabelsName)

细节调整

最后就是对一些绘图细节的调整,如字体、字号、线的粗细等等,具体的可以看这篇文章

% 设置全局字体字号
set(gca,'Fontname','Times New Roman','FontSize',18)
xlabel('Time/h')

% 设置轴线宽度
set(gca,'linewidth',1)

% 设置次刻度线
set(gca,'XMinorTick',true)

% 设置刻度线的长度
set(gca,'TickLength',[0.015,0.05])

%% 保存
exportgraphics(gca,'Infww_干特图.png','Resolution',600)

效果图:
在这里插入图片描述

总代码

clc;clear;close all
set(0,'defaultfigurecolor','w');

%% 数据
dataAll = cell(3,1);    % 创建储存所有数据的元胞, 使得每一个元胞的第一列都是开始的时间,第二列为结束的时间
% 第一个进程的数据
x1s = [1, 3, 6, 10];   % 开始的时间
x1e = [2, 5, 8.5, 14]; % 结束的时间
dataAll{1} = zeros(length(x1s),2);  % 初始化
dataAll{1}(:,1) = x1s;  % 将数据存入
dataAll{1}(:,2) = x1e;

% 第二个进程的数据
x2s = [0.5, 2, 5.1, 8.2, 11];   % 开始的时间
x2e = [1.5, 4.2, 8, 10, 15];     % 结束的时间
dataAll{2} = zeros(length(x2s),2);  % 初始化
dataAll{2}(:,1) = x2s;  % 将数据存入
dataAll{2}(:,2) = x2e;

% 第三个进程的数据
x3s = [1.5, 4, 5, 7.5, 11.5];   % 开始的时间
x3e = [3.5, 5, 7, 9, 14.5];     % 结束的时间
dataAll{3} = zeros(length(x3s),2);  % 初始化
dataAll{3}(:,1) = x3s;  % 将数据存入
dataAll{3}(:,2) = x3e;

%% 
scrsz = get(0,'ScreenSize'); %%%% 获取屏幕的尺寸
f = figure('Name','甘特图','Position',[0 30 scrsz(3) scrsz(4)-95]); 


% 配色表
myColors = ["#9489fa"; "#f06464"; "#f7af59"; "#f0da49"; "#71c16f"; "#2aaaef";
            "#5690dd"; "#bd88f5"; "#009db2"; "#024b51"; "#0780cf"; "#765005"];
w=0.6;       %横条宽度 

n = length(dataAll);
for i = 1:n
    time_s = dataAll{i}(:,1);   % 开始的时间
    time_e = dataAll{i}(:,2);   % 结束的时间
    m = length(time_s);
    for j = 1:m
        x = [time_s(j),time_s(j),time_e(j),time_e(j)]; 
        y = i + [-w/2 w/2 w/2 -w/2];

        patch('xdata',x,'ydata',y,'facecolor',myColors(i,:),'edgecolor','k'); 

        hold on
    end
end

% 设置标签
yticks(1:n);
yticklabelsName = cell(n,1);
for i = 1:n
    yticklabelsName{i} = ['Group ',num2str(i)];
end
yticklabels(yticklabelsName)


% 设置全局字体字号
set(gca,'Fontname','Times New Roman','FontSize',18)
xlabel('Time/h')

% 设置轴线宽度
set(gca,'linewidth',1)

% 设置次刻度线
set(gca,'XMinorTick',true)

% 设置刻度线的长度
set(gca,'TickLength',[0.015,0.05])

%% 保存
exportgraphics(gca,'Infww_干特图.png','Resolution',600)

总结

  这只是一个基础的示例,实际中还会有更具体的、更细致的要求,这就需要再做额外调整;另外本人也仍在学习中,这只是个人的学习笔记,可能还有一些不足之处,欢迎指正。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Infww

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值