分层环形图以在R中更好地区分子群。

huangapple go评论65阅读模式
英文:

layered-donut chart for a better subgroups-differentiation in R

问题

我正在尝试找到一种在R中绘制以下分层环形图的方法,以便我可以更好地区分子组。该图表是通过Excel实现的,通过生成四个不同的图层,每个子组具有不同数量的图层。

我尝试了以下方法,但效果不理想。

ggdonutchart方法

data <- as.data.frame(Titanic)
p <- data %>% group_by(Class) %>% summarise(num = sum(Freq))
ggdonutchart(p, x = "num", label = "Class", fill = "Class", 
             palette = c("darkblue","blue","lightblue","gray"), color = "white")

这种方法的问题在于,尝试在外部添加另一个相同的图层,即 PieDonut(PD, aes(Class, Class, count=n), title = "Titanic: Survival by Class"),会导致错误消息:! Each row of output must be identified by a unique combination of keys.

我想使用Titanic数据集生成类似第一张图的图表,不同的颜色显示不同的组。例如,深蓝色表示头等舱的份额,蓝色表示二等舱的份额,浅蓝色表示三等舱的份额,灰色表示船员的份额。换句话说,不同的颜色具有不同的宽度。

有没有办法实现这个目标?谢谢。

英文:

I'm trying to find a way to plot the following layered-donut chart in R, so that I can differentiate the subgroups better. The graph is realized by Excel, by generating four different layers, and each subgroup has different amount of layers.

分层环形图以在R中更好地区分子群。

I have tried the following approach, but it is not ideal.

ggdonutchart approach

p &lt;- data %&gt;% group_by(Class) %&gt;% summarise(num = sum(Freq))
ggdonutchart(p, x = &quot;num&quot;, label = &quot;Class&quot;, fill = &quot;Class&quot;, 
             palette = c(&quot;darkblue&quot;,&quot;blue&quot;,&quot;lightblue&quot;,&quot;gray&quot;), color = &quot;white&quot;)

分层环形图以在R中更好地区分子群。

The problem with this approach is that trying to add another identical layer outside, i.e. PieDonut(PD, aes(Class, Class, count=n), title = &quot;Titanic: Survival by Class&quot;), will give me the error message: ! Each row of output must be identified by a unique combination of keys.

I would like to use the Titanic dataset to generate a chart similar to the first one, with different colors showing different groups. For example, dark blue for the share of 1st class, blue for the share of 2nd class, light blue for the share of 3rd class, and gray for the share of crew class. In other words, different color has different width.

Any idea how to do this? Thank you.

答案1

得分: 2

以下是翻译好的代码部分:

library(tidyverse)

data.frame(x = rep(c('A', 'B', 'C', 'D'), times = c(4:1))) %>%
  ggplot(aes(x, y = 1, fill = x)) +
  geom_col(position = 'stack', color = 'white', linewidth = 0.1, width = 1) +
  coord_polar() +
  scale_y_continuous(limits = c(-10, 5)) +
  scale_fill_manual(values = c('#1b587c', '#4ea5d8', '#c4e1f2', '#bfbfbf')) +
  theme_void() +
  theme(plot.background = element_rect(fill = '#f2f2f2', color = NA))
library(tidyverse)

data <- as.data.frame(Titanic)

data %>% 
  group_by(Class, Survived) %>% 
  summarise(n = sum(Freq), .groups = "drop") %>%
  mutate(xmin = c(0, cumsum(head(n, -1))),
         xmax = cumsum(n), ymin = 4, ymax = 5) %>%
  group_by(Class) %>%
  reframe(Survived = Survived, n = n, xmin = xmin, xmax = xmax,
          ymin = ymin, ymax = ymax, perc = scales::percent(n / sum(n))) %>%
  bind_rows(data %>%
              group_by(Class) %>%
              summarise(Survived = "All", n = sum(Freq), .groups = "drop") %>%
              mutate(xmin = c(0, cumsum(head(n, -1))),
                     xmax = cumsum(n), ymin = 2, ymax = 4,
                     perc = scales::percent(n / sum(n)))) %>%
  ggplot() +
  geom_rect(aes(xmin = xmin, xmax = xmax, alpha = Survived,
                ymin = ymin, ymax = ymax, fill = Class),
            color = "white") +
  geom_text(aes(x = (xmin + xmax)/2, y = ifelse(Survived == "All", 3, 4.5), 
                label = paste(ifelse(Survived == "All", 
                                     as.character(Class), 
                                     Survived), perc, sep = "\n"))) +
  annotate("text", 0, 0, label = "Class", size = 8) +
  scale_y_continuous(limits = c(0, 5)) +
  scale_alpha_manual(values = c(1, 0.3, 0.6), guide = "none") +
  guides(fill = "none") +
  coord_polar() +
  theme_void()
英文:

It's certainly easy enough to recreate the plot in R. I'm not sure how we would go from your data to this plot, since you haven't included it in your question, but here's a fully reproducible example of how to get the plot:

library(tidyverse)

data.frame(x = rep(c(&#39;A&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;), times = c(4:1))) %&gt;%
  ggplot(aes(x, y = 1, fill = x)) +
  geom_col(position = &#39;stack&#39;, color = &#39;white&#39;, linewidth = 0.1, width = 1) +
  coord_polar() +
  scale_y_continuous(limits = c(-10, 5)) +
  scale_fill_manual(values = c(&#39;#1b587c&#39;, &#39;#4ea5d8&#39;, &#39;#c4e1f2&#39;, &#39;#bfbfbf&#39;)) +
  theme_void() +
  theme(plot.background = element_rect(fill = &#39;#f2f2f2&#39;, color = NA))

分层环形图以在R中更好地区分子群。


Edit

To replicate the donut pie chart in vanilla ggplot, you probably need to shape your data into rectangles and plot them:

library(tidyverse)

data &lt;- as.data.frame(Titanic)

data %&gt;% 
  group_by(Class, Survived) %&gt;% 
  summarise(n = sum(Freq), .groups = &quot;drop&quot;) %&gt;%
  mutate(xmin = c(0, cumsum(head(n, -1))),
         xmax = cumsum(n), ymin = 4, ymax = 5) %&gt;%
  group_by(Class) %&gt;%
  reframe(Survived = Survived, n = n, xmin = xmin, xmax = xmax,
          ymin = ymin, ymax = ymax, perc = scales::percent(n / sum(n))) %&gt;%
  bind_rows(data %&gt;%
              group_by(Class) %&gt;%
              summarise(Survived = &quot;All&quot;, n = sum(Freq), .groups = &quot;drop&quot;) %&gt;%
              mutate(xmin = c(0, cumsum(head(n, -1))),
                     xmax = cumsum(n), ymin = 2, ymax = 4,
                     perc = scales::percent(n / sum(n)))) %&gt;%
  ggplot() +
  geom_rect(aes(xmin = xmin, xmax = xmax, alpha = Survived,
                ymin = ymin, ymax = ymax, fill = Class),
            color = &quot;white&quot;) +
  geom_text(aes(x = (xmin + xmax)/2, y = ifelse(Survived == &quot;All&quot;, 3, 4.5), 
                label = paste(ifelse(Survived == &quot;All&quot;, 
                                     as.character(Class), 
                                     Survived), perc, sep = &quot;\n&quot;))) +
  annotate(&quot;text&quot;, 0, 0, label = &quot;Class&quot;, size = 8) +
  scale_y_continuous(limits = c(0, 5)) +
  scale_alpha_manual(values = c(1, 0.3, 0.6), guide = &quot;none&quot;) +
  guides(fill = &quot;none&quot;) +
  coord_polar() +
  theme_void()

分层环形图以在R中更好地区分子群。

答案2

得分: 0

以下是翻译好的代码部分:

data <- data.frame(data.frame(stringsAsFactors=FALSE,
                              Group = c("A", "B", "C", "D"),
                              Share = c(0.25, 0.3, 0.2, 0.25)
))
data2 <- transform(data, Share = ifelse(Group == "A", 0, Share))
data3 <- transform(data2, Share = ifelse(Group == "B", 0, Share))
data4 <- transform(data3, Share = ifelse(Group == "C", 0, Share))

plt <- ggplot() + geom_col(aes(x = 2, y = Share, fill = Group), 
                           data = data, color = "white") + 
  geom_col(aes(x = 2.9, y = Share, fill = Group), 
           data = data2, color = "white") +
  geom_col(aes(x = 3.8, y = Share, fill = Group), 
           data = data3, color = "white") +
  geom_col(aes(x = 4.7, y = Share, fill = Group), 
           data = data4, color = "white") +
  scale_fill_manual(values = c('#bfbfbf', '#c4e1f2', '#4ea5d8', '#1b587c')) +
  xlim(0, 5.5) + labs(x = NULL, y = NULL) + 
  theme(axis.ticks=element_blank(),
        axis.text=element_blank(),
        axis.title=element_blank())

plt
plt + coord_polar(theta = "y")

分层环形图以在R中更好地区分子群。

英文:
data &lt;- data.frame(data.frame(stringsAsFactors=FALSE,
Group = c(&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;),
Share = c(0.25, 0.3, 0.2, 0.25)
))
data2 &lt;- transform(data, Share = ifelse(Group == &quot;A&quot;, 0, Share))
data3 &lt;- transform(data2, Share = ifelse(Group == &quot;B&quot;, 0, Share))
data4 &lt;- transform(data3, Share = ifelse(Group == &quot;C&quot;, 0, Share))
plt &lt;- ggplot() + geom_col(aes(x = 2, y = Share, fill = Group), 
data = data, color = &quot;white&quot;) + 
geom_col(aes(x = 2.9, y = Share, fill = Group), 
data = data2, color = &quot;white&quot;) +
geom_col(aes(x = 3.8, y = Share, fill = Group), 
data = data3, color = &quot;white&quot;) +
geom_col(aes(x = 4.7, y = Share, fill = Group), 
data = data4, color = &quot;white&quot;) +
scale_fill_manual(values = c(&#39;#bfbfbf&#39;, &#39;#c4e1f2&#39;, &#39;#4ea5d8&#39;, &#39;#1b587c&#39;)) +
xlim(0, 5.5) + labs(x = NULL, y = NULL) + 
theme(axis.ticks=element_blank(),
axis.text=element_blank(),
axis.title=element_blank())
plt
plt + coord_polar(theta = &quot;y&quot;) 

分层环形图以在R中更好地区分子群。

huangapple
  • 本文由 发表于 2023年7月31日 23:00:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76804868.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定