Fork me on GitHub

可视化神器Plotly玩转甘特图

可视化神器Plotly玩转甘特图

本文介绍的是一种特殊的柱状图:甘特图,虽然在实际工作中使用的几率较小,还是很有必要和兴趣来学习下,将制作过程分享给大家。

扩展阅读

Plotly的文章会形成连载系列,前面7篇Plotly可视化文章分别是:

什么是甘特图

甘特图最初绘制是基于时间线轴timeline的,用来表示一个项目的进度。甘特图依赖于两种数轴表示:

  • 垂直轴(纵轴):指定需要执行的任务
  • 水平轴(横轴):列出每个任务的执行时间段

在甘特图的柱状图中,每个水平条的宽度显示的是任务执行需要的时间

甘特图的发明者(1910-1915期间发明):亨利.甘特👍

导入库

文章绘图使用的是plotly_express和plotly中的图形工厂函数figure_factory方法

1
2
3
4
5
6
import pandas as pd
import numpy as np

import plotly_express as px
# 图形工厂
import plotly.figure_factory as ff

基于px实现

基础图形

通过字典的方式生成一份模拟数据:

1
2
3
4
5
df = pd.DataFrame([
dict(Task="考公务员", Start='2020-01-01', Finish='2020-02-28'),
dict(Task="考教师资格证", Start='2020-03-15', Finish='2020-04-15'),
dict(Task="考六级", Start='2020-05-20', Finish='2020-06-30')
])

绘图的基本代码如下;甘特图的绘制是基于时间线timeline的,主要参数是:

  • 绘图数据
  • 开始时间
  • 结束时间
  • 纵轴数据
1
2
3
4
5
6
7
8
9
10
fig = px.timeline(
df, # 绘图数据
x_start="Start", # 开始时间
x_end="Finish", # 结束时间
y="Task" # y轴显示的数据
)

# 实施翻转
fig.update_yaxes(autorange="reversed")
fig.show()

如果不翻转的效果如何:最终发现y轴显示的标签顺序发生了变化

1
2
3
4
5
6
7
8
9
10
fig = px.timeline(
df, # 绘图数据
x_start="Start", # 开始时间
x_end="Finish", # 结束时间
y="Task" # y轴显示的数据
)

# 不实施翻转
# fig.update_yaxes(autorange="reversed")
fig.show()

修改颜色

上面的图形颜色是plotly自带的,可以通过数值和字符改变颜色,模拟一份新的数据:

1
2
3
4
5
6
7
8
df1 = pd.DataFrame({
"Task":["考公务员","考教师证","考6级"],
"Start":["2021-01-01","2021-02-25","2021-04-01"],
"End":["2021-01-28","2021-03-19","2021-06-30"],
"name":["Mike","Mike","Peter"]
})

df1

传入字符类型的参数改变颜色:

1
2
3
4
5
6
7
8
9
fig = px.timeline(
df1, # 绘图数据
x_start="Start", # 开始时间
x_end="End", # 结束时间
y="Task", # y轴数据
color="name" # 颜色设置
)

fig.show()

如果y轴和颜色是相同的取值:

1
2
3
4
5
6
7
8
9
fig = px.timeline(
df1,
x_start="Start",
x_end="End",
y="name", # y和color取值相同
color="name"
)

fig.show()

通过数值型参数改变颜色

1
2
3
4
5
6
7
8
df2 = pd.DataFrame({
"任务": ["考公务员","考教师证","考6级"],
"开始时间": ["2021-01-01","2021-02-25","2021-04-01"],
"结束时间": ["2021-01-28","2021-03-19","2021-06-30"],
"完成度": [80,73,95]
})

df2

结果为:

1
2
3
4
  任务      开始时间      结束时间    完成度
0 考公务员 2021-01-01 2021-01-28 80
1 考教师证 2021-02-25 2021-03-19 73
262021-04-01 2021-06-30 95

绘图代码如下:

1
2
3
4
5
6
7
8
9
fig = px.timeline(
df2,
x_start="开始时间",
x_end="结束时间",
y="任务",
color="完成度" # 通过数值设置颜色
)

fig.show()

基于图形工厂实现

为什么有图形工厂

The plotly.figure_factory module contains dedicated functions for creating very specific types of plots that were at the time of their creation difficult to create with graph objects and prior to the existence of Plotly Express.

在Plotly_Express存在之前,图形工厂函数用于创建那些基于go很难生成的图形

As new functionality gets added to Plotly.js and to Plotly Express, certain Figure Factories become unnecessary and are therefore deprecated as “legacy”, but remain in the module for backwards-compatibility reasons.

随着一些新的功能被添加到Plotly.js和Plotly_Express中,某些工厂函数变得不是很必要;但是为了向后兼容版本,部分还是保留在模块中

The following types of plots are still difficult to create with Graph Objects or Plotly Express and therefore the corresponding Figure Factories are not deprecated(弃用):

因为px或者go方法还是很难创建某些图形,所以建议还是使用图形工厂:

不推荐使用的工厂函数制作的图形:

基础绘图

模拟生成一份数据:

1
2
3
4
5
6
7
data = pd.DataFrame([
dict(Task="考公务员", Start='2019-01-01', Finish='2019-05-28',Complete=90),
dict(Task="考教师资格证", Start='2019-07-15', Finish='2019-11-15',Complete=50),
dict(Task="考雅思", Start='2020-01-20', Finish='2020-04-30',Complete=10)
])

data

绘图的代码:

1
2
fig = ff.create_gantt(data)
fig.show()

工厂函数生成的甘特图可以进行时间段的选择,上图默认是所有的统计时间范围。

改变颜色

使用的是模拟的数据:

1
2
3
4
5
6
7
8
fig = ff.create_gantt(
data,
colors="Viridis",
index_col="Complete",
show_colorbar=True # 显示颜色棒
)

fig.show()

多组甘特图

将不同类型的数据分组放在一个甘特图中:

1
2
3
4
5
6
7
8
9
10
11
12
13
data1 = pd.DataFrame([
dict(Task="考公务员", Start='2019-01-01', Finish='2019-03-28',Resource='Incomplete'),
dict(Task="考公务员", Start='2019-04-01', Finish='2019-05-28',Resource='Complete'),

dict(Task="考教师资格证", Start='2019-06-01', Finish='2019-7-15',Resource='Not Started'),
dict(Task="考教师资格证", Start='2019-07-20', Finish='2019-11-15',Resource='Complete'),

dict(Task="考雅思", Start='2020-01-20', Finish='2020-02-15',Resource='Not Started'),
dict(Task="考雅思", Start='2020-03-01', Finish='2020-03-15',Resource='Incomplete'),
dict(Task="考雅思", Start='2020-03-20', Finish='2020-04-30',Resource='Complete')
])

data1

绘图代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
colors_data1 = {
'Not Started':'rgb(100,20,108)',
'Incomplete':(1,0.9,0.5),
'Complete':'rgb(0,255,100)'
}

fig = ff.create_gantt(
data1, # 数据
colors=colors_data1, # 颜色设置
index_col='Resource', # 颜色显示字段
show_colorbar=True, # 显示颜色柱
group_tasks=True # 分组显示
)

fig.show()

总结

甘特图是一种使用频率,相对于柱状图、饼图等较低的图形,它有自己的特殊使用场景,在项目进度展示的场景尤其适合,也适合任务计划的制作。

本文标题:可视化神器Plotly玩转甘特图

发布时间:2021年05月17日 - 15:05

原始链接:http://www.renpeter.cn/2021/05/17/%E5%8F%AF%E8%A7%86%E5%8C%96%E7%A5%9E%E5%99%A8Plotly%E7%8E%A9%E8%BD%AC%E7%94%98%E7%89%B9%E5%9B%BE.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Coffee or Tea