在 ggplot 中为多个类别制作配对点

Posted

技术标签:

【中文标题】在 ggplot 中为多个类别制作配对点【英文标题】:making paired points in ggplot for multiple categories 【发布时间】:2022-01-16 05:15:06 【问题描述】:

我知道这个问题之前已经回答过了,但它并没有按照我的意愿去做。我在 R 中有一个数据框。我想在不同类别之间建立配对点。数据框是:


sample <- data.frame(city_name = c(rep('Wahsington',10),rep('Seattle',10)),
                     experience = rep(c("ten","five"),5),
                     test = rep(c('manager','manager','team lead','team lead',
                                  'CFO','CFO','CEO','CEO','Executive',
                                  'Executive'),2),
                     score = c(87.10,27.20,98.15,67.20,68.30,23.00,78.75,49.30,63.30,37.90,
                                    69.10,20.20,90.65,56.05,69.40,47.35,52.55,37.85,
                                    70.90,47.75))

为了绘制成对的点,我这样做:


options(repr.plot.width=30, repr.plot.height=8)
ggplot(sample, aes(x = test, y = score, group = test)) + 
geom_line() + 
geom_point(size = 2, aes(color = experience)) + 
facet_wrap(~ city_name) +
scale_x_discrete("") +
theme_minimal() +
  ylab('Score') + xlab('') + theme(axis.text.x=element_text(angle = 90, hjust = 0))

我得到的情节如下:

但是,我将这些配对点不要落在彼此之下,而是为了美学目的而稍微倾斜,就像这里一样,但对于不同的类别,如在 x 轴上注释的“CFO”和“CEO”,就像在第一张图中一样:

如何在 R 中使用 ggplot 来实现这一点?

编辑:这是我想要实现的一个示例:

【问题讨论】:

您能否包含您想要实现的输出的手动草图,特别是 x 轴上的注释如何工作?名称与图中的线有何关系?以“但是……”开头的句子有点混乱,也许可以通过编辑来解决? @Peter 很抱歉之前不清楚。我已经添加了我脑海中的手动草图。 好的,谢谢,这可以制作一个非常宽的图表,这是您想要的吗?我想如果偏移量很小,那么它可以工作。 我可以用测试类别注释我的第二个图表吗?即在测试列中用其对应的值注释每个配对点。 【参考方案1】:

另一种选择是使用嵌套刻面(使用 ggh4x)。 (它并没有真正给出您想要的外观,而只是指出该选项)。另请参阅下文,了解使用散点图可视化配对数据的不同方法的建议。

library(tidyverse)
library(ggh4x)
## bad idea to call an object like a very commonly used function (sample)
## df is also a function, but much less commonly used
df <- data.frame(city_name = c(rep('Wahsington',10),rep('Seattle',10)),
                     experience = rep(c("ten","five"),5),
                     test = rep(c('manager','manager','team lead','team lead',
                                  'CFO','CFO','CEO','CEO','Executive',
                                  'Executive'),2),
                     score = c(87.10,27.20,98.15,67.20,68.30,23.00,78.75,49.30,63.30,37.90,
                               69.10,20.20,90.65,56.05,69.40,47.35,52.55,37.85,
                               70.90,47.75))
ggplot(df, aes(x = experience, y = score, group = test)) + 
  geom_line() + 
  geom_point(size = 2, aes(color = experience)) + 
  facet_nested(~ city_name + test) +
  ## one call to labs reduces the code to relabel the axis
  labs(x = NULL, y = "Score") + 
  theme_minimal() +
  theme(axis.text.x=element_blank())

使用散点图可以更引人注目地可视化配对数据

df_wide <- 
  df %>% 
  pivot_wider(names_from = experience, values_from = score)

lims <- c(0, 100)

ggplot(df_wide, aes(five, ten, color = test)) +
  geom_point() +
  geom_abline(slope = 1, intercept = 0) +
  ggrepel::geom_text_repel(aes(label = test)) +
  scale_color_brewer(NULL, palette = "Set1") +
  facet_grid(~city_name) +
  coord_equal(xlim = lims, ylim = lims) +
  cowplot::theme_minimal_grid() +
  theme(legend.position = "none")

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

【讨论】:

第二张图看起来很不错。我会用那个。谢谢:) @John 查看 Claus Wilke 的精彩书籍clauswilke.com/dataviz【参考方案2】:

做到这一点的一种方法是使 x 轴对于经验值和测试值是连续的;在经验为“十”的情况下使用 x 偏移量。

library(ggplot2)
library(dplyr)

offset = 0.4

# modify the data to allow for x values to control the location of points and line ends.

df <- 
  df %>% 
  group_by(city_name, experience) %>% 
  arrange(city_name, experience, test) %>% 
  mutate(x = as.numeric(row_number()),
         x_lab_pos = x + 0.5 * offset, 
         x = if_else(experience == "ten", x + offset, x))

x_breaks <- sort(unique(df$x_lab_pos))
x_label <- sort(unique(df$test))

ggplot(df, aes(x = x, y = score, group = test)) + 
  geom_line() + 
  geom_point(size = 2, aes(color = experience)) +
  facet_wrap(~ city_name) +
  scale_x_continuous(breaks = x_breaks,
                     labels = x_label) +
  theme_minimal() +
  labs(x = NULL,
       y = 'Score') +
  theme(axis.text.x=element_text(angle = 90, hjust = 0))

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

数据

df <- data.frame(city_name = c(rep('Washington',10),rep('Seattle',10)),
                     experience = rep(c("ten","five"),5),
                     test = rep(c('manager','manager','team lead','team lead',
                                  'CFO','CFO','CEO','CEO','Executive',
                                  'Executive'),2),
                     score = c(87.10,27.20,98.15,67.20,68.30,23.00,78.75,49.30,63.30,37.90,
                               69.10,20.20,90.65,56.05,69.40,47.35,52.55,37.85,
                               70.90,47.75))

【讨论】:

感谢您提供如此详细的解决方案:)

以上是关于在 ggplot 中为多个类别制作配对点的主要内容,如果未能解决你的问题,请参考以下文章

在 seaborn 点图中连接每个类别中的配对点

在R中为一个工作表制作多个类别的单独直方图

在 Python 中加快字符串与对象的配对

BZOJ4205卡牌配对 最大流

ios 核心蓝牙与外部 BLE 设备配对

最优点配对问题(紫书)