ggplot2,geom_segment的颜色分段

4
我正在设计一些室内和室外活动的复杂情节,但遇到了困难。我想在绘图中的geom_segment步骤中通过(XminYminZmin)给室内/室外活动的时间增加颜色。目前仅通过Zmin进行染色(使用连续变量,效果不佳)。
我已经贴出了所有代码,以便其他人构建类似的内容。我最初受到这篇博客文章的启发。
感谢任何帮助!
df <- data.frame(
  date = seq(Sys.Date(), len= 156, by="4 day")[sample(156, 26)],
  action = paste('Then', LETTERS[1:13], 'happed, which was not related to', LETTERS[14:26]),
  IndoorOutdoor = rep(c(-1,1), 13),
  Xmin = sample(90, 26, replace = T),
  Ymin = sample(90, 26, replace = T),
  Zmin = sample(90, 26, replace = T)
)

df$XYZmin <- rowSums(df[,c("Xmin", "Ymin", "Zmin")])*df$IndoorOutdoor

# install.packages("ggplot2", dependencies = TRUE)
require(ggplot2)

# step 1 
plot <- ggplot(df,aes(x=date,y=0))

# step 2, this is where I want to add 'more' color 
plot <- plot + geom_segment(aes(y=0,yend=XYZmin,xend=date, colour= Zmin))

# The text is added as follows
plot <- plot + geom_text(aes(y=XYZmin,label=paste(action, '\n this happed on ', date)),size=2.5,hjust=-.01, vjust=-.01, angle = 35)

# points at the end of the line segments
plot <- plot + geom_point(aes(y=XYZmin))

# #raw a vertical line
plot <- plot + geom_hline(y=0,size=1,color='purple')

#drawing the actual arrow
# plot <- plot + geom_segment(x=2011.4,xend=2012.2,y=.2,yend=0,color='purple',size=1) + geom_segment(x=2011.4,xend=2012.2,y=-.2,yend=0,color='purple',size=1)

plot <- plot + theme(axis.text.y = element_blank()) + ylab('') + xlab('')
plot + labs(title = "Timeline for when what happened")

enter image description here


Zmin 映射为连续变量,以可定义的方式映射到颜色。如果要将三个数字映射到单一的颜色比例尺中,您想如何实现?如果它们是离散的,我可以看到它们之间的相互作用映射,但对于连续变量来说这是没有意义的。 - Brian Diggs
@BrianDiggs,感谢您回答我的问题。是我的表述不准确。我设想一个离散版本的 XminYminZmin,并通过三种离散颜色对各个分段进行着色。这样说清楚了吗? - Eric Fail
@BrianDiggs,像这个段落或者像这条线。请告诉我这是否回答了你的问题。如果没有,我很乐意在我的图表上尝试说明它。 - Eric Fail
1个回答

9

这里有两种方法。一种是使用不同的geom_segment构建每行(我认为这更接近于您所做的?),另一种则只使用geom_bar,这将是我的首选(可扩展性更强)。我认为在构建data.frame时存在错误-当您创建IndoorOutdoor时,会创建56行,这会在后面造成问题。我已经在下面进行了更改。

set.seed(1234)
df <- data.frame(
  date = seq(Sys.Date(), len= 156, by="4 day")[sample(156, 26)],
  action = paste('Then', LETTERS[1:13], 'happed, which was not related to', LETTERS[14:26]),
  IndoorOutdoor = rep(c(-1,1), 13), #Change so there are only 26 rows
  Xmin = sample(90, 26, replace = T),
  Ymin = sample(90, 26, replace = T),
  Zmin = sample(90, 26, replace = T)
)

df$XYZmin <- rowSums(df[,c("Xmin", "Ymin", "Zmin")])*df$IndoorOutdoor
df[,8:10] <- df[,4:6]*df[,3] #Adding the sign to each X/Y/Z
names(df)[8:10] <- paste0(names(df)[4:6],"p") #to differentiate from your X/Y/Z
require(ggplot2)

对于使用geom_bar的解决方案,我将df进行融合,以便绘制单个值,并将fill映射到变量(Xmin等)。

df.m <- melt(df[,c(1:3,7:10)], measure.vars=c("Xminp", "Yminp", "Zminp"))
plot.alt <- ggplot(df.m, aes(date, value, fill=variable)) + 
  geom_bar(position="stack", stat="identity", width=0.5) + #width is just to make it look like yours
#All of this is from your original plot
  geom_text(aes(y=XYZmin,label=paste(action, '\n this happed on ', date)),size=2.5,hjust=-.01, vjust=-.01, angle = 35) + 

  geom_point(aes(y=XYZmin), show_guide=FALSE) +
  geom_hline(y=0,size=1,color='purple') +
  theme(axis.text.y = element_blank()) + ylab('') + xlab('') +
  labs(title = "Timeline for when what happened")
plot.alt

输入图像描述

另一种方法是使用geom_segment来构建它:

plot <- ggplot(df,aes(x=date)) +
#Three geom_segments 
  geom_segment(aes(y=0,yend=Xminp,xend=date), colour= "blue") +
  geom_segment(aes(y=Xminp,yend=Xminp + Yminp,xend=date), colour= "red") +
  geom_segment(aes(y=Xminp + Yminp,yend=Xminp + Yminp + Zminp,xend=date), colour= "green") +
#This is all from your plot
  geom_text(aes(y=XYZmin,label=paste(action, '\n this happed on ', date)),size=2.5,hjust=-.01, vjust=-.01, angle = 35) +
  geom_point(aes(y=XYZmin)) +
  geom_hline(y=0,size=1,color='purple') +
  theme(axis.text.y = element_blank()) + ylab('') + xlab('') +
  labs(title = "Timeline for when what happened")
plot

希望这有意义……如果不是你想要的,请告诉我。 在此输入图片描述

非常感谢您提供的非常好的答案! - Eric Fail

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接