0

我的目标是在 ggplot 的边缘创建一个比例标签,并且这个比例标签在图形中的位置应该是不变的(这样在类似的图形中循环不会显示比例标签移动)。

这项任务比我预期的要困难得多,因为 ggplot:

  1. 没有刻度标签的概念,
  2. 不容易在页边空白处添加注释,
  3. 坚持以数据相关(即非位置不变)的方式定位注释

编辑:为清楚起见,我特别关注标尺标签。有关示例,请参见生成的 ggplot。

这是我的解决方案,尽管是以一种骇人听闻的方式:

library(ggplot2)
library(grid)
library(gridExtra)
library(tidyverse)
library(dplyr)

dat = data.frame("Country" = c(rep("USA",50),
                               rep("Canada",50),
                               rep("Japan",50),
                               rep("Poland",50),
                               rep("Germany",50)),
                 "Outcome" = c(rnorm(n = 50, mean = 4.0, sd = 1.0),
                               rnorm(n = 50, mean = 5.0, sd = 0.5),
                               rnorm(n = 50, mean = 3.0, sd = 1.5),
                               rnorm(n = 50, mean = 4.5, sd = 1.0),
                               rnorm(n = 50, mean = 4.5, sd = 1.5))
)

myfunction = function(data, IV, DV, varlevels){
  
  # bumpsize is the hacky code that gets it to work
  # parameters need fine-tuning for perfect consistency but good enough here
  bumpsize = .45-(.06*length(varlevels))  
  
  # compute mean for plotting
  as_tibble(dat) %>%
    group_by({{IV}}) %>%
    summarise(Outcome = mean({{DV}},na.rm=T)) %>%
    
  # do the plotting  
  ggplot(mapping = aes({{IV}}, Outcome, fill = {{IV}})) +
    geom_col() +
    scale_x_discrete(limits = {{varlevels}}) +
    scale_y_continuous(breaks = c(1:7), limits = c(1,7), oob = scales::squish) +
    theme(legend.position = "none") +
    coord_cartesian(clip = "off") +
    annotation_custom(
      grob = textGrob(label = "Good", gp = gpar(col = "grey50"), rot = 90),
      ymin = 6, ymax = 7, xmin = bumpsize, xmax = bumpsize) +
    annotation_custom(
      grob = textGrob(label = "Bad", gp = gpar(col = "grey50"), rot = 90),
      ymin = 1, ymax = 2, xmin = bumpsize, xmax = bumpsize)
}



myfunction(data = dat, IV = Country, DV = Outcome, varlevels =  c("USA","Canada","Japan","Poland","Germany"))

ggsave("outcome_by_country.png", dpi = 300, units = "in", height= 5.89, width = 6.69)

我的问题: 有没有一种方法可以实现不变的位置比例标签,而无需求助于当前实现的 hacky 变量级方程?

4

1 回答 1

1

在 ggplot 中识别的两个“神奇”位置是-Inf并且Inf始终放置在面板中的最小和最大位置。我们可以使用它来注释绘图边缘的"Good""Bad"文本。我们可以使用该hjust参数来确定标签应该离(次要和主要)x 轴的水平线多远。该vjust参数确定文本放置在页边距的距离。这将需要取决于轴文本标签的宽度,但是当您将这些固定为1:7时,建议的值vjust似乎是合适的。/参数适用于文本大小hjustvjust因此这些不依赖于在条形图中绘制的数据。

library(ggplot2)
library(grid)
library(gridExtra)
library(tidyverse)
library(dplyr)

dat = data.frame("Country" = c(rep("USA",50),
                               rep("Canada",50),
                               rep("Japan",50),
                               rep("Poland",50),
                               rep("Germany",50)),
                 "Outcome" = c(rnorm(n = 50, mean = 4.0, sd = 1.0),
                               rnorm(n = 50, mean = 5.0, sd = 0.5),
                               rnorm(n = 50, mean = 3.0, sd = 1.5),
                               rnorm(n = 50, mean = 4.5, sd = 1.0),
                               rnorm(n = 50, mean = 4.5, sd = 1.5))
)

myfunction = function(data, IV, DV, varlevels){
  # compute mean for plotting
  as_tibble(dat) %>%
    group_by({{IV}}) %>%
    summarise(Outcome = mean({{DV}},na.rm=T)) %>%
    
    # do the plotting  
    ggplot(mapping = aes({{IV}}, Outcome, fill = {{IV}})) +
    geom_col() +
    scale_x_discrete(limits = {{varlevels}}) +
    scale_y_continuous(breaks = c(1:7), limits = c(1,7), oob = scales::squish) +
    theme(legend.position = "none") +
    coord_cartesian(clip = "off") +
    annotate(
      "text", x = -Inf, y = c(-Inf, Inf), label = c("Bad", "Good"), angle = 90, 
      hjust = c(-0.3, 1.3), # Some offset from c(0, 1), here: 0.3
      vjust = -1.7
    )
}



myfunction(data = dat, IV = Country, DV = Outcome, varlevels =  c("USA","Canada","Japan","Poland","Germany"))

reprex 包于 2021-07-27 创建(v1.0.0)

于 2021-07-27T21:55:17.880 回答