如何将不同对齐方式的堆叠条形图标签整齐地对齐?

3

我将我的标签大致对齐到了堆叠条形图的两侧。问题是它们看起来很凌乱,因为它们在每侧的条形上没有正确地左右对齐。我该如何解决这个问题,让它们看起来更专业呢?

df3 <- data.frame(
  Label = c("Dasher", "Dancer", "Comet", "Cupid", "Prancer", "Blitzen", "Rudolph"),
  Amount = c(650.01, 601.01, 340.05, 330.20, 260.01, 250.80, 10.10)
)

# Sort order
level_order <- df3 %>% 
  arrange(desc(Amount))

ggplot(level_order, aes(fill=fct_inorder(Label), y=Amount, x="")) + 
               geom_bar(position="stack", stat="identity", width = 0.55) +
               scale_fill_brewer(palette = "Blues", direction = -1) +
               theme_void() +
               geom_text(aes(label = paste0("$", Amount)),
                         position = position_stack(vjust = 0.5),
                         hjust = -3.1,
                         size = 5) +
               geom_text(aes(label = Label),
                         position = position_stack(vjust = 0.5),
                         hjust = 5,
                         size = 5) +
               theme(legend.position = "none") +
               theme(plot.title = element_text(size = 50, hjust = .5, vjust = 0)) +
               ggtitle("Food Costs by Reindeer")

enter image description here


1
请问您能否让问题更加清晰明了一些:您是想让左侧标签左对齐,右侧标签右对齐吗? - Peter
1
我们从中学到了什么?鲁道夫是真的! - tjebo
4个回答

2

hjust决定了文本的对齐方式(0表示左对齐,1表示右对齐)。目前你的geom_text的x坐标默认为1,因此更改它将会改变文本的位置。

ggplot(level_order, aes(fill=fct_inorder(Label), y=Amount, x="")) + 
  geom_bar(position="stack", stat="identity", width = 0.55) +
  scale_fill_brewer(palette = "Blues", direction = -1) +
  theme_void() +
  geom_text(aes(x=0.6, label = paste0("$", Amount)),
            position = position_stack(vjust = 0.5),
            hjust = 0.5,
            size = 5) +
  geom_text(aes(x=1.4, label = Label),
            position = position_stack(vjust = 0.5),
            hjust = 0.5,
            size = 5) +
  theme(legend.position = "none") +
  theme(plot.title = element_text(size = 50, hjust = .5, vjust = 0)) +
  ggtitle("Food Costs by Reindeer")

2
你也可以将hjust作为一种美学方式传递。为了做到这一点,你需要将标签准备为一个单独的数据框。然后,你只需要调用geom_text一次。我不是说这一定更好,只是指出这是可能的。代码中还有一些注释,涉及一些常见的陷阱。
library(tidyverse)
df3 <- data.frame(
  Label = c("Dasher", "Dancer", "Comet", "Cupid", "Prancer", "Blitzen", "Rudolph"),
  Amount = c(650.01, 601.01, 340.05, 330.20, 260.01, 250.80, 10.10)
) %>% 
  ## arrange step here
  arrange(desc(Amount)) 

## I like to prepare the data outside ggplot
label_df <- df3 %>% 
  mutate(Amount_lab = paste0("$", Amount)) %>%
  pivot_longer(-Amount) %>%
## this adds a column for your adjustment, and the x position compared with the central column
  mutate(hjust = rep(0:1, nrow(.)/2), 
         x = rep(c(1.21, .79), nrow(.)/2))

ggplot(mapping = aes(y = Amount)) + 
  ## geom_col is geom_bar(stat = "identity"), stack is default, so you can omit it
  ## call data in the geom layers
  ## set x to 1
  ## width = .4 so it matches your selected x from above
  geom_col(data = df3, aes(x = 1, fill=fct_inorder(Label)), width = .4) +
  scale_fill_brewer(palette = "Blues", direction = -1) +
  ## need to reverse both y and value, weirdly 
  geom_text(data = label_df, aes(x, y = rev(Amount), label = rev(value), 
## this is the main trick
  hjust = hjust),
  position = position_stack(vjust = 0.5) ) +
  ## sadly, need to turn clip off
  coord_cartesian(clip = "off") +
  theme_void() +
## call theme only once!!
  theme(legend.position = "none",
        plot.title = element_text(size = 20, hjust = .5, vjust = 0),
        ## you need to add a margin 
        plot.margin = margin(r = .6, l = .6, unit = "in")) +
  ggtitle("Food Costs by Reindeer")

reprex package (v2.0.1) 于2021年12月20日创建


1
尝试在调用geom_text时修复x坐标,并使用hjust管理对齐...
df3 <- data.frame(
  Label = c("Dasher", "Dancer", "Comet", "Cupid", "Prancer", "Blitzen", "Rudolph"),
  Amount = c(650.01, 601.01, 340.05, 330.20, 260.01, 250.80, 10.10)
)


library(ggplot2)
library(dplyr)
library(forcats)

level_order <- df3 %>% 
  arrange(desc(Amount))

ggplot(level_order, aes(fill=fct_inorder(Label), y=Amount, x="")) + 
  geom_bar(position="stack", stat="identity", width = 0.55) +
  scale_fill_brewer(palette = "Blues", direction = -1) +
  theme_void() +
  geom_text(aes(x = 1.3, label = paste0("$", Amount)),
            position = position_stack(vjust = 0.5),
            hjust = 0,
            size = 5) +
  geom_text(aes(x = 0.6, label = Label),
            position = position_stack(vjust = 0.5),
            hjust = 0,
            size = 5) +
  theme(legend.position = "none") +
  theme(plot.title = element_text(size = 50, hjust = .5, vjust = 0)) +
  ggtitle("Food Costs by Reindeer")

本示例由reprex包 (v2.0.1)于2021年12月19日创建。


以您的答案为起点,我使用了hjust函数进行对齐,并忘记了x参数来定位标签。完美!我会在答案中展示它的样子。 - David M Vermillion

0
使用Peter上面的答案(提醒我忘记存在的“x”位置参数),这是最终修复,得到了我想要的结果。hjust = 0是左对齐,hjust = 1是右对齐。
library(tidyverse)
library(grid)

df3 <- data.frame(
  Label = c("Dasher", "Dancer", "Comet", "Cupid", "Prancer", "Blitzen", "Rudolph"),
  Amount = c(650.01, 601.01, 340.05, 330.20, 260.01, 250.80, 10.10)
)

# Sort order
level_order <- df3 %>% 
  arrange(desc(Amount))

ggplot(level_order, aes(fill=fct_inorder(Label), y=Amount, x="")) + 
               geom_bar(position="stack", stat="identity", width = 0.55) +
               scale_fill_brewer(palette = "Blues", direction = -1) +
               theme_void() +
               geom_text(aes(x = 1.3, label = paste0("$", Amount)),
                         position = position_stack(vjust = 0.5),
                         hjust = 0,
                         size = 5) +
               geom_text(aes(x = 0.7, label = Label),
                         position = position_stack(vjust = 0.5),
                         hjust = 1,
                         size = 5) +
               theme(legend.position = "none",
                     plot.margin = unit(c(0,0,2,0), "cm"))
grid.text("Food Costs by Reindeer", x = unit(0.5, "npc"), y = unit(0, "npc"),
          vjust = -0.5, gp = gpar(cex=4))

Solution Result


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接