ggplot2 中 geom_bar 顶部的重叠文本

Overlapping text on top of geom_bar in ggplot2

我使用 ggplot2 制作了一个类似于下面的条形图。

我无法使条形顶部的百分比居中并且不与其他条形和数字重叠。示例代码如下。

library(tidyverse)

cat1=c("cat1","cat1","cat1","cat1","cat1","cat1","cat1","cat1","cat1","cat1","cat1","cat1",
       "cat2","cat2","cat2","cat2","cat2","cat2","cat2","cat2","cat2","cat2","cat2","cat2",
       "cat3","cat3","cat3","cat3","cat3","cat3","cat3","cat3","cat3","cat3","cat3","cat3",
       "cat4","cat4","cat4","cat4","cat4","cat4","cat4","cat4","cat4","cat4","cat4","cat4")
cat2=c("c1","c2","c3","c4","c5","c6","c7","c8","c9","c10","c11","c12",
       "c1","c2","c3","c4","c5","c6","c7","c8","c9","c10","c11","c12",
       "c1","c2","c3","c4","c5","c6","c7","c8","c9","c10","c11","c12",
       "c1","c2","c3","c4","c5","c6","c7","c8","c9","c10","c11","c12")
count1=round(rnorm(48,10))
fakeperc=rnorm(48,9)
df1=cbind(count1,fakeperc)
df2=cbind(cat1,cat2)
finaldf=as.data.frame(cbind(df1,df2))
finaldf$cat1=as.factor(finaldf$cat1)
finaldf$fakeperc=as.numeric(finaldf$fakeperc)

#finaldf$cat1=factor(finaldf$cat1,levels = c("cat1","cat2","cat3","cat4"))
finaldf$cat2 = factor(finaldf$cat2,
                levels = c("c1","c2","c3","c4","c5","c6","c7","c8","c9","c10","c11","c12"))

a=ggplot(data=finaldf,aes(x=cat1, y=count1,
                              fill=cat2,group=cat2)) +
  geom_bar(stat='identity',color='black',width=.65,position=position_dodge(width=.9))+
  scale_y_discrete(limits=0:50,breaks=c(0,10,20,30,40,50))+
  scale_fill_brewer(palette="Set3") +
  theme_classic() +
  geom_text(data = finaldf,
            aes(x=cat1,y=count1,group=cat2,
            label=format(paste(round(fakeperc),"%",sep = ""))),inherit.aes = F,
            color='black',position=position_dodge(.9),vjust=-.5,size=3)
a

尝试将 nudge_y 或 nudge_x 添加到 geom_text 调用时,没有任何反应。我怀疑这是因为已经有一个 position_dodge 调用。我开放任何和所有解决方案,以使这些百分比不重叠且清晰易读。

这是您要找的吗:

library(ggplot2)
#Code
ggplot(data=finaldf,aes(x=cat2, y=count1,
                          fill=cat2,group=cat2)) +
  geom_bar(stat='identity',color='black',
           position=position_dodge(width=1))+
  scale_fill_brewer(palette="Set3") +
  theme_bw() +
  geom_text(aes(x=cat2,y=count1,group=cat2,
                label=format(paste(round(fakeperc),"%",sep = ""))),inherit.aes = F,
            color='black',position=position_dodge(1),
            size=3,vjust=-0.5)+
  facet_wrap(.~cat1,scales = 'free_x',nrow = 1,strip.position = 'bottom')+
  theme(axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        legend.position = 'top',
        strip.background = element_blank(),
        panel.spacing = unit(2, "lines"),
        panel.grid = element_blank())+
  guides(fill = guide_legend(nrow = 1))

输出:

你怎么看这个?

# I think you meant count1 to be numeric
finaldf$count1 <- as.numeric(finaldf$count1)

ggplot(data = finaldf,
       aes(x     = cat1, 
           y     = count1,
           fill  = cat2,
           group = cat2)) +
 geom_col(color = 'black',
          width = 0.65,
          position = position_dodge(width = 0.9)) +
 geom_text(data = finaldf,
           aes(x     = cat1,
               y     = count1,
               group = cat2,
               label = scales::percent(fakeperc/100, accuracy = 0.01)),
           inherit.aes = FALSE,
           color = 'black',
           position = position_dodge(0.9),
           hjust = -0.1,
           size = 3) +
 scale_y_continuous(limits = c(0,50), breaks = c(0,10,20,30,40,50)) +
 scale_fill_brewer(palette = "Set3") +
 theme_classic() +
 coord_flip()

  • 我整理了一下代码(根据我的口味)
  • 我将 scale_y_numeric 更改为 scale_y_continuous(因为 count1 应该是数字)
  • 我使用 coord_flip() 使其更具可读性
  • 我用scales::percent写百分比数字

(不知道你为什么设置从 0 到 50 的限制,但我按照我的预期保留了它们)


如果你不想使用coor_flip:

finaldf$count1 <- as.numeric(finaldf$count1)

ggplot(data = finaldf,
       aes(x     = cat1, 
           y     = count1,
           fill  = cat2,
           group = cat2)) +
 geom_col(color = 'black',
          width = 0.65,
          position = position_dodge(width = 0.9)) +
 geom_text(data = finaldf,
           aes(x     = cat1,
               y     = count1,
               group = cat2,
               label = scales::percent(fakeperc/100, accuracy = 0.01)),
           inherit.aes = FALSE,
           color = 'black',
           position = position_dodge(0.9),
           hjust = -0.1,
           angle = 90,
           size = 3) +
 scale_y_continuous(limits = c(0,50), breaks = c(0,10,20,30,40,50)) +
 scale_fill_brewer(palette = "Set3") +
 theme_classic()