ggplot函数添加文字在传奇下方 [英] ggplot function to add text just below legend

查看:200
本文介绍了ggplot函数添加文字在传奇下方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在RI中,想要创建一个函数,它需要一个ggplot对象和一些文本,并通过在图例下方添加文本来返回和ggplot对象(在图的右侧,同时保留右侧的图例) p>

  myplot = ggplot(iris,aes(x = Sepal.Length,y = Sepal.Width,color = Species))+ 
geom_line()

我想添加Sepal.Width = 3.05就在这个传说之后)。我查看了相关的问题,但他们将图例的位置改变为底部,并且不作为函数工作,而是打印该图。

解决方案

一些可能性。

第一个使用 annotate(),并且涉及通过反复试验。 x位置使用 hjust 进行调整,y位置被选择为略低于图例。注意:文字周围没有边框。



第二个假设需要边框。组合文本和框使用 grid 构造。然后使用 annotation_custom()定位grob。 ymin ymax 被设置为略低于图例。通过反复试验设置 xmin xmax 以使文本和图例对齐。

这两种方法都涉及在绘图面板外绘图,因此需要关闭绘图面板的裁剪。但是,如果文字大小或长度发生变化,标签的位置需要调整。



第三种方法对文本长度和大小的变化具有相当的稳健性。与方法2相似,组合文本和框格grob使用 grid 构造。然后,使用 gtable 函数,将grob附加到图例(位于图例的中间列)。

 #1. 
library(ggplot2)
library(grid)
library(gtable )

#标签
label =平均值Sepal.Width = 3.05

#该图 - 注意标签$ b $的额外保证金空间b myplot = ggplot(iris,aes(x = Sepal.Length,y = Sepal.Width,color = Species))+
geom_line()+
annotate(text,x = Inf,y = $ 2.88,label = label,hjust = -0.08,size = 3)+
主题(plot.margin = unit(c(.5,6,.5,.5),lines),
legend.background = element_rect(color =black))

#关闭剪切到绘图面板
g = ggplotGrob(myplot)
g $ layout $ clip [g $ layout $ name ==panel] =off
grid.draw(g)


#2.
#构建标签grob - a文本和框的组合
textgrob = textGrob(label,gp = gpar(cex = .75),)
width = unit(1,grobwidth,textgrob)+ unit(10,points )
height = unit(1,grobheight,textgrob)+ unit(10,points)
rectgrob = rectGrob(gp = gpar(col我们=黑色,填充= NA),高度=高度,宽度=宽度)
labelGrob = gTree(labelGrob,children = gList(rectgrob,textgrob))

# plot - 注意标签的额外空白区域
myplot = ggplot(iris,aes(x = Sepal.Length,y = Sepal.Width,color = Species))+
geom_line()+
annotation_custom(labelGrob,
xmin = 1.137 * max(iris $ Sepal.Length),xmax = 1.137 * max(iris $ Sepal.Length),
ymin = 2.9,ymax = 2.9)+
主题(plot.margin = unit(c(0.5,6,0.5,0.5),lines),
legend.background = element_rect(color =black))

#关闭剪切到绘图板
g = ggplotGrob(myplot)
g $ layout $ clip [g $ layout $ name ==panel] =off
grid.draw (g)




#3。
#标签
label =Mean of\\\
Sepal.Width = 3.05
#尝试不同的标签
#label =a

#绘图
myplot = ggplot(iris,aes(x = Sepal.Length,y = Sepal.Width,color = Species))+
geom_line()+
theme(legend。 background = element_rect(color =black))

#获取图例
g = ggplotGrob(myplot)
leg = g $ grobs [[which(g $ layout $ name ==guide-box)]]

#构建标签grob
xpos = 5
textgrob = textGrob(x = unit(xpos,points),label ,gp = gpar(cex = .75),just =left)
width = unit(1,grobwidth,textgrob)+ unit(2 * xpos,points)#x b $ b height = unit(1,grobheight,textgrob)+ unit(2 * xpos,points)
rectgrob = rectGrob(x = unit(0,points),just =left ,
gp = gpar(color =black,fill = NA),height = height,width = width)
labelGrob = gTree(labelGrob,children = gList(rectgrob,textgrob))

#将标签grob添加到新行添加编辑到图例
pos = subset(leg $ layout,grepl(guides,name),t:r)

leg = gtable_add_rows(leg,height,pos = pos $ t +1)
leg = gtable_add_grob(leg,labelGrob,t = pos $ t + 2,l = pos $ l)

#将图例的中间宽度调整为原始宽度
#或grob的宽度
leg $ widths [pos $ l] = max(width,leg $ widths [pos $ l])

#添加传说的两部分之间的一些空间
leg $ heights [pos $ t + 1] = unit(5,pt)

#将修改过的图例返回到原始图
g $ grobs [[which(g $ layout $ name ==guide-box)]] = leg

#将包含图例的列的宽度调整为最大
#原始宽度或标签的宽度
g $ widths [g $ layout [grepl(guide-box,g $ layout $ name),l]] = max(width,sum (leg $ widths))

#绘制绘图
grid.newpage()
grid.draw(g)


In R I want to make a function which takes an ggplot object and some text and returns and ggplot object by adds text just below the legend (in the right side of the plot, while keeping legend on the right side).

myplot = ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species)) + 
           geom_line()

I want to add text "mean of Sepal.Width = 3.05" (and a box around it) just after the legend. I looked at related questions but they change the position of legend to bottom and do not work as a function rather prints the plot.

解决方案

A couple of possibilities.

The first uses annotate(), and involves positioning the text by trial and error. The x position is adjusted using hjust, the y position is selected to be a little below the legend. Note: no border around the text.

The second assumes a border is required. The combined text and box is constructed using grid. Then the grob is positioned using annotation_custom(). ymin and ymax are set to be a little below the legend. xmin and xmax are set by trial and error to get the text and the legend to align.

Both methods involve plotting outside the plot panel, so clipping to the plot panel needs to be turned off. But if the text size or length changes, the position of the label needs to be adjusted.

The third method is reasonably robust to changes to text length and size. Similar to method 2, the combined text and box grob is constructed using grid. Then, using gtable functions, the grob is attached to the legend (to the middle column of the legend).

# 1.
library(ggplot2)
library(grid)
library(gtable)

# The label
label = "Mean of Sepal.Width = 3.05"

# The plot - Note the extra margin space for the label
myplot = ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species)) + 
    geom_line() +   
    annotate("text", x = Inf, y = 2.9, label = label, hjust = -0.08, size = 3) +
    theme(plot.margin = unit(c(.5,6,.5,.5),"lines"),
          legend.background = element_rect(colour = "black"))

# Turn off clipping to the plot panel
g = ggplotGrob(myplot)
g$layout$clip[g$layout$name == "panel"] = "off"
grid.draw(g)


# 2.
# Construct the label grob - a combination of text and box
textgrob = textGrob(label, gp = gpar(cex = .75), )
width = unit(1, "grobwidth",textgrob) + unit(10, "points")
height = unit(1, "grobheight", textgrob)+ unit(10, "points")
rectgrob = rectGrob(gp=gpar(colour = "black", fill = NA), height = height, width = width)
labelGrob = gTree("labelGrob", children = gList(rectgrob, textgrob))

# The plot - Note the extra margin space for the label
myplot = ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species)) + 
    geom_line() +   
    annotation_custom(labelGrob,  
       xmin = 1.137*max(iris$Sepal.Length), xmax = 1.137*max(iris$Sepal.Length), 
       ymin = 2.9, ymax = 2.9) +
    theme(plot.margin = unit(c(0.5, 6, 0.5, 0.5), "lines"),
          legend.background = element_rect(colour = "black"))

# Turn off clipping to the plot panel
g = ggplotGrob(myplot)
g$layout$clip[g$layout$name == "panel"] = "off"
grid.draw(g)




#3.
# The label
label = "Mean of\nSepal.Width = 3.05"
# Try a different label
# label = "a"

# The plot
myplot = ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species)) + 
    geom_line() +   
    theme(legend.background = element_rect(colour = "black"))

# Get the legend
g = ggplotGrob(myplot)
leg = g$grobs[[which(g$layout$name == "guide-box")]]

# Construct the label grob 
xpos = 5
textgrob = textGrob(x = unit(xpos, "points"), label, gp = gpar(cex = .75), just = "left")
width = unit(1, "grobwidth",textgrob) + unit(2*xpos, "points")  # twice the x position
height = unit(1, "grobheight", textgrob)+ unit(2*xpos, "points")
rectgrob = rectGrob(x = unit(0, "points"), just = "left", 
    gp = gpar(colour = "black", fill = NA), height = height, width = width)
labelGrob = gTree("labelGrob", children = gList(rectgrob, textgrob))

# Add the label grob to a new row added to the legend
pos = subset(leg$layout, grepl("guides", name), t:r)

leg = gtable_add_rows(leg, height, pos = pos$t+1)
leg = gtable_add_grob(leg, labelGrob, t = pos$t+2, l = pos$l)

# Adjust the middle width of the legend to be the maximum of the original width 
# or the width of the grob
leg$widths[pos$l] = max(width, leg$widths[pos$l])

# Add some space between the two parts of the legend
leg$heights[pos$t+1] = unit(5, "pt")

# Return the modified legend to the origial plot
g$grobs[[which(g$layout$name == "guide-box")]] = leg

# Adjust the width of the column containing the legend to be the maximum 
# of the original width or the width of the label
g$widths[g$layout[grepl("guide-box", g$layout$name), "l"]] = max(width, sum(leg$widths))

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

这篇关于ggplot函数添加文字在传奇下方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆