我在R中绘制了一个带ggplot2的图,我希望y轴的标题出现在图的左上角。请考虑以下代码以获取默认行为:
require(ggplot2)
xy = data.frame(x=1:10, y=10:1)
ggplot(data = xy) +
geom_point(aes(x = x, y = y)) +
ylab("very long label")
这会生成以下图表:
我想移动并旋转文本“非常长的标签”。我可以使用theme()
函数来做一些事情:
ggplot(data = xy) +
geom_point(aes(x = x, y = y)) +
ylab("very long label") +
theme(axis.title.y = element_text(angle = 0, vjust = 1.1, hjust = 10))
这给了我这个:
您可以看到我的目的地,但边距不正确 - 左边距太大,因为空间是为旋转标签保留的,而上边距对于文字来说太小了。
如何告诉ggplot我希望y轴标题在该位置没有旋转并让它为它保留适当的空间?
答案 0 :(得分:6)
将它放在主图标题中:
ggplot(data = xy) +
geom_point(aes(x = x, y = y)) +
ggtitle("very long label") +
theme(plot.title = element_text(hjust = 0))
如果你喜欢使用负hjust
值,你可以将它稍微向左推,但如果你走得太远,标签将被剪裁。在这种情况下,您可以尝试使用plot.margin
:
ggplot(data = xy) +
geom_point(aes(x = x, y = y)) +
ggtitle("very long label") +
theme(plot.title = element_text(hjust = -0.3),
plot.margin = rep(grid::unit(0.75,"in"),4))
很明显,这使得向图表添加实际标题变得很困难。您始终可以使用以下内容手动注释:
grid.text("Actual Title",y = unit(0.95,"npc"))
或者反过来,使用grid.text
作为y标签。
答案 1 :(得分:1)
我刚刚遇到了同样的问题,并找到了对社区有用的解决方案。
这个想法是创建一个自定义主题,用副标题替换轴标签。下面以示例为例:
p <- ggplot2::ggplot(iris, ggplot2::aes(x = Sepal.Width, y = Sepal.Length,
color = Species)) +
ggplot2::geom_point()
创建一个类mytheme
,该类可以修改ggplot
使用的主题。在此,在极简解决方案中,不对样式进行任何限制(我将在稍后介绍限制)。
custom_theme <- function(...){
out <- ggplot2::theme_minimal() + ggplot2::theme(...)
class(out) <- c("mytheme",class(ggplot2::theme_minimal()))
return(out)
}
与此类相关联的ggplot_add
方法将覆盖默认方法。此自定义方法采用现有的y
标签并将其放入subtitle
中。在函数的前两行进行替换。函数的第三行使用稍后定义的update_theme
函数:
ggplot_add.mytheme <- function(object, plot, object_name) {
plot$labels$subtitle <- plot$labels$y
plot$labels$y <- NULL
plot$theme <- update_theme(plot$theme, object)
plot
}
update_theme
函数是ggplot2
软件包的一部分,直到最近。该功能最近消失了(see this commit)。我实现的技巧是这样定义函数:
update_theme <- function(oldtheme, newtheme) {
# If the newtheme is a complete one, don't bother searching
# the default theme -- just replace everything with newtheme
if (isTRUE(attr(newtheme, "complete", exact = TRUE)))
return(newtheme)
# These are elements in newtheme that aren't already set in oldtheme.
# They will be pulled from the default theme.
newitems <- !names(newtheme) %in% names(oldtheme)
newitem_names <- names(newtheme)[newitems]
oldtheme[newitem_names] <- theme_get()[newitem_names]
# Update the theme elements with the things from newtheme
# Turn the 'theme' list into a proper theme object first, and preserve
# the 'complete' attribute. It's possible that oldtheme is an empty
# list, and in that case, set complete to FALSE.
old.validate <- isTRUE(attr(oldtheme, "validate"))
new.validate <- isTRUE(attr(newtheme, "validate"))
oldtheme <- do.call(theme, c(oldtheme,
complete = isTRUE(attr(oldtheme, "complete")),
validate = old.validate & new.validate))
oldtheme + newtheme
}
然后可以使用theme
创建预期的输出:
p + ggplot2::labs(y = "A very very long label") + custom_theme()
如果以后要更改轴标题的某些样式元素(例如,文本大小),则 y 标签将是一个问题,因为它是字幕元素。例如,运行的用户
p + custom_theme(axis.title = ggplot2::element_text(size = 24))
希望 y 标签的尺寸也为24。我认为这不是一个真正的问题,因为您可以更改custom_theme
并增加约束条件
labs
后设置theme
时如果用户在更改theme
之前设置labs
,例如,
p + ggplot2::labs(y = "A very very long label") + custom_theme() + ggplot2::labs(y = "override")