ggplot2:y轴标签在绘图区域内左对齐 [英] ggplot2: y axis labels left-justified inside plot area

查看:238
本文介绍了ggplot2:y轴标签在绘图区域内左对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种自动移动y轴刻度标签的方法,以使它们在实际绘图区域内显示为左对齐的.我喜欢ggplot中主题组件的通用灵活性,但是遇到了麻烦,试图找到一种通用的方式来实现此目的.

I'm looking for a way to automatically move the y-axis tick labels so that they appear left-justified within the actual plot area. I love the general flexibility of theme components in ggplot, but ran into a wall trying to find a general way to do this.

我知道给 axis.text.y just = 0 并加上负的右边距(* gag *)可以达到这种效果,但是负的空白必须手动设置以匹配最长的y轴刻度标签的宽度.

I know giving axis.text.y a combination of hjust=0 and a negative right margin (*gag*) can accomplish this effect, but the negative margin has to be manually set to match the width of the longest y-axis tick label.

作为示例,请考虑以下代码:

As an example, consider the following code:

library(ggplot2)

set.seed(0)
dat <- data.frame(x = 1:100, y = (1:100) + runif(100, -10, 10))

p1 <- ggplot(dat, aes(x, y)) + 
  geom_line() +
  scale_y_continuous("", breaks = c(0, 30, 60, 90),
                     labels = c(0, 30, 60, "90 units of something")) +
  theme(axis.text.y = element_text(hjust = 0,
                                   margin = margin(0, -3.1, 0, 0, 'cm')))

我认为它很好地将y轴标签(例如某物的单位" )合并到绘图主体中,但是为了实现它,请使用 -3.1 的最后一行必须手动找到(通过反复试验),这增加了侮辱性伤害:我不仅使用负边距将文本拖到不需要的位置,而且还抛出了带有一些神秘的,易碎的,硬编码的魔术数字.

I think it elegantly incorporates the y-axis label (e.g., "units of something") into the body of the plot, but in order to accomplish it, the -3.1 in the last line has to be found manually (by trial and error), which adds insult to injury: not only am I using a negative margin to pull text where it doesn't want to be -- I'm throwing in some arcane, fragile, hard-coded magic number.

有人知道我可以在哪里找到更通用,更优雅的解决方案吗?

Does anyone know where I can look for a more general and elegant solution to this problem?

推荐答案

这是一个使用grobs的骇客,它将y轴标签从其原始位置移开,以覆盖绘图区域.

Here's a hack using grobs, which shifts the y-axis labels away from its original position to overlap the plot area.

虽然我认为它不是很优雅(毕竟这是一种需要在 ggplotGrob 中进行转换的hack),但定位不是硬编码的,&您可以在转换之前 ggplot() 中指定所需的主题控件.

While I don't consider it exactly elegant (it's a hack that requires conversion in ggplotGrob after all), the positioning is not hard-coded, & you can specify whatever theme control you want in ggplot() before conversion.

设置:

library(ggplot2)
library(grid)
library(gtable)

# sample data
set.seed(0)
dat <- data.frame(x=1:100, y=(1:100) + runif(100, -10, 10))

# create ggplot object
p <- ggplot(dat, aes(x, y)) + 
  geom_line() +
  scale_y_continuous("", 
                     breaks = c(0, 30, 60, 90),
                     labels = c(0, 30, 60, "90 units of something")) +
  # left-align y-axis labels
  # you can also specify other theme parameters as desired
  theme(axis.text.y = element_text(hjust = 0))

不知所措:

# convert from ggplot to grob object
gp <- ggplotGrob(p)

# locate the grob that corresponds to y-axis labels
y.label.grob <- gp$grobs[[which(gp$layout$name == "axis-l")]]$children$axis    

# remove y-axis labels from the plot, & shrink the space occupied by them
gp$grobs[[which(gp$layout$name == "axis-l")]] <- zeroGrob()
gp$widths[gp$layout$l[which(gp$layout$name == "axis-l")]] <- unit(0, "cm")

使用水平顺序[ticks] [labels] [buffer space]为y轴刻度/标签定义一个新的grob:

Define a new grob for the y-axis ticks / labels, with the horizontal order [ticks][labels][buffer space]:

# create new gtable
new.y.label.grob <- gtable(heights = unit(1, "npc"))

# place axis ticks in the first column
new.y.label.grob <- gtable_add_cols(new.y.label.grob,
                                    widths = y.label.grob[["widths"]][2])
new.y.label.grob <- gtable_add_grob(new.y.label.grob,
                                    y.label.grob[["grobs"]][[2]],
                                    t = 1, l = 1)

# place axis labels in the second column
new.y.label.grob <- gtable_add_cols(new.y.label.grob,
                                    widths = y.label.grob[["widths"]][1])
new.y.label.grob <- gtable_add_grob(new.y.label.grob,
                                    y.label.grob[["grobs"]][[1]],
                                    t = 1, l = 2)

# add third column that takes up all the remaining space
new.y.label.grob <- gtable_add_cols(new.y.label.grob,
                                    widths = unit(1, "null"))

在与绘图区域相同的位置,将新定义的y轴标签grob重新添加到绘图grob中:

Add the newly defined y-axis label grob back to the plot grob, in the same location as the plot area:

gp <- gtable_add_grob(gp,
                      new.y.label.grob,
                      t = gp$layout$t[which(gp$layout$name == "panel")],
                      l = gp$layout$l[which(gp$layout$name == "panel")])

检查结果:

grid.draw(gp)

这篇关于ggplot2:y轴标签在绘图区域内左对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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