ggplot2:条形图中的动态宽度

时间:2018-02-15 13:42:17

标签: r ggplot2

我认为提出这个问题的最简单方法是:是否有可能重现这个情节?

bar plot with varying widths

所以我希望条形的宽度根据过程的持续时间而变化。

以下是您的示例数据框架:

structure(list(starttime = structure(c(1518652800, 1518652802, 
1518652803.5, 1518652806.5, 1518652808), tzone = "", class = c("POSIXct", 
"POSIXt")), endtime = structure(c(1518652801.5, 1518652803.5, 
1518652805.5, 1518652807.5, 1518652808.5), tzone = "", class = c("POSIXct", 
"POSIXt")), duration = c(1.5, 1.5, 2, 1, 0.5), order = c(1, 2, 
3, 4, 5), process = c("A", "B", "C", "B", "C"), blue = c(300, 
200, 100, 200, 300), orange = c(100, 50, 300, 100, 100), yellow = c(150, 
100, 150, 100, 200), total = c(550, 350, 550, 400, 600)), .Names = c("starttime", 
"endtime", "duration", "order", "process", "blue", "orange", 
"yellow", "total"), row.names = c(NA, -5L), class = "data.frame")

这就是我的到来:plot without varying width

这是相应的代码(反转此post后面的时间轴):

更新:此解决方案有效

df2 <- reshape(data = df, idvar = "order", varying = list(6:8),
               direction = "long", v.names = "some_measure")
df2$measure_type <- factor(ifelse(df2$time == 1, "blue",
                           ifelse(df2$time == 2, "orange", "yellow")),
                           levels = c("yellow", "orange", "blue"))
library(ggplot2)
library(scales)
# this function is used to reverse the time axis
c_trans <- function(a, b, breaks = b$breaks, format = b$format) {
  a <- as.trans(a)
  b <- as.trans(b)

  name <- paste(a$name, b$name, sep = "-")

  trans <- function(x) a$trans(b$trans(x))
  inv <- function(x) b$inverse(a$inverse(x))

  trans_new(name, trans, inv, breaks, format)
}
# this works
ggplot() +
geom_bar(data = df2, aes(x = starttime + .5*duration, y = some_measure, fill = measure_type), stat = "identity", position = "stack", width = df$duration) +
  scale_fill_manual(values = c("blue" = "dodgerblue3", "orange" = "darkorange", "yellow" = "gold2"), guide = FALSE) +
  geom_text(data = subset(df2, measure_type == "blue") ,aes(x = starttime + .5*duration, y = 55, label = paste("PROCESS",process)), color = "white") +
  labs(x = "time", y = "some measure") +
  coord_flip() +
  scale_x_continuous(trans = c_trans("reverse", "time"), labels = function(x) strftime(x, format = "%H:%M%:%OS"), breaks = seq(min(df$starttime),max(df$starttime), by = 1))

2 个答案:

答案 0 :(得分:0)

你可以像这样定义不同的宽度

ggplot() +
  geom_bar(data=df2, 
           aes(x=starttime, y=some_measure, fill=measure_type), 
           stat="identity", position="stack", width=c(.5,.8,1,.2,.3)) +
  scale_fill_manual(values=c(
                      "blue"="dodgerblue3", 
                      "orange"="darkorange", 
                      "yellow"="gold2"), 
                    guide = FALSE) +
  geom_text(data=subset(df2, measure_type == "blue"),
            aes(x=starttime, y=55, label=paste("PROCESS",process)), 
            color="white") +
  labs(x="time", y="some measure") +
  coord_flip() +
  scale_x_continuous(trans=c_trans("reverse", "time"), 
                     labels=function(x) strftime(x, format="%H:%M%:%OS"))

只需使用一个函数来计算每个条的宽度。

答案 1 :(得分:0)

这个怎么样:

df2=ddply(df2,.(starttime),mutate,measureTotal=sum(some_measure)/1000)
ggplot() +
  geom_bar(data = df2, aes(x = starttime, y = some_measure, fill = measure_type), stat = "identity", 
           position = "stack",width=df2$measureTotal)+
  scale_fill_manual(values = c("blue" = "dodgerblue3", "orange" = "darkorange", "yellow" = "gold2"), guide = FALSE) +
  geom_text(data = subset(df2, measure_type == "blue") ,aes(x = starttime, y = 55, label = paste("PROCESS",process)), 
            color = "white") +labs(x = "time", y = "some measure") +
  coord_flip() +
  scale_x_continuous(trans = c_trans("reverse", "time"), labels = function(x) strftime(x, format = "%H:%M%:%OS"))

enter image description here

当然,你可以用任何我用过1000的数字除以获得优先宽度