Barplot with double x-axis labels

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

Barplot with double x-axis labels

问题

我需要创建一个条形图,显示三种不同服务的每周销售数量。我需要将日历周和月份作为x轴标签之一。

以下是我的代码:

  1. sample <- data.frame(service_type = c("A","B","C","A","B","C","A","B","C","A","B","C","A","B","C","A","B","C","A","B","C"),
  2. qty = c(38,185,87,29,12,133,2,14,31,2,9,59,60,43,137,135,31,159,15,32,1),
  3. year_week = c("2022 - CW02","2022 - CW02","2022 - CW02","2022 - CW03","2022 - CW03","2022 - CW03","2022 - CW04","2022 - CW04","2022 - CW04","2022 - CW05","2022 - CW05","2022 - CW05","2022 - CW06","2022 - CW06","2022 - CW06","2022 - CW07","2022 - CW07","2022 - CW07","2022 - CW08","2022 - CW08","2022 - CW08"),
  4. xlabel2 = c("Jan-22","Jan-22","Jan-22","Jan-22","Jan-22","Jan-22","Jan-22","Jan-22","Jan-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22","Feb-22")
  5. )
  6. ## 使用 annotate
  7. sample %>%
  8. ggplot() +
  9. aes(x = year_week, fill = service_type, weight = qty) +
  10. geom_bar(position = "dodge") +
  11. scale_fill_hue(direction = 1) +
  12. theme_minimal() +
  13. theme(legend.position = "left", axis.text.x = element_text(angle=90, hjust=1)) +
  14. coord_cartesian(clip = "off") +
  15. annotate(geom = "text",
  16. x = 1:(nrow(sample)/3),
  17. y = min(sample$qty),
  18. label = unique(sample$xlabel2),
  19. vjust = 1,
  20. angle = 90)
  21. ## 使用 facet_wrap
  22. sample %>%
  23. ggplot() +
  24. aes(x = year_week, fill = service_type, weight = qty) +
  25. geom_bar(position = "dodge") +
  26. scale_fill_hue(direction = 1) +
  27. theme_minimal() +
  28. theme(legend.position = "left", axis.text.x = element_text(angle=90, hjust=1)) +
  29. facet_wrap(~xlabel2, strip.position = "bottom") +
  30. theme(strip.placement = "outside")

第一次尝试使用 annotate,但我收到错误信息'Error in annotate(): ! Unequal parameter lengths: x (7), label (2)'

第二次尝试使用 facet_wrap,图表重复了第一个轴标签两次,不符合我的要求。

我不确定这些方法中是否有一个是正确的。非常感谢任何能帮助我的人。

谢谢!

英文:

I need to build a barplot showing the sold qty of three different services on a weekly basis. I need to add as x-axis label either the calendar week and the month.
See the image for an example:

Barplot with double x-axis labels

Here is my code:

  1. sample &lt;- data.frame(service_type = c(&quot;A&quot;,&quot;B&quot;,&quot;C&quot;,&quot;A&quot;,&quot;B&quot;,&quot;C&quot;,&quot;A&quot;,&quot;B&quot;,&quot;C&quot;,&quot;A&quot;,&quot;B&quot;,&quot;C&quot;,&quot;A&quot;,&quot;B&quot;,&quot;C&quot;,&quot;A&quot;,&quot;B&quot;,&quot;C&quot;,&quot;A&quot;,&quot;B&quot;,&quot;C&quot;),
  2. qty = c(38,185,87,29,12,133,2,14,31,2,9,59,60,43,137,135,31,159,15,32,1),
  3. year_week = c(&quot;2022 - CW02&quot;,&quot;2022 - CW02&quot;,&quot;2022 - CW02&quot;,&quot;2022 - CW03&quot;,&quot;2022 - CW03&quot;,&quot;2022 - CW03&quot;,&quot;2022 - CW04&quot;,&quot;2022 - CW04&quot;,&quot;2022 - CW04&quot;,&quot;2022 - CW05&quot;,&quot;2022 - CW05&quot;,&quot;2022 - CW05&quot;,&quot;2022 - CW06&quot;,&quot;2022 - CW06&quot;,&quot;2022 - CW06&quot;,&quot;2022 - CW07&quot;,&quot;2022 - CW07&quot;,&quot;2022 - CW07&quot;,&quot;2022 - CW08&quot;,&quot;2022 - CW08&quot;,&quot;2022 - CW08&quot;),
  4. xlabel2 = c(&quot;Jan-22&quot;,&quot;Jan-22&quot;,&quot;Jan-22&quot;,&quot;Jan-22&quot;,&quot;Jan-22&quot;,&quot;Jan-22&quot;,&quot;Jan-22&quot;,&quot;Jan-22&quot;,&quot;Jan-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;,&quot;Feb-22&quot;)
  5. )
  6. ## To use annotate
  7. sample %&gt;%
  8. #arrange(desc(dat_cal_week_id)) %&gt;%
  9. ggplot() +
  10. aes(x = year_week, fill = service_type, weight = qty) +
  11. geom_bar(position = &quot;dodge&quot;) +
  12. scale_fill_hue(direction = 1) +
  13. theme_minimal() +
  14. #theme(legend.position = &quot;left&quot;, axis.text.x = element_text(angle=90, hjust=1)) +
  15. theme(legend.position = &quot;left&quot;, axis.text.x = element_blank()) +
  16. coord_cartesian(clip = &quot;off&quot;) +
  17. annotate(geom = &quot;text&quot;,
  18. x = 1:(nrow(sample)/3),
  19. y = min(sample$qty),
  20. label = unique(sample$xlabel2),
  21. vjust = 1,
  22. angle = 90)
  23. ## Using facet_wrap
  24. sample %&gt;%
  25. #arrange(desc(dat_cal_week_id)) %&gt;%
  26. ggplot() +
  27. aes(x = year_week, fill = service_type, weight = qty) +
  28. geom_bar(position = &quot;dodge&quot;) +
  29. scale_fill_hue(direction = 1) +
  30. theme_minimal() +
  31. theme(legend.position = &quot;left&quot;, axis.text.x = element_text(angle=90, hjust=1)) +
  32. facet_wrap(~xlabel2, strip.position = &quot;bottom&quot;) +
  33. theme(strip.placement = &quot;outside&quot;)

The first try is with annotate but I receive the error 'Error in annotate():
! Unequal parameter lengths: x (7), label (2)'

The second try is with facet_wrap and the plot is repeating the first axis labels twice and it's not what I'm looking for
See image

I'm not sure that any of these approaches are correct.
I really appreciate anyone who can help me with this.
Thanks
​ ​ ​ ​

答案1

得分: 1

一个选择是使用分面,但具有自由比例,即scales="free_x"。另外,至少对于你的示例数据,我会切换到facet_grid,因为它允许使用space="free_x",这样我们可以获得每个分面等宽的条形图:

  1. library(ggplot2)
  2. sample$xlabel2 <- factor(sample$xlabel2, c("Jan-22", "Feb-22"))
  3. ggplot(sample) +
  4. aes(x = year_week, fill = service_type, weight = qty) +
  5. geom_bar(position = "dodge") +
  6. scale_fill_hue(direction = 1) +
  7. theme_minimal() +
  8. theme(legend.position = "left", axis.text.x = element_text(angle = 90, hjust = 1)) +
  9. facet_grid(~xlabel2, switch = "x", scales = "free_x", space = "free_x") +
  10. theme(strip.placement = "outside")

Barplot with double x-axis labels

  1. <details>
  2. <summary>英文:</summary>
  3. One option would be to use facetting but with a free scale, i.e. `scales=&quot;free_x&quot;`. Additionally at least for your example data I would switch to `facet_grid` as it allows to use `space=&quot;free_x&quot;` so that we get bars of equal width per facet:

library(ggplot2)

sample$xlabel2 <- factor(sample$xlabel2, c("Jan-22", "Feb-22"))

ggplot(sample) +
aes(x = year_week, fill = service_type, weight = qty) +
geom_bar(position = "dodge") +
scale_fill_hue(direction = 1) +
theme_minimal() +
theme(legend.position = "left", axis.text.x = element_text(angle = 90, hjust = 1)) +
facet_grid(~xlabel2, switch = "x", scales = "free_x", space = "free_x") +
theme(strip.placement = "outside")

  1. [![enter image description here][1]][1]
  2. [1]: https://i.stack.imgur.com/YbwsK.png
  3. </details>
  4. # 答案2
  5. **得分**: 0
  6. 如果您将 `year_week` 转换为 `Date` 对象,可以在 `scale_x_date()` 中使用 `sec.axis`

library(dplyr)
library(ggplot2)

sample <- sample %>%
mutate(date = as.Date(paste0(year_week, 1), "%Y - CW%U%u"))

sample %>%
ggplot() +
aes(x = date, fill = service_type, weight = qty) +
geom_bar(position = "dodge") +
scale_fill_hue(direction = 1) +
scale_x_date(
date_labels = "%Y - CW%U",
date_breaks = "1 week",
sec.axis = dup_axis(
breaks = as.Date(paste0("15-", unique(sample$xlabel2)), "%d-%b-%y"),
labels = (x) format(x, "%b-%y")
)
) +
theme_minimal() +
theme(legend.position = "left", axis.text.x.bottom = element_text(angle=90, hjust=1))

  1. [![][1]][1]
  2. <details>
  3. <summary>英文:</summary>
  4. If you convert `year_week` to a `Date` object, you can use `sec.axis` in `scale_x_date()`:

library(dplyr)
library(ggplot2)

sample <- sample %>%
mutate(date = as.Date(paste0(year_week, 1), "%Y - CW%U%u"))

sample %>%
ggplot() +
aes(x = date, fill = service_type, weight = qty) +
geom_bar(position = "dodge") +
scale_fill_hue(direction = 1) +
scale_x_date(
date_labels = "%Y - CW%U",
date_breaks = "1 week",
sec.axis = dup_axis(
breaks = as.Date(paste0("15-", unique(sample$xlabel2)), "%d-%b-%y"),
labels = (x) format(x, "%b-%y")
)
) +
theme_minimal() +
theme(legend.position = "left", axis.text.x.bottom = element_text(angle=90, hjust=1))

  1. [![][1]][1]
  2. [1]: https://i.stack.imgur.com/RIzxa.png
  3. </details>

huangapple
  • 本文由 发表于 2023年3月31日 16:47:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75896553.html
匿名

发表评论

匿名网友

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

确定