如何在ggplot2中使用facet_grid制作甜甜圈图表?

7

我正在尝试制作甜甜圈图表。

唯一的问题是它们看起来像这样...

enter image description here

以下是我的代码:

ggplot(
  diamonds,
  aes(
    x = cut,
    fill = color
  )
) +
  geom_bar(
    position = 'fill',
    stat = 'bin'
  ) +
  scale_y_continuous(
    labels = percent_format()
  ) +
  facet_grid(clarity ~ cut) + 
  coord_polar(theta = 'y') 

我怎样才能将图表从奇怪的派变成相同宽度的圆形?


3
你肯定可以制作一个可复现的例子——一个最小化的可复现的例子,不超过85行代码,并且不需要去某个网站下载SPSS文件。请使用有相似结构的内置数据,或快速模拟数据,或者使用dput()共享您绘图中的转换后的数据。想要了解更多制作好的范例的贴士,请参考这里 - Gregor Thomas
1
你可能想要了解一下 cut 函数,它比嵌套的 ifelse 语句更适合对数值数据进行分组。此外,x %in% c("a", "b", "c") 通常比 x == "a" | x == "b" | x == "c" 更好用。 - Gregor Thomas
@Gregor 谢谢,我忘记了股票数据集。我更新了我的PNG和代码。 - Username
@aomith 将 x = cut 替换为 x = factor(1) 可以将圆环变成均匀大小的馅饼,但我想制作均匀大小的圆环。 - Username
1个回答

9
这是一种漂亮而整洁的方法:
library(ggplot2)
library(data.table)

# get data, calculate quantities of interest
diam <- diamonds; setDT(diam) 
tabulated <- diam[, .N, by = .(cut, color, clarity)]

# plot
ggplot(tabulated, aes(x=2, y=N, fill=color)) +
  geom_bar(position = 'fill', stat = 'identity')  +
  facet_grid(clarity ~ cut) + 
  xlim(0.5, 2.5) +
  coord_polar(theta = 'y') + 
  labs(x=NULL, y=NULL)

这里输入图片描述

好的,这是如何工作的?让我们看看你的代码-你得到一些看起来像甜甜圈但内部大小不同的图。为什么会这样呢?将数据“拆分”并将输出仅作为条形图查看会很有帮助。 (为简单起见,我将对您的facet进行子集处理,仅选择两行。)

ggplot(subset(diamonds, as.numeric(clarity) <=2), 
       aes(x = cut, fill = color)) +
  geom_bar(position = 'fill', stat = 'bin')  +
  facet_grid(clarity ~ cut)

在这里输入图片描述

您将一个对X进行了映射的值,但它并没有什么有用的作用——它只是偏移了条形图,但由于您正在以该变量进行分面处理,因此每个图中只有一个堆叠的条形图。

然而,当您添加coord_polar时,具有偏移X值的图形显示为甜甜圈,而x=1的图形显示为饼图。这是因为使用coord_polar时,堆叠的一系列条形图嵌套在彼此内部,而X=1表示最内部的“线圈”。

因此,解决方案始于不将实际值映射到X。您可以使所有绘图的X=1,但那样会得到所有的饼图,而不是甜甜圈。您想要的是一个堆叠的条形图,在x轴上留出一些空间(那就是甜甜圈的中心)。您可以通过复制数据来实现这一点,这样您就有了两组堆叠的条形图,然后清除第一组。这就是我之前发布的答案,它有效(有关详细信息,请参见编辑历史记录)。

然而,Hadley通过Twitter提出了一个更简单的解决方案,我觉得有义务为后人发布:调整x限制以在x轴上强制一些前导空格。

首先,计算您想要的值(我使用data.table进行此操作):

library(data.table)
diam <- diamonds; setDT(diam)
tabulated <- diam[, .N, by = .(cut, color, clarity)]

现在,将柱状图堆叠起来并留出一些空间

enter image description here

这是您想要的堆叠条形图,您需要做的就是添加coord_polar(如本帖顶部所示)。 您可以调整x轴限制以调整甜甜圈/孔比例以适合您的喜好。


这正是我想要的!作为一个R初学者,我有几个问题。1) diam[, .N, by = .(cut, color, clarity)]中在进行什么操作?逗号、by=和括号前面的.代表什么?2) 在plot_data[donutslice==1, N:=0]中,N:=0中的冒号代表什么意思? - Username
那是 data.table 的术语。 - Axeman
1
对的,这是 data.table 的术语。第一件事就是按照三个变量分组计数案例。你可以在 base R 中使用 aggregate(carat ~ cut + color + clarity, data=diamonds, FUN=length) 得到类似的结果(但现在计数列名为'carat'而不是N)。不过,学习使用 data.table 很棒。 - arvi1000
1
最后一件事只需要使用 data.table 进行赋值。基本 R 代码为:plot_data$N[plot_data$donutslice==1] <- 0,但是使用 data.table 版本更加简洁! - arvi1000

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