堆积条形图:如何定义填充

发布于 2025-01-12 01:58:02 字数 3067 浏览 2 评论 0原文

我再次需要您的帮助,我期待着您的倾听和帮助。学习。

我想描述几种鸟类(t1 - t7)之间的相互关系。观察它们与自己类型或其他类型鸟类互动的频率 (o1 - o7)

数据 (bird.data) 如下所示:

typeo1o2o3o4o5o6o7
t177.63.51.59.13.31.43.6
t21064.493.22.17.43.9
t38.612.163.22.40.68.84.3
t428.75.12.051.45.80.36.6
t54.112.29.51.00.464.58.3
t610.93.60.36.566.82.09.9
t715.98.24.55.69.45.451.0
bird.data <- structure(list(type = c("t1”, “t2", “t3”, “t4”, “t5”, “t6”, “t7”), o1 = c(77.6, 10, 8.6, 28.7, 4.1, 10.9, 15.9), o2 = c(3.5, 64.4, 12.1, 5.1, 12.2, 3.6, 8.2), o3 = c(1.5, 9, 63.2, 2, 9.5, 0.3, 4.5), o4 = c(9.1, 3.2, 2.4, 51.4, 1, 6.5, 5.6), o5 = c(3.3, 2.1, 0.6, 5.8, 0.4, 66.8, 9.4), o6 = c(1.4, 7.4, 8.8, 0.3, 64.5, 2, 5.4), o7 = c(3.6, 3.9, 4.3, 6.6, 8.3, 9.9, 51)), row.names = c(NA, -7L), class = c("tbl_df", "tbl", "data.frame"))

为了以图形方式显示这一点,我想绘制一个翻转的堆叠条形图 - 类似于此: 输入图片此处描述(摘自这篇文章:向堆积条形图ggplot2添加百分比标签)

我想在 x 轴(类型)上描绘不同类型的鸟类,而不是县,而不是计划类型,我想用不同类型鸟类之间的相互作用百分比填充条形(o1-o7)。

我现在的问题是:

  • 如何组织/分组列 o1、o2、o3、o4、o5、o6、o7 用作填充?
  • 我的y是什么?
ggplot() +
geom_bar(aes(y = ?, x = type, fill = ?),
         data = bird.data,
         stat="identity") +
         coord_flip()

预先非常感谢您的任何建议! :-)

编辑: 我已经实现了 stefan 的伟大建议,现在遇到了另一个问题:

当向堆积条形图添加标签时,vjust=0.5 不会将它们放置在相应条形图的中间:

```
ggplot() +
  geom_col(aes(x = value, y = type, fill = name), 
           data = bird_data_long,
           position = position_stack(reverse = TRUE)) +
  scale_y_discrete(limits=rev) +
  geom_label(data = subset(bird_data_long, value > 10), 
            aes(x = value, y = type, label = paste0(round(value, digits = 0),"%")), 
            size = 3, position = position_stack(vjust = 0.5))
```

该图如下所示: 堆叠栏with Labels

因此,我的问题是:如何调整标签的位置,使它们恰好放置在它们所代表的条的中间?知道它们为什么倾斜吗?非常感谢任何建议!

Once again, I need your help and I'm looking forward to listen & learn.

I would like to depict the interrelation between several types of birds (t1 - t7). It is observed how frequently they interact with their own type or other types of birds (o1 - o7)

The data (bird.data) looks as follows:

typeo1o2o3o4o5o6o7
t177.63.51.59.13.31.43.6
t21064.493.22.17.43.9
t38.612.163.22.40.68.84.3
t428.75.12.051.45.80.36.6
t54.112.29.51.00.464.58.3
t610.93.60.36.566.82.09.9
t715.98.24.55.69.45.451.0
bird.data <- structure(list(type = c("t1”, “t2", “t3”, “t4”, “t5”, “t6”, “t7”), o1 = c(77.6, 10, 8.6, 28.7, 4.1, 10.9, 15.9), o2 = c(3.5, 64.4, 12.1, 5.1, 12.2, 3.6, 8.2), o3 = c(1.5, 9, 63.2, 2, 9.5, 0.3, 4.5), o4 = c(9.1, 3.2, 2.4, 51.4, 1, 6.5, 5.6), o5 = c(3.3, 2.1, 0.6, 5.8, 0.4, 66.8, 9.4), o6 = c(1.4, 7.4, 8.8, 0.3, 64.5, 2, 5.4), o7 = c(3.6, 3.9, 4.3, 6.6, 8.3, 9.9, 51)), row.names = c(NA, -7L), class = c("tbl_df", "tbl", "data.frame"))

To show this graphically, I want to plot a flipped, stacked bar chart - similar to this one:
enter image description here
(Taken from this post: Add percentage labels to stacked bar chart ggplot2)

Instead of County, I want to depict the different types of birds on the x-axis (type), instead of Plan Types I want to fill the bar with the percentage of interactions between the different types of birds (o1-o7).

My questions now are:

  • How do I organize/group columns o1, o2, o3, o4, o5, o6, o7 to be used as fill?
  • What is my y?
ggplot() +
geom_bar(aes(y = ?, x = type, fill = ?),
         data = bird.data,
         stat="identity") +
         coord_flip()

Thanks a lot in advance for any advice! :-)

EDIT:
I have implemented the great suggestions by stefan, and now encountered another problem:

When adding labels to the stacked bar chart, vjust=0.5 does not place them in the middle of the respective bar:

```
ggplot() +
  geom_col(aes(x = value, y = type, fill = name), 
           data = bird_data_long,
           position = position_stack(reverse = TRUE)) +
  scale_y_discrete(limits=rev) +
  geom_label(data = subset(bird_data_long, value > 10), 
            aes(x = value, y = type, label = paste0(round(value, digits = 0),"%")), 
            size = 3, position = position_stack(vjust = 0.5))
```

The plot looks like this:
Stacked Bar with Labels

My question therefore is: how can I adjust the position of the labels so that they are placed exactly in the middle of the bar they are representing? Any idea why they are skewed? Any advice is much appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枫以 2025-01-19 01:58:02

您可以通过使用 tidyr::pivot_longer 将数据转换为长格式来实现您想要的结果。之后,在 filly 上映射的内容就非常简单了。

注意:我使用 geom_col(...),而不是 geom_bar(.. stat="identity")。另外,我切换了 xy 的角色,而不是 coord_flip

library(tidyr)
library(ggplot2)

bird_data_long <- bird.data %>% 
  pivot_longer(-type, names_to = "name", values_to = "value")

head(bird_data_long)
#> # A tibble: 6 × 3
#>   type  name  value
#>   <chr> <chr> <dbl>
#> 1 t1    o1     77.6
#> 2 t1    o2      3.5
#> 3 t1    o3      1.5
#> 4 t1    o4      9.1
#> 5 t1    o5      3.3
#> 6 t1    o6      1.4

ggplot() +
  geom_col(aes(x = value, y = type, fill = name), data = bird_data_long)

编辑 主要问题是您对 geom_text 中的数据进行了子集化。因此,与条形相比,您堆叠了一组不同的值,以便标签的位置不再对应于条形的位置。要去掉较小条形的标签,请使用 ifelse 代替。这样您的标签就会放置在正确的位置。

ggplot() +
  geom_col(aes(x = value, y = type, fill = name), 
           data = bird_data_long,
           position = position_stack(reverse = TRUE)) +
  scale_y_discrete(limits=rev) +
  geom_label(data = bird_data_long, 
             aes(x = value, y = type, group = name, label = ifelse(value > 10, paste0(round(value, digits = 0),"%"), NA)), 
             size = 3, position = position_stack(vjust = 0.5,reverse = TRUE), na.rm = TRUE)

You could achieve your desired result by converting your data to long format using e.g. tidyr::pivot_longer. Afterwards it's pretty straightforward what should be mapped on fill and y.

Note: Instead of geom_bar(.. stat="identity") I use geom_col(...). Also instead of coord_flip I switched the role of x and y.

library(tidyr)
library(ggplot2)

bird_data_long <- bird.data %>% 
  pivot_longer(-type, names_to = "name", values_to = "value")

head(bird_data_long)
#> # A tibble: 6 × 3
#>   type  name  value
#>   <chr> <chr> <dbl>
#> 1 t1    o1     77.6
#> 2 t1    o2      3.5
#> 3 t1    o3      1.5
#> 4 t1    o4      9.1
#> 5 t1    o5      3.3
#> 6 t1    o6      1.4

ggplot() +
  geom_col(aes(x = value, y = type, fill = name), data = bird_data_long)

EDIT The main issue is that you subsetted the data in geom_text. Hence you are stacking a different set of values compared to the bars so that the positions of the labels no longer correspond to the positions of the bars. To get rid of labels for smaller bars use an ifelse instead. This way your labels are placed at the correct positions.

ggplot() +
  geom_col(aes(x = value, y = type, fill = name), 
           data = bird_data_long,
           position = position_stack(reverse = TRUE)) +
  scale_y_discrete(limits=rev) +
  geom_label(data = bird_data_long, 
             aes(x = value, y = type, group = name, label = ifelse(value > 10, paste0(round(value, digits = 0),"%"), NA)), 
             size = 3, position = position_stack(vjust = 0.5,reverse = TRUE), na.rm = TRUE)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文