英文:
Barplot with double x-axis labels
问题
我需要创建一个条形图,显示三种不同服务的每周销售数量。我需要将日历周和月份作为x轴标签之一。
以下是我的代码:
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"),
qty = c(38,185,87,29,12,133,2,14,31,2,9,59,60,43,137,135,31,159,15,32,1),
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"),
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")
)
## 使用 annotate
sample %>%
ggplot() +
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)) +
coord_cartesian(clip = "off") +
annotate(geom = "text",
x = 1:(nrow(sample)/3),
y = min(sample$qty),
label = unique(sample$xlabel2),
vjust = 1,
angle = 90)
## 使用 facet_wrap
sample %>%
ggplot() +
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_wrap(~xlabel2, strip.position = "bottom") +
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:
Here is my code:
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"),
qty = c(38,185,87,29,12,133,2,14,31,2,9,59,60,43,137,135,31,159,15,32,1),
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"),
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")
)
## To use annotate
sample %>%
#arrange(desc(dat_cal_week_id)) %>%
ggplot() +
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)) +
theme(legend.position = "left", axis.text.x = element_blank()) +
coord_cartesian(clip = "off") +
annotate(geom = "text",
x = 1:(nrow(sample)/3),
y = min(sample$qty),
label = unique(sample$xlabel2),
vjust = 1,
angle = 90)
## Using facet_wrap
sample %>%
#arrange(desc(dat_cal_week_id)) %>%
ggplot() +
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_wrap(~xlabel2, strip.position = "bottom") +
theme(strip.placement = "outside")
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"
,这样我们可以获得每个分面等宽的条形图:
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")
<details>
<summary>英文:</summary>
One option would be to use facetting but with a free scale, i.e. `scales="free_x"`. Additionally at least for your example data I would switch to `facet_grid` as it allows to use `space="free_x"` 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")
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/YbwsK.png
</details>
# 答案2
**得分**: 0
如果您将 `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]
<details>
<summary>英文:</summary>
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]: https://i.stack.imgur.com/RIzxa.png
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论