使用一个 X 轴将辅助 X 轴标签添加到 ggplot

Add secondary X axis labels to ggplot with one X axis

**编辑,这里有两个很好的解决方案,一个被标记为答案,但是@hrbrmstr 提供了一个结合两个 ggplots 的很好的解决方案,它非常适合这个简单的情节。*

这是代码

breaks.major <- c(0,15,37.5,52.5,67.5,82.5,95,100) #defines the midpoints of the categories (label locations)
breaks.minor <- c(30,45,60,75,90) #defines the edges of the categories (second label set I need)
labels.minor <- c("","Extremely \nDissatisfied","Dissatisfied","Uncertain","Satisfied","Very \nSatisfied","Extremely \nSatisfied","")
lims =c(0,100)
g <- ggplot(mpg, aes(class))+
  geom_bar()+
  coord_flip()+
  scale_y_continuous(limit = lims, minor_breaks = breaks.minor, breaks = breaks.major, labels = labels.minor) +
  theme(panel.grid.major.x = element_blank()) +
  theme(panel.grid.major.y = element_blank()) +
  theme(axis.ticks.x=element_blank()) +
  theme(axis.title= element_blank()) 

它产生了这个情节:

我需要两组 X 轴标签,一组显示类别名称(即已经通过 labels.minor 存在的 "satisfied" 等),一组显示值breaks.minor 位置(对应于类别限制,即垂直面板网格线)。我需要当前 labels.minor 标签低于所需的附加标签。

我目前用换行符来做到这一点,这样数字和类别都在一个长字符串中,但是间距变得很有趣 plot resizes.I 可以用文本框来做到这一点(我假设),是吗ggplot中的一种方式?

如果您将我当前的标签放在其部分的中心(例如 "Extremely Satisfied" 偏离中心),则加分

这是我想要的输出(原谅我的'mspaint')

也许是这样的。注意两个轴的 expand 设置以处理适当的间距和类别名称的位置。

您图中的标签并没有真正偏离中心,它们位于类别边界的中心。只是默认情况下轴会进一步扩展。

如果你想要更花哨,你也可以在绘图区域之外绘制,但这需要更多的操作。 This question 应该让你开始。

ggplot(mpg, aes(class))+
  geom_bar()+
  geom_text(data = data.frame(br = breaks.minor), aes(y = br, label = br, x = 7.75),
            size = 4, col = 'grey30') +
  coord_flip()+
  scale_y_continuous(limit = lims, minor_breaks = breaks.minor, 
                     breaks = breaks.major, labels = labels.minor, 
                     expand = c(0, 0)) +
  scale_x_discrete(expand = c(0.05, 0)) +
  theme(panel.grid.major.x = element_blank()) +
  theme(panel.grid.major.y = element_blank()) +
  theme(axis.ticks.x=element_blank()) +
  theme(axis.title= element_blank())

我认为这符合您的要求:

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

breaks.major <- c(0, 15, 37.5, 52.5, 67.5, 82.5, 95, 100)
breaks.minor <- c(30, 45, 60, 75, 90)
labels.minor <- c("", "Extremely\nDissatisfied", "Dissatisfied", "Uncertain",
                  "Satisfied", "Very\nSatisfied", "Extremely\nSatisfied", "")
lims <- c(0, 100)

# build the main plot with the text axis
gg1 <- ggplot(mpg, aes(class))
gg1 <- gg1 + geom_bar()
gg1 <- gg1 + scale_y_continuous(expand=c(0,0), limit=lims, 
                                minor_breaks=breaks.minor, 
                                breaks=breaks.major,
                                labels=labels.minor)
gg1 <- gg1 + coord_flip()
gg1 <- gg1 + theme(panel.grid.major.x=element_blank())
gg1 <- gg1 + theme(panel.grid.major.y=element_blank())
gg1 <- gg1 + theme(axis.ticks.x=element_blank())
gg1 <- gg1 + theme(axis.title=element_blank())

# let ggplot2 do the work of building the second axis
gg2 <- ggplot(mpg, aes(class))
gg2 <- gg2 + scale_y_continuous(expand=c(0,0), limit=lims, 
                                breaks=c(0, breaks.minor, 100))
gg2 <- gg2 + coord_flip()
gg2 <- gg2 + theme(axis.ticks.x=element_blank())
gg2 <- gg2 + theme(axis.text.x=element_text(hjust=c(0, 0.5, 0.5, 0.5, 0.5, 0.5, 1)))

gt1 <- ggplot_gtable(ggplot_build(gg1))
gt2 <- ggplot_gtable(ggplot_build(gg2))
axis2 <- grid.arrange(gt2$grobs[[5]])

gt <- gtable_add_rows(gt1, unit(0.1, "null"), 4)
grid.arrange(gtable_add_grob(gt, axis2, t=5, l=4, b=5, r=4))

我把所有的标签都写成了主要标签。

# OP's
breaks.major <- c(0,15,37.5,52.5,67.5,82.5,95,100) #defines the midpoints of the categories (label locations)
breaks.minor <- c(30,45,60,75,90) #defines the edges of the categories (second label set I need)
labels.minor <- c("","Extremely \nDissatisfied","Dissatisfied","Uncertain","Satisfied","Very \nSatisfied","Extremely \nSatisfied","")
lims =c(0,100)

breaks.major2 <- c(0,15,37.5,52.5,67.5,82.5,95)
breaks.minor2 <- c(30,45,60,75,90,100)       # put 100 into minor from major

breaks.comb <- sort(c(breaks.major2, breaks.minor2 - 1.0E-6))  # avoid the just same value as minor
label.comb <- c(0, "\nExtremely \nDissatisfied", 30, "\nDissatisfied", 45, "\nUncertain", 60, 
                "\nSatisfied", 75, "\nVery \nSatisfied", 90, "\nExtremely \nSatisfied", 100)

library(ggplot2)
g <- ggplot(mpg, aes(class))+
  geom_bar()+
  coord_flip()+
  scale_y_continuous(limit = lims, minor_breaks = breaks.minor2, breaks = breaks.comb, 
                     labels = label.comb, expand = c(0,0)) +
  theme(panel.grid.major.x = element_blank()) +
  theme(panel.grid.major.y = element_blank()) +
  theme(axis.ticks.x=element_blank()) +
  theme(axis.title= element_blank()) +
  theme(plot.margin = unit(c(0.5, 0.5, 0.5, 0.5), "lines"))