[英]How do I draw an arrow on a histogram drawn using ggplot2?
這是數據集:
set.seed(123)
myd <- data.frame (class = rep(1:4, each = 100), yvar = rnorm(400, 50,30))
require(ggplot2)
m <- ggplot(myd, aes(x = yvar))
p <- m + geom_histogram(colour = "grey40", fill = "grey40", binwidth = 10) +
facet_wrap(~class) + theme_bw( )
p + opts(panel.margin=unit(0 ,"lines"))
我想為每個主題類落入的條形圖添加標簽,並生成類似后期功率點處理圖形的內容。 在R中有沒有辦法做到這一點? ......
編輯:我們可以想到不同的指針,如點或誤差條,如果箭頭不是不可能的話
讓我們說以下是要標記的主題:
class name yvar
2 subject4 104.0
3 subject3 8.5
3 subject1 80.0
4 subject2 40.0
4 subject1 115.0
classd <- data.frame (class = c(2,3,3,4,4),
name = c ("subject4", "subject3", "subject1", "subject2", "subject1"),
yvar = c(104.0, 8.5,80.0,40.0, 115.0))
以下是使用geom_text()
添加標簽的部分解決方案,使用arrow
選項添加geom_segment()
以添加箭頭。
缺點是我必須為每個箭頭和標簽手動選擇y位置。 也許其他人可以幫助弄清楚如何以編程方式找到直方圖欄高度。
set.seed(123)
myd <- data.frame (class = rep(1:4, each = 100), yvar = rnorm(400, 50,30))
library(ggplot2)
library(grid) # unit() is in the grid package.
arrow_pos = read.table(header=TRUE, stringsAsFactors=FALSE,
text="class name yvar
2 subject4 104.0
3 subject3 8.5
3 subject1 80.0
4 subject2 40.0
4 subject1 115.0")
arrow_pos$y = c(3, 5, 9, 13, 1) # Manually enter y position.
arrow_pos$class = factor(as.character(arrow_pos$class),
levels=c("1", "2", "3", "4")) # Gets rid of warnings.
p1 = ggplot(myd, aes(x=yvar)) +
theme_bw() +
geom_histogram(colour="grey40", fill="grey40", binwidth=10) +
facet_wrap(~ class) +
opts(panel.margin=unit(0 ,"lines")) +
geom_text(data=arrow_pos, aes(label=name, x=yvar, y=y + 2), size=3) +
geom_segment(data=arrow_pos,
aes(x=yvar, xend=yvar, y=y + 1.5, yend=y + 0.25),
arrow=arrow(length=unit(2, "mm")))
png("p1.png", height=600, width=600)
print(p1)
dev.off()
不推薦使用Update opts
; 使用theme
代替。
稍微擴展bdemarest的響應,我認為這會以編程方式計算條形高度。 arrow_pos
的最后兩列包含相關信息: Freq
是條形的高度; xval
在條形中點的x位置。 但是,有些標簽與條形圖重疊。
編輯默認情況下, cut
其間隔限制為(b1,b2),而它表示ggplot2
其在geom_histogram中的間隔限制為[b1,b2]。 我修改了代碼,以便將它們的間隔限制為[b1,b2],即ggplot方式。
library(ggplot2)
library(grid) # unit() is in the grid package.
library(plyr) # Data restructuring
set.seed(123)
myd <- data.frame (class = rep(1:4, each = 100), yvar = rnorm(400, 50, 30))
arrow_pos = read.table(header=TRUE, stringsAsFactors=FALSE,
text="class name yvar
2 subject4 104.0
3 subject3 8.5
3 subject1 80.0
4 subject2 40.0
4 subject1 115.0")
# Calculate the y positions for the labels and arrows
# For the myd data frame, obtain counts within each bin, but separately for each class
bwidth <- 10 # Set binwidth
Min <- floor(min(myd$yvar)/bwidth) * bwidth
Max <- ceiling(max(myd$yvar)/bwidth) * bwidth
# Function to do the counting
func <- function(df) {
tab = as.data.frame(table(cut(df$yvar, breaks = seq(Min, Max, bwidth), right = FALSE)))
tab$upper = Min + bwidth * (as.numeric(rownames(tab)))
return(tab)
}
# Apply the function to each class in myd data frame
TableOfCounts <- ddply(myd, .(class), function(df) func(df))
# Transfer counts of arrow_pos
arrow_pos$upper <- (floor(arrow_pos$yvar/bwidth) * bwidth) + bwidth
arrow_pos <- merge(arrow_pos, TableOfCounts, by = c("class", "upper"))
arrow_pos$xvar <- (arrow_pos$upper - .5 * bwidth) # x position of the arrow is at the midpoint of the bin
arrow_pos$class=factor(as.character(arrow_pos$class),
levels=c("1", "2", "3", "4")) # Gets rid of warnings.
ggplot(myd, aes(x=yvar)) +
theme_bw() +
geom_histogram(colour="grey70", fill="grey70", binwidth=bwidth) +
facet_wrap(~ class) +
theme(panel.margin=unit(0, "lines")) +
geom_text(data=arrow_pos, aes(label=name, x=xvar, y=Freq + 2), size=4) +
geom_segment(data=arrow_pos,
aes(x=xvar, xend=xvar, y=Freq + 1.5, yend=Freq + 0.25),
arrow=arrow(length=unit(2, "mm")))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.