2015-04-23 47 views
12

你能幫我註釋一個ggplot2散點圖嗎?用額外的勾號和標籤標註ggplot

爲了將典型的散點圖(黑色):

df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T)) 
ggplot(df, aes(x=x, y=y)) + geom_point() 

我想在一個額外的滴答聲的形式和自定義標籤(紅色)添加註釋:

示例圖片:

enter image description here

+0

請參閱'scale_x_continuous' –

+0

因此,我可以使用'scale_x_continuous'來更改所有刻度的格式和位置,但是我可以使用它來添加一個自定義刻度+標籤嗎?我沒有看到。 – magum

回答

14

四種解決方案。

第一次使用scale_x_continuous添加附加元素,然後使用theme來定製新的文本和刻度標記(加上一些額外的調整)。

第二個使用annotate_custom創建新的grobs:文本grob和一行grob。 grobs的位置在數據座標中。結果是如果y軸的極限改變,grob的定位將會改變。因此,下面的示例中y軸是固定的。另外,annotation_custom正試圖在繪圖面板外繪製。默認情況下,打開繪圖面板的剪輯。它需要被關閉。

第三個是第二個變體(並且從here引用代碼)。 grobs的默認座標系統是'npc',因此在建造grobs時垂直放置grobs。使用annotation_custom的grobs定位使用數據座標,因此請在annotation_custom中水平放置grobs。因此,與第二種解決方案不同,在此解決方案中Grobs的定位與y值的範圍無關。

第四個使用viewports。它爲查找文本和刻度標記設置了更便利的單位系統。在x方向上,位置使用數據座標;在y方向上,位置使用「npc」座標。因此,在這個解決方案中,grobs的定位與y值的範圍無關。

首個解決方案

## scale_x_continuous then adjust colour for additional element 
## in the x-axis text and ticks 
library(ggplot2) 
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T)) 

p = ggplot(df, aes(x=x, y=y)) + geom_point() + 
    scale_x_continuous(breaks = c(0,25,30,50,75,100), labels = c("0","25","xyz","50","75","100")) + 
    theme(axis.text.x = element_text(color = c("black", "black", "red", "black", "black", "black")), 
     axis.ticks.x = element_line(color = c("black", "black", "red", "black", "black", "black"), 
          size = c(.5,.5,1,.5,.5,.5))) 

# y-axis to match x-axis 
p = p + theme(axis.text.y = element_text(color = "black"), 
     axis.ticks.y = element_line(color = "black")) 

# Remove the extra grid line 
p = p + theme(panel.grid.minor = element_blank(), 
       panel.grid.major.x = element_line(color = c("white", "white", NA, "white", "white", "white"))) 
p 

enter image description here

第二種解決

## annotation_custom then turn off clipping 
library(ggplot2) 
library(grid) 
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T)) 

p = ggplot(df, aes(x=x, y=y)) + geom_point() + 
scale_y_continuous(limits = c(0, 4)) + 
annotation_custom(textGrob("xyz", gp = gpar(col = "red")), 
     xmin=30, xmax=30,ymin=-.4, ymax=-.4) + 
annotation_custom(segmentsGrob(gp = gpar(col = "red", lwd = 2)), 
     xmin=30, xmax=30,ymin=-.25, ymax=-.15) 

g = ggplotGrob(p) 
g$layout$clip[g$layout$name=="panel"] <- "off" 
grid.draw(g) 

enter image description here

方案三

library(ggplot2) 
library(grid) 
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T)) 

p = ggplot(df, aes(x=x, y=y)) + geom_point() 

gtext = textGrob("xyz", y = -.05, gp = gpar(col = "red")) 
gline = linesGrob(y = c(-.02, .02), gp = gpar(col = "red", lwd = 2)) 

p = p + annotation_custom(gtext, xmin=30, xmax=30, ymin=-Inf, ymax=Inf) + 
     annotation_custom(gline, xmin=30, xmax=30, ymin=-Inf, ymax=Inf) 

g = ggplotGrob(p) 
g$layout$clip[g$layout$name=="panel"] <- "off" 
grid.draw(g) 

enter image description here

方案四

更新至V2.2.0 GGPLOT2

## Viewports 
library(ggplot2) 
library(grid) 
df <- data.frame(x=seq(1:100), y=sort(rexp(100, 2), decreasing = T)) 

(p = ggplot(df, aes(x=x, y=y)) + geom_point()) 


# Search for the plot panel using regular expressions 
Tree = as.character(current.vpTree()) 
pos = gregexpr("\\[panel.*?\\]", Tree) 
match = unlist(regmatches(Tree, pos)) 
match = gsub("^\\[(panel.*?)\\]$", "\\1", match) # remove square brackets 
downViewport(match) 

####### 
# Or find the plot panel yourself 
# current.vpTree() # Find the plot panel 
# downViewport("panel.6-4-6-4") 
##### 

# Get the limits of the ggplot's x-scale, including the expansion. 
x.axis.limits = ggplot_build(p)$layout$panel_ranges[[1]][["x.range"]] 

# Set up units in the plot panel so that the x-axis units are, in effect, "native", 
# but y-axis units are, in effect, "npc". 
pushViewport(dataViewport(yscale = c(0, 1), xscale = x.axis.limits, clip = "off")) 
grid.text("xyz", x = 30, y = -.05, just = "center", gp = gpar(col = "red"), default.units = "native") 
grid.lines(x = 30, y = c(.02, -.02), gp = gpar(col = "red", lwd = 2), default.units = "native") 

upViewport(0) 

enter image description here

+1

很好的答案,沒有什麼補充。 – tonytonov

+1

非常感謝,我會選2號門;) – magum

0

以下將爲您提供xyz標籤及其上方的一行,您可能需要玩弄x和y位置以獲取它們正是你想要的地方。

ggplot(df, aes(x=x, y=y)) + geom_point() + annotate(x=27, y=0, label="xyz", color="red") +annotate(x=27, ymin=-1, ymax=1, color="red") 

更多信息here如果需要。

+0

'annotate'只允許在劇情內添加註釋。這不是我正在尋找的。 – magum