x轴上的附加标签作为分隔符的图例

时间:2016-07-27 09:41:56

标签: r ggplot2

我是新来的,所以如果我忘记了,请原谅我。 我试图得到像下面的图像。但是我在两点上苦苦挣扎:我的线不直接从y轴开始,我想要在x轴的测量下方和x轴的标签两个标签作为vline的图例。我试图用annotation_custom来获取它,但是这把它放在了剧情本身,但我希望它在x轴上或在剧情的顶部,而不是写在图表本身上。

到目前为止,我使用了以下代码:

require(reshape)
library(ggplot2)

user <- gl(3, 1)
Meas1 <- c(0.7, 0.3, 0.3)
Meas2 <- c(0.7, 0.3, 0.3)
Meas3 <- c(0.2, 0.4, 0.4)
group <- c(3, 2, 2)
df <- data.frame(user=user, Meas1=Meas1, Meas2=Meas2, Meas3=Meas3, group=group)

dfm <- melt(df, id.vars=c("user", "group"))
flevels=as.vector.factor(unique(dfm$variable))

ggplot(dfm, aes(x=factor(variable), y=value, colour=user, group=user)) + 
  geom_line() + 
  scale_x_discrete(breaks=flevels, labels=flevels)

这就是我想要的方式(标签是class1和class2)

enter image description here

我真的很乐意帮助你。

2 个答案:

答案 0 :(得分:0)

要直接在y轴处开始直线,您需要将展开参数放到scale_x_discrete函数中,例如:

scale_x_discrete(breaks=flevels, labels=flevels, expand = c(0,0)) 

您可以添加如下图例:

theme(legend.position = 'bottom')

只要您的数据中有三个用户具有相同的值,结果就是三个标签。我认为通过消除用户2来对数据进行子集化将是获得两个标签的最简单方法。

答案 1 :(得分:0)

有些可能性浮现在脑海中。我在下面提出三个。在这三个中,我定位了#1; Class 1&#34;和&#34; 2级&#34;图表顶部的标签。但我不确定你想要在第1类和第34类之间划分界限的方式和位置。和&#34; 2级和#34;。我把它放在图表的一半以上。

第一个是最简单的。它使用annotate定位标签。据我所知,没有简单的方法来划分两个区域的短线段。在这里,我在图表上绘制一条线,但因为它遍历了情节面板,我认为这是一种分心。

第二个构造包含两个标签和一个短线段的grob,然后使用annotation_custom定位grob。第三个也构造了一个grob(尽管grob构造稍微简单一点),然后使用gtable包中的函数定位grob。

以下更多评论。

# Your data
require(reshape)

user <- gl(3, 1)
Meas1 <- c(0.7, 0.3, 0.3)
Meas2 <- c(0.7, 0.3, 0.3)
Meas3 <- c(0.2, 0.4, 0.4)
group <- c(3, 2, 2)
df <- data.frame(user=user, Meas1=Meas1, Meas2=Meas2, Meas3=Meas3, group=group)

dfm <- melt(df, id.vars = c("user", "group"))
flevels = as.vector.factor(unique(dfm$variable))

第一种方法annotate

标签位于绘图面板的顶部,然后使用vjust将文本移动到绘图面板之外。顶部绘图边距被加宽以为标签提供空间。由于文本正在绘图面板外绘制,因此需要关闭对绘图面板的裁剪。

library(ggplot2)
library(grid)

# The plot
p = ggplot(dfm, aes(x = factor(variable), y = value, colour = user, group = user)) + 
   geom_line() + 
   scale_x_discrete(breaks = flevels, labels = flevels) +
   theme(plot.margin = unit(c(1.5, .1, .1, .1), "lines"))

# plus the annotations
p = p + annotate("text", x = c(1.35, 2.85), y = Inf, label = c("Class 1", "Class 2"), vjust = -.75) +
        annotate("segment", x = 2.2, xend = 2.2, y = -Inf, yend = Inf)

# Turn off clipping
gp = ggplotGrob(p)
gp$layout[gp$layout$name == "panel", "clip"] = "off"

# Draw the plot
grid.newpage()
grid.draw(gp)

第二种方法annotation_custom

有几种方法可以定位元素。在这里,我在构建grob中进行定位,然后annotation_custom可以跨越-InfInf。为了使y坐标正确,有一点反复试验。此外,由于grob正在绘图板外部绘制,因此需要加宽顶部绘图边距,并且需要关闭对面板的裁剪。

xpos = .6 # of the demarcation between the two labels; in npc units

# Construct the grob
lab1 = textGrob("Class 1", x = .5 * xpos, y = 1.02)
lab2 = textGrob("Class 2", x = .5 + .5 * xpos, y = 1.02)
seg = linesGrob(x = c(xpos, xpos), y = c(1, 1.04))

labs = gTree(children = gList(lab1, lab2, seg))

p = ggplot(dfm, aes(x = factor(variable), y = value, colour = user, group = user)) + 
   geom_line() + 
   scale_x_discrete(breaks = flevels, labels = flevels) +
   theme(plot.margin = unit(c(1.5, .1, .1, .1), "lines")) +

   annotation_custom(labs, xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf)

gp = ggplotGrob(p)
gp$layout[gp$layout$name == "panel", "clip"] = "off"

grid.newpage()
grid.draw(gp)

第三种方法gtable函数

构建了grob,但需要担心y坐标。 gtable函数在gtable的顶部添加一行(即绘图),然后将grob插入该行。 tl引用gtable布局中的行和列。 gtable_show_layout(gp)将显示布局。另请参阅gtable帮助页面(?gtable_add_rows?gtable_add_grob

library(gtable)

xpos = .6 # in npc units
lab1 = textGrob("Class 1", x = .5 * xpos)
lab2 = textGrob("Class 2", x = .5 + .5 * xpos)
seg = linesGrob(x = c(xpos, xpos))

labs = gTree(children = gList(lab1, lab2, seg))

p = ggplot(dfm, aes(x = factor(variable), y = value, colour = user, group = user)) + 
   geom_line() + 
   scale_x_discrete(breaks = flevels, labels = flevels)

gp = ggplotGrob(p)

row = 2
gp = gtable_add_rows(gp, unit(2, "grobheight", lab1), row)

l = gp$layout[grepl("panel", gp$layout$name), ]$l
gp = gtable_add_grob(gp, labs, t = row + 1, l = l)

grid.newpage()
grid.draw(gp)

enter image description here