在甘特图上绘制许多折线图,quickly/scalably
Plot many line charts on top of gantt chart, quickly/scalably
Objective 图表:(用 Photoshop 制作)
监视门卫进出大厅的情况。蓝色是看门人 1,棕色是看门人 2。线代表大厅里的客人数量(比例是相对于自身的,即 ymin=0, ymax=max.visitor.value
,没有明确的轴)。颜色代表 (cum. janitor time)/(cum. # of guests)
,即如果乱码堆积起来,线开始变成红色。
我在哪里: (R with plotrix::gantt.chart)
问题
我希望完全用 R 实现 objective(每天添加渐变线)。我不确定如何进行 - 我正在考虑:1) 用较低的值添加它们杠杆图形并手动排列它们,因为 plotrix 基于基本图形或 2) 远离 plotrix 并使用基于网格的包,这可能比前者更 readable/higher 级别(?)。
问题
我试图通过查看 SO thread 讨论制作甘特图的各种方法来寻找基于网格的包。我尝试使用 plotly,但它似乎不支持 'multiple time chunks' 相同的 'task'。我想在将更多时间花在其他包上之前暂停一下,并且可能 运行 进入死胡同(考虑添加所有线图),同时对高级方法一无所知。
作为最后的手段,我可能会考虑一个一个地创建折线图并将它们拼接到 R 之外的甘特图中。
数据样本
甘特图数据(随机样本,为简洁起见仅在周一和周二)
janitor.type weekday dummy.start.time dummy.end.time
<dbl> <chr> <dttm> <dttm>
1 1 Monday 1970-01-01 18:01:20 1970-01-01 18:06:50
2 1 Monday 1970-01-01 18:08:10 1970-01-01 18:11:52
3 1 Monday 1970-01-01 17:22:00 1970-01-01 17:23:00
4 1 Monday 1970-01-01 11:39:40 1970-01-01 11:41:58
5 2 Monday 1970-01-01 19:35:40 1970-01-01 19:40:40
6 1 Monday 1970-01-01 15:23:00 1970-01-01 15:24:12
7 1 Monday 1970-01-01 11:54:50 1970-01-01 12:00:20
8 1 Tuesday 1970-01-01 17:23:00 1970-01-01 18:18:18
9 2 Tuesday 1970-01-01 19:25:00 1970-01-01 19:39:18
10 1 Tuesday 1970-01-01 16:40:10 1970-01-01 17:09:10
11 1 Tuesday 1970-01-01 14:16:50 1970-01-01 14:19:38
12 2 Tuesday 1970-01-01 09:27:00 1970-01-01 09:30:30
13 1 Tuesday 1970-01-01 14:08:40 1970-01-01 14:13:40
14 1 Tuesday 1970-01-01 11:12:40 1970-01-01 11:13:40
> dput(gantt)
structure(list(asset.type = c(1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1), weekday = c("Monday", "Monday", "Monday", "Monday",
"Monday", "Monday", "Monday", "Tuesday", "Tuesday", "Tuesday",
"Tuesday", "Tuesday", "Tuesday", "Tuesday"), dummy.start.time = structure(c(82880,
83290, 80520, 59980, 88540, 73380, 60890, 80580, 87900, 78010,
69410, 52020, 68920, 58360), class = c("POSIXct", "POSIXt"), tzone = ""),
dummy.end.time = structure(c(83210, 83512, 80580, 60118,
88840, 73452, 61220, 83898, 88758, 79750, 69578, 52230, 69220,
58420), class = c("POSIXct", "POSIXt"), tzone = "")), row.names = c(NA,
-14L), vars = "weekday", drop = TRUE, .Names = c("asset.type",
"weekday", "dummy.start.time", "dummy.end.time"), indices = list(
0:6, 7:13), group_sizes = c(7L, 7L), biggest_group_size = 7L, labels = structure(list(
weekday = c("Monday", "Tuesday")), row.names = c(NA, -2L), class = "data.frame", vars = "weekday", drop = TRUE, .Names = "weekday"), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
访客
Monday Tuesday
9:00:00 AM 138 9:00:00 AM 153
10:00:00 AM 251 10:00:00 AM 299
11:00:00 AM 432 11:00:00 AM 479
12:00:00 PM 560 12:00:00 PM 453
1:00:00 PM 555 1:00:00 PM 535
2:00:00 PM 475 2:00:00 PM 383
3:00:00 PM 448 3:00:00 PM 416
4:00:00 PM 469 4:00:00 PM 417
5:00:00 PM 459 5:00:00 PM 519
6:00:00 PM 403 6:00:00 PM 384
7:00:00 PM 290 7:00:00 PM 278
8:00:00 PM 120 8:00:00 PM 116
9:00:00 PM 29 9:00:00 PM 34
dput(访问者)
structure(list(weekday = c("Monday", "Monday", "Monday", "Monday",
"Monday", "Monday", "Monday", "Monday", "Monday", "Monday", "Monday",
"Monday", "Monday", "Tuesday", "Tuesday", "Tuesday", "Tuesday",
"Tuesday", "Tuesday", "Tuesday", "Tuesday", "Tuesday", "Tuesday",
"Tuesday", "Tuesday", "Tuesday"), time = structure(c(50400, 54000,
57600, 61200, 64800, 68400, 72000, 75600, 79200, 82800, 86400,
90000, 93600, 50400, 54000, 57600, 61200, 64800, 68400, 72000,
75600, 79200, 82800, 86400, 90000, 93600), class = c("POSIXct",
"POSIXt"), tzone = ""), count = c(138L, 251L, 432L, 560L, 555L,
475L, 448L, 469L, 459L, 403L, 290L, 120L, 29L, 153L, 299L, 479L,
453L, 535L, 383L, 416L, 417L, 519L, 384L, 278L, 116L, 34L)), .Names = c("weekday",
"time", "count"), row.names = c(NA, -26L), class = "data.frame")
plotrix::gantt.图表代码
# Set up variables for gantt chart
labels <- gantt$weekday
starts <- gantt$dummy.start.time
ends <- gantt$dummy.end.time
priorities <- as.numeric(gantt$asset.type)
Ymd.format <- "%Y/%m/%d %H:%M:%S"
# Feed variables to chart parameters
gantt.info <- list(
labels = labels,
starts = starts,
ends = ends,
priorities = priorities
)
# Define chart intervals
hours <- seq(
as.POSIXct("1970/01/01 09:00:00", format = Ymd.format),
as.POSIXct("1970/01/01 21:00:00", format = Ymd.format),
by = "hour"
)
# Define labels for vgridlab
hourslab <- format(hours, format = "%H")
# Define vertical gridline
vgridpos <- as.POSIXct(hours, format = Ymd.format)
vgridlab <- hourslab
# Optional coloring
colfunc <- colorRampPalette(c("#00bff3", "#362f2d"))
# Define timeframe on x axis
timeframe <-
as.POSIXct(c("1970/01/01 09:00:00", "1970/01/01 21:00:00"), format = Ymd.format)
# Create the chart
main = ""
test <- gantt.chart(
gantt.info,
taskcolors = colfunc(2),
xlim = timeframe,
main = main,
priority.legend = F,
vgridpos = vgridpos,
vgridlab = vgridlab,
hgrid = TRUE,
half.height = 0.125,
time.axis = 1
)
我用了ggplot2
。为了能够使用 2 种不同的颜色设置——一种用于甘特图资产类型,另一种用于访问者计数,我选择了两种几何类型,一种能够采用填充颜色:geom_rect
,另一种线条颜色:geom_line
.
我使用网格分面来分隔工作日,因为甘特图和访客没有共同的 y 轴。
颜色和填充调色板可以通过 scale_colour_gradient
(连续)或 scale_fill_manual
(离散)设置,或者利用颜色 brewer 调色板 scale_colour_distiller
(连续)和 scale_fill_brewer
(离散)。我使用以下每个示例来复制给定甘特图中的配色方案。
# factor weekdays and set levels to correct order
gantt$weekday <- factor(gantt$weekday, levels=c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"))
visitors$weekday <- factor(visitors$weekday, levels=c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"))
# factor gantt$asset.type as this represent categorical not continuous values
gantt$asset.type <- factor(gantt$asset.type)
# gantt chart
library(ggplot2)
ggplot() +
geom_line(data=visitors, aes(x=time, y=count, colour=count)) +
geom_rect(data=gantt, aes(xmin=dummy.start.time, xmax=dummy.end.time, ymin=-100, ymax=0, fill=asset.type)) +
facet_grid(weekday~.) +
scale_colour_distiller("Visitor Count", type="div", palette="RdYlGn", direction = -1) +
scale_fill_manual("Asset Type", values=c("dodger blue", "black")) +
theme_bw() +
theme(axis.title = element_blank())
注意:您可以通过调整 geom_rect
的 ymin
和 ymax
来调整资产条的粗细。我让 ymax=0
和 ymin
取负值,所以它被绘制在访客计数 y 范围下方。
我要补充一点,您还可以使用 geom_segment
在 ggplot2
中制作甘特图,但是您的绘图的一个特定问题需要两种不同的色标,而 geom_segment
只需要 colour
美学喜欢 geom_line
.
这里是 ggplot2
用于创建甘特图的代码:
ggplot(gantt) +
geom_segment(aes(x=dummy.start.time, xend=dummy.end.time, y=weekday, yend=weekday, colour=asset.type), size=10) +
scale_colour_manual("Asset Type", values=c("dodger blue", "black")) +
theme_bw() +
theme(axis.title = element_blank())
Objective 图表:(用 Photoshop 制作)
监视门卫进出大厅的情况。蓝色是看门人 1,棕色是看门人 2。线代表大厅里的客人数量(比例是相对于自身的,即 ymin=0, ymax=max.visitor.value
,没有明确的轴)。颜色代表 (cum. janitor time)/(cum. # of guests)
,即如果乱码堆积起来,线开始变成红色。
我在哪里: (R with plotrix::gantt.chart)
问题
我希望完全用 R 实现 objective(每天添加渐变线)。我不确定如何进行 - 我正在考虑:1) 用较低的值添加它们杠杆图形并手动排列它们,因为 plotrix 基于基本图形或 2) 远离 plotrix 并使用基于网格的包,这可能比前者更 readable/higher 级别(?)。
问题
我试图通过查看 SO thread 讨论制作甘特图的各种方法来寻找基于网格的包。我尝试使用 plotly,但它似乎不支持 'multiple time chunks' 相同的 'task'。我想在将更多时间花在其他包上之前暂停一下,并且可能 运行 进入死胡同(考虑添加所有线图),同时对高级方法一无所知。
作为最后的手段,我可能会考虑一个一个地创建折线图并将它们拼接到 R 之外的甘特图中。
数据样本
甘特图数据(随机样本,为简洁起见仅在周一和周二)
janitor.type weekday dummy.start.time dummy.end.time
<dbl> <chr> <dttm> <dttm>
1 1 Monday 1970-01-01 18:01:20 1970-01-01 18:06:50
2 1 Monday 1970-01-01 18:08:10 1970-01-01 18:11:52
3 1 Monday 1970-01-01 17:22:00 1970-01-01 17:23:00
4 1 Monday 1970-01-01 11:39:40 1970-01-01 11:41:58
5 2 Monday 1970-01-01 19:35:40 1970-01-01 19:40:40
6 1 Monday 1970-01-01 15:23:00 1970-01-01 15:24:12
7 1 Monday 1970-01-01 11:54:50 1970-01-01 12:00:20
8 1 Tuesday 1970-01-01 17:23:00 1970-01-01 18:18:18
9 2 Tuesday 1970-01-01 19:25:00 1970-01-01 19:39:18
10 1 Tuesday 1970-01-01 16:40:10 1970-01-01 17:09:10
11 1 Tuesday 1970-01-01 14:16:50 1970-01-01 14:19:38
12 2 Tuesday 1970-01-01 09:27:00 1970-01-01 09:30:30
13 1 Tuesday 1970-01-01 14:08:40 1970-01-01 14:13:40
14 1 Tuesday 1970-01-01 11:12:40 1970-01-01 11:13:40
> dput(gantt)
structure(list(asset.type = c(1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1), weekday = c("Monday", "Monday", "Monday", "Monday",
"Monday", "Monday", "Monday", "Tuesday", "Tuesday", "Tuesday",
"Tuesday", "Tuesday", "Tuesday", "Tuesday"), dummy.start.time = structure(c(82880,
83290, 80520, 59980, 88540, 73380, 60890, 80580, 87900, 78010,
69410, 52020, 68920, 58360), class = c("POSIXct", "POSIXt"), tzone = ""),
dummy.end.time = structure(c(83210, 83512, 80580, 60118,
88840, 73452, 61220, 83898, 88758, 79750, 69578, 52230, 69220,
58420), class = c("POSIXct", "POSIXt"), tzone = "")), row.names = c(NA,
-14L), vars = "weekday", drop = TRUE, .Names = c("asset.type",
"weekday", "dummy.start.time", "dummy.end.time"), indices = list(
0:6, 7:13), group_sizes = c(7L, 7L), biggest_group_size = 7L, labels = structure(list(
weekday = c("Monday", "Tuesday")), row.names = c(NA, -2L), class = "data.frame", vars = "weekday", drop = TRUE, .Names = "weekday"), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
访客
Monday Tuesday
9:00:00 AM 138 9:00:00 AM 153
10:00:00 AM 251 10:00:00 AM 299
11:00:00 AM 432 11:00:00 AM 479
12:00:00 PM 560 12:00:00 PM 453
1:00:00 PM 555 1:00:00 PM 535
2:00:00 PM 475 2:00:00 PM 383
3:00:00 PM 448 3:00:00 PM 416
4:00:00 PM 469 4:00:00 PM 417
5:00:00 PM 459 5:00:00 PM 519
6:00:00 PM 403 6:00:00 PM 384
7:00:00 PM 290 7:00:00 PM 278
8:00:00 PM 120 8:00:00 PM 116
9:00:00 PM 29 9:00:00 PM 34
dput(访问者)
structure(list(weekday = c("Monday", "Monday", "Monday", "Monday",
"Monday", "Monday", "Monday", "Monday", "Monday", "Monday", "Monday",
"Monday", "Monday", "Tuesday", "Tuesday", "Tuesday", "Tuesday",
"Tuesday", "Tuesday", "Tuesday", "Tuesday", "Tuesday", "Tuesday",
"Tuesday", "Tuesday", "Tuesday"), time = structure(c(50400, 54000,
57600, 61200, 64800, 68400, 72000, 75600, 79200, 82800, 86400,
90000, 93600, 50400, 54000, 57600, 61200, 64800, 68400, 72000,
75600, 79200, 82800, 86400, 90000, 93600), class = c("POSIXct",
"POSIXt"), tzone = ""), count = c(138L, 251L, 432L, 560L, 555L,
475L, 448L, 469L, 459L, 403L, 290L, 120L, 29L, 153L, 299L, 479L,
453L, 535L, 383L, 416L, 417L, 519L, 384L, 278L, 116L, 34L)), .Names = c("weekday",
"time", "count"), row.names = c(NA, -26L), class = "data.frame")
plotrix::gantt.图表代码
# Set up variables for gantt chart
labels <- gantt$weekday
starts <- gantt$dummy.start.time
ends <- gantt$dummy.end.time
priorities <- as.numeric(gantt$asset.type)
Ymd.format <- "%Y/%m/%d %H:%M:%S"
# Feed variables to chart parameters
gantt.info <- list(
labels = labels,
starts = starts,
ends = ends,
priorities = priorities
)
# Define chart intervals
hours <- seq(
as.POSIXct("1970/01/01 09:00:00", format = Ymd.format),
as.POSIXct("1970/01/01 21:00:00", format = Ymd.format),
by = "hour"
)
# Define labels for vgridlab
hourslab <- format(hours, format = "%H")
# Define vertical gridline
vgridpos <- as.POSIXct(hours, format = Ymd.format)
vgridlab <- hourslab
# Optional coloring
colfunc <- colorRampPalette(c("#00bff3", "#362f2d"))
# Define timeframe on x axis
timeframe <-
as.POSIXct(c("1970/01/01 09:00:00", "1970/01/01 21:00:00"), format = Ymd.format)
# Create the chart
main = ""
test <- gantt.chart(
gantt.info,
taskcolors = colfunc(2),
xlim = timeframe,
main = main,
priority.legend = F,
vgridpos = vgridpos,
vgridlab = vgridlab,
hgrid = TRUE,
half.height = 0.125,
time.axis = 1
)
我用了ggplot2
。为了能够使用 2 种不同的颜色设置——一种用于甘特图资产类型,另一种用于访问者计数,我选择了两种几何类型,一种能够采用填充颜色:geom_rect
,另一种线条颜色:geom_line
.
我使用网格分面来分隔工作日,因为甘特图和访客没有共同的 y 轴。
颜色和填充调色板可以通过 scale_colour_gradient
(连续)或 scale_fill_manual
(离散)设置,或者利用颜色 brewer 调色板 scale_colour_distiller
(连续)和 scale_fill_brewer
(离散)。我使用以下每个示例来复制给定甘特图中的配色方案。
# factor weekdays and set levels to correct order
gantt$weekday <- factor(gantt$weekday, levels=c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"))
visitors$weekday <- factor(visitors$weekday, levels=c("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"))
# factor gantt$asset.type as this represent categorical not continuous values
gantt$asset.type <- factor(gantt$asset.type)
# gantt chart
library(ggplot2)
ggplot() +
geom_line(data=visitors, aes(x=time, y=count, colour=count)) +
geom_rect(data=gantt, aes(xmin=dummy.start.time, xmax=dummy.end.time, ymin=-100, ymax=0, fill=asset.type)) +
facet_grid(weekday~.) +
scale_colour_distiller("Visitor Count", type="div", palette="RdYlGn", direction = -1) +
scale_fill_manual("Asset Type", values=c("dodger blue", "black")) +
theme_bw() +
theme(axis.title = element_blank())
注意:您可以通过调整 geom_rect
的 ymin
和 ymax
来调整资产条的粗细。我让 ymax=0
和 ymin
取负值,所以它被绘制在访客计数 y 范围下方。
我要补充一点,您还可以使用 geom_segment
在 ggplot2
中制作甘特图,但是您的绘图的一个特定问题需要两种不同的色标,而 geom_segment
只需要 colour
美学喜欢 geom_line
.
这里是 ggplot2
用于创建甘特图的代码:
ggplot(gantt) +
geom_segment(aes(x=dummy.start.time, xend=dummy.end.time, y=weekday, yend=weekday, colour=asset.type), size=10) +
scale_colour_manual("Asset Type", values=c("dodger blue", "black")) +
theme_bw() +
theme(axis.title = element_blank())