英文:
control y-axis title positions when combining several plots with patchwork package
问题
我想能够控制每个图中关于y轴的标题位置相对于y轴本身的位置,这样当我将不同长度的抗生素名称输入到顶部图中时,底部图中的y轴标题与y轴的距离保持一致,我不必在更改顶部图中的抗生素名称时手动更改底部图中的位置。 有人能帮忙吗?
第一张图显示默认值,没有任何调整。
第二张图显示y轴标题应该距离y轴标签的期望距离。
第三张图演示了在顶部图中改变抗生素名称长度时,需要更改校正值。我想尝试编写代码,使其自动发生。
英文:
I would like to be able to control the y-axis title position for each plot with respect to the y-axis itself, so that when I input differing antibiotic name lengths into the top plot, the y-axis title in the bottom plot is the same distance from the y-axis and I do not have to manually change this in the bottom plot everytime I change the antiobiotic names in the top plot. Anyone able to help?
The first plot shows the default without any adjustment.
The second plot shows the desired distance the y-axis title should be from the y-axis labels.
The third plot demonstates how varying the antibiotic name length in top plot means the correction needs to be changed. I would like to try to code this to happen automatically.
library(tidyverse)
library(patchwork)
therapy_1 <- tibble(
antibiotic = c("IV Piperacillin-tazobactam", "IV Piperacillin-tazobactam"),
time_point = c("start", "end"),
date = c("2023-04-10","2023-04-25")) %>%
mutate(date = as_date(date))
therapy_2 <-tibble(
antibiotic = c("PO co-trimoxazole", "PO co-trimoxazole"),
time_point = c("start", "end"),
date = c("2023-04-10","2023-04-25")) %>%
mutate(date = as_date(date))
inflammatory_markers <- tibble(
date = c("2023-04-10", "2023-04-12"),
value = c("38.1", "37.8")) %>%
mutate(date = as_date(date))
p1 <- therapy_1 %>%
ggplot(aes(x = date)) +
geom_line(aes(y = antibiotic, colour = antibiotic)) +
theme(legend.position = "none")
p2 <- therapy_2 %>%
ggplot(aes(x = date)) +
geom_line(aes(y = antibiotic, colour = antibiotic)) +
theme(legend.position = "none")
default <- inflammatory_markers %>%
ggplot(aes(x = date)) +
geom_point(aes(y = value))
desired <- inflammatory_markers %>%
ggplot(aes(x = date)) +
geom_point(aes(y = value)) +
theme(axis.title.y = element_text(margin = margin(r = -160)))
# default output
p1 / default
<!-- -->
# desired output
p1 / desired
<!-- -->
# when length of y-axis labels shortened
p2 / desired
<!-- -->
<sup>Created on 2023-05-08 with reprex v2.0.2</sup>
答案1
得分: 0
这实际上并不是完全简单的(使用补丁)。我建议的解决方案也不是完美的。我认为最简单的解决方法是使用自定义注释作为您的y轴标题,而不是真正的y轴标题。这并不完美,因为图的大小仍然会变化,而注释位置将取决于您的x比例。
## 在您的下部面板添加自定义注释。
desired <-
inflammatory_markers %>%
ggplot(aes(x = date)) +
geom_point(aes(y = value)) +
## 使用geom_text而不是annotate,因为您正在使用日期,并且要使用“nudge_x”,而annotate无法使用
geom_text(
data = data.frame(), aes(
label = "value",
x = min(inflammatory_markers$date),
y = 1.5
),
angle = 90, nudge_x = -.4
) +
## 限制坐标并关闭裁剪
coord_cartesian(xlim = range(inflammatory_markers$date), clip = "off") +
## 删除y轴标签
labs(y = NULL)
p1 / desired
<!-- -->
p2 / desired
<!-- -->
<sup>创建于2023-05-08,使用reprex v2.0.2</sup>
英文:
That's actually not exactly trivial (with patchwork). The solution which I am suggesting would also not be perfect. I think the easiest hack would be to use a custom annotation as your y axis title instead of a real y axis title. It is not perfect, because the size of the plots still vary and the annotation position will be located depending on your x scale.
## adding a custom annotation to your inferior panel.
desired <-
inflammatory_markers %>%
ggplot(aes(x = date)) +
geom_point(aes(y = value)) +
## annotate with geom_text and not annotate, because you are using dates
## and you want to use "nudge_x" which doesn't work with annotate
geom_text(
data = data.frame(), aes(
label = "value",
x = min(inflammatory_markers$date),
y = 1.5
),
angle = 90, nudge_x = -.4
) +
## limit coordinates and turn clipping off
coord_cartesian(xlim = range(inflammatory_markers$date), clip = "off") +
## remove y label
labs(y = NULL)
# default output
p1 / desired
<!-- -->
p2 / desired
<!-- -->
<sup>Created on 2023-05-08 with reprex v2.0.2</sup>
答案2
得分: 0
不同到足以值得提供第二个答案(依我个人看法)。如果您愿意使用另一个包,您也可以使用 egg::ggarrange
,它应该完全满足您的需求。
library(egg)
ggarrange(p1, desired)
ggarrange(p2, desired)
创建于2023-05-08,使用 reprex v2.0.2
英文:
Different enough to merit a second answer (IMO). If you're happy to use another package, you can also use egg::ggarrange
which should do exactly what you need.
library(egg)
ggarrange(p1, desired)
<!-- -->
ggarrange(p2, desired)
<!-- -->
<sup>Created on 2023-05-08 with reprex v2.0.2</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论