英文:
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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论