You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建降序排列的棒棒糖图?排查排序失效问题

问题分析与解决

你的代码排序不生效的核心问题是:在ggplot的主映射中使用了reorder(category, value)对x轴进行排序,但后续的geom_segment和geom_point又单独指定了x = category,覆盖了主映射里的排序规则,导致这些图层的元素依然按照原始的category顺序排列,和主图层的排序脱节。

另外,因为你用了coord_flip()反转坐标轴,想要实现降序排列的话,reorder里应该用-value来让高值的category排在上方(反转后对应左侧),也可以结合数据框排序提前设置因子顺序,两种方法都能解决问题。

修正方案一:统一使用主映射的排序(推荐)

去掉geom_segment和geom_point里单独的x = category,让它们继承主aes里已经排序好的x变量:

# Horizontal Lollipop Chart with Ball on Right Side and Data
library(ggplot2)
library(dplyr)

df <- data.frame(category = c("To save more money", 
                          "To exercise more", 
                          "To eat healthier", 
                          "To spend more time with family/friends",
                          "To lose weight", 
                          "To reduce spendings on living expenses (e.g., food, energy)",
                          "To spend less time on social media",
                          "To reduce stress on the job"),
             value = c(59, 50, 47, 40, 35, 26, 19, 19))

# 按value降序排列数据框
dm <- df %>% arrange(desc(value))

# 创建棒棒糖图,统一使用主映射的排序
ggplot(dm, aes(x = reorder(category, -value), y = value, label = value)) +
  geom_segment(
    aes(y = 0, yend = value),  # 去掉单独的x和xend,继承主映射的x
    color = "steelblue", 
    linewidth = 1.5
  ) +
  geom_point(color = "steelblue", size = 4) +  # 去掉单独的x,继承主映射
  geom_text(
    aes(label = paste0(value, "%")),
    hjust = -0.75, 
    vjust = 0.5, 
    color = "black",
    size = 3
  ) + 
  theme_minimal() +
  theme(panel.grid.major.y = element_blank()) + 
  coord_flip() +   
  labs(title = "Horizontal Lollipop Chart", x = "", y = "")

修正方案二:提前设置因子顺序

通过arrange后把category转为因子,指定levels为排序后的顺序,这样后续所有图层都会自动使用这个顺序:

library(ggplot2)
library(dplyr)

df <- data.frame(category = c("To save more money", 
                          "To exercise more", 
                          "To eat healthier", 
                          "To spend more time with family/friends",
                          "To lose weight", 
                          "To reduce spendings on living expenses (e.g., food, energy)",
                          "To spend less time on social media",
                          "To reduce stress on the job"),
             value = c(59, 50, 47, 40, 35, 26, 19, 19))

# 按value降序排列,并将category转为因子,指定levels
dm <- df %>% 
  arrange(desc(value)) %>%
  mutate(category = factor(category, levels = category))

# 创建棒棒糖图,无需再用reorder
ggplot(dm, aes(x = category, y = value, label = value)) +
  geom_segment(
    aes(x = category, y = 0, xend = category, yend = value), 
    color = "steelblue", 
    linewidth = 1.5
  ) +
  geom_point(aes(x = category, y = value), color = "steelblue", size = 4) +
  geom_text(
    aes(label = paste0(value, "%")),
    hjust = -0.75, 
    vjust = 0.5, 
    color = "black",
    size = 3
  ) + 
  theme_minimal() +
  theme(panel.grid.major.y = element_blank()) + 
  coord_flip() +   
  labs(title = "Horizontal Lollipop Chart", x = "", y = "")

两种方法都能实现你想要的降序排列棒棒糖图,第一种代码更简洁,减少重复指定x变量的冗余。

内容的提问来源于stack exchange,提问作者Data and AI Nerd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 10:17:22