使用 ggplot2 在 R 中均匀调整面板和 y 轴文本大小

问题描述 投票:0回答:2

我有以下玩具数据框和

ggplot2
图表。我希望面板的大小和 y 轴上的文本大小相等,就像将视图分成两半一样。最后,结果将以pdf形式呈现,如果我可以自由地说,我想要这种调整大小和分割的原因是什么。

library(dplyr, warn = FALSE)
library(ggplot2)
library(ggstats)
library(purrr)

likert_levels <- c(
  "Strongly disagree",
  "Disagree",
  "Neither agree nor disagree",
  "Agree",
  "Strongly agree"
)

df <-
  tibble(
    "there is an argument sort_prop_include_center that could be set up to TRUE in order to include half of the centered level when sorting data" = sample(likert_levels, 150, replace = TRUE),
    "Similarly, the argument totals_include_center allows you to include half of the centered level into the left and the right totals" = sample(likert_levels, 150, replace = TRUE, prob = 5:1),
    "Here is one possible option which uses reorder and an ifelse to reorder the variable mapped on y using the counts (aka the sum) of Strictly disagree " = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
    "and disagree answers. Under the hood ggstats::gglikert reshape the data to long where the question id's are stored in a column named .question and the answers in a column named .answer:" = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
    "They used sampling data and create a data frame called df. I am using the same as given in the link. (the df not the df_dk). Ok, if i run in R the following code :" = sample(c(likert_levels, NA), 150, replace = TRUE),
    "proportion of answers higher than the centered level. I want the plot to be sorted according to very left proportions that are the combination (sum) of the two lower levels. (i.e. Respectively the percentages on the very right in the sum of the two lower categories. )" = sample(likert_levels, 150, replace = TRUE, prob = c(1, 0, 1, 1, 0))
  ) %>%
  mutate(across(everything(), ~ factor(.x, levels = likert_levels)))

# function to save retyping common arguments
anno <- partial(annotate, "text", x = -1, angle = 90, size = 5, fontface = "bold")

gglikert(df) +
  aes(y = reorder(.question,
                  ifelse(
                    .answer %in% c("Strongly disagree", "Disagree"),
                    1, 0
                  ),
                  FUN = sum, decreasing = TRUE
  )) +
  theme(axis.text.y = element_text(size = 8)) + 
  geom_hline(yintercept = c(1.5, 5.5), linetype = "dashed", colour = "grey20") +
  anno(y = 1, label = "warning\nzone", color = "#A6611A") +
  anno(y = 3.5, label = "so-so", color = "black") +
  anno(y = 6, label = "no warning\nzone", color = "#018571") +
  labs(y = NULL)

我如何使用 ggplot2 在 R 中成功?

编辑:是否可以删除背景主题中的线条。完全空白

r ggplot2 plot
2个回答
0
投票

一种选择是拆分元素并使用

patchwork
:

将它们重新添加到 50/50 宽度共享输出中
library(dplyr, warn = FALSE)
library(ggplot2)
library(ggstats)
library(purrr)
library(patchwork)

likert_levels <- c(
  "Strongly disagree",
  "Disagree",
  "Neither agree nor disagree",
  "Agree",
  "Strongly agree"
)

df <-
  tibble(
    "there is an argument sort_prop_include_center that could be set up to TRUE in order to include half of the centered level when sorting data" = sample(likert_levels, 150, replace = TRUE),
    "Similarly, the argument totals_include_center allows you to include half of the centered level into the left and the right totals" = sample(likert_levels, 150, replace = TRUE, prob = 5:1),
    "Here is one possible option which uses reorder and an ifelse to reorder the variable mapped on y using the counts (aka the sum) of Strictly disagree " = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
    "and disagree answers. Under the hood ggstats::gglikert reshape the data to long where the question id's are stored in a column named .question and the answers in a column named .answer:" = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
    "They used sampling data and create a data frame called df. I am using the same as given in the link. (the df not the df_dk). Ok, if i run in R the following code :" = sample(c(likert_levels, NA), 150, replace = TRUE),
    "proportion of answers higher than the centered level. I want the plot to be sorted according to very left proportions that are the combination (sum) of the two lower levels. (i.e. Respectively the percentages on the very right in the sum of the two lower categories. )" = sample(likert_levels, 150, replace = TRUE, prob = c(1, 0, 1, 1, 0))
  ) %>%
  mutate(across(everything(), ~ factor(.x, levels = likert_levels)))

# function to save retyping common arguments
anno <- partial(annotate, "text", x = -1, angle = 90, size = 5, fontface = "bold")

g1 <- gglikert(df) +
  aes(y = reorder(.question,
                  ifelse(
                    .answer %in% c("Strongly disagree", "Disagree"),
                    1, 0
                  ),
                  FUN = sum, decreasing = TRUE
  )) +
  theme(axis.text.y = element_text(size = 8)) + 
  geom_hline(yintercept = c(1.5, 5.5), linetype = "dashed", colour = "grey20") +
  anno(y = 1, label = "warning\nzone", color = "#A6611A") +
  anno(y = 3.5, label = "so-so", color = "black") +
  anno(y = 6, label = "no warning\nzone", color = "#018571") +
  labs(y = NULL)

tmp <- ggplot_gtable(ggplot_build(g1))

y_axis <- ggpubr::as_ggplot(tmp$grobs[[5]])

y_axis + (
  g1 + theme(
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank(),
    panel.grid = element_blank()
  )
) + plot_layout(widths = c(1, 1))


0
投票

这将需要根据您的输出尺寸/设备进行一些手动调整,但它可以让您对最终数字进行精细控制。

要点是通过使用

scales::label_wrap()
来操纵 y 轴标签占用的空间。

然后我们需要返回并调整绘图的某些部分以适应主要与图例相关的标签更改。

library(dplyr, warn = FALSE)
library(ggplot2)
library(ggstats)
library(purrr)
library(scales)

likert_levels <- c(
  "Strongly disagree",
  "Disagree",
  "Neither agree nor disagree",
  "Agree",
  "Strongly agree"
)

df <-
  tibble(
    "there is an argument sort_prop_include_center that could be set up to TRUE in order to include half of the centered level when sorting data" = sample(likert_levels, 150, replace = TRUE),
    "Similarly, the argument totals_include_center allows you to include half of the centered level into the left and the right totals" = sample(likert_levels, 150, replace = TRUE, prob = 5:1),
    "Here is one possible option which uses reorder and an ifelse to reorder the variable mapped on y using the counts (aka the sum) of Strictly disagree " = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
    "and disagree answers. Under the hood ggstats::gglikert reshape the data to long where the question id's are stored in a column named .question and the answers in a column named .answer:" = sample(likert_levels, 150, replace = TRUE, prob = 1:5),
    "They used sampling data and create a data frame called df. I am using the same as given in the link. (the df not the df_dk). Ok, if i run in R the following code :" = sample(c(likert_levels, NA), 150, replace = TRUE),
    "proportion of answers higher than the centered level. I want the plot to be sorted according to very left proportions that are the combination (sum) of the two lower levels. (i.e. Respectively the percentages on the very right in the sum of the two lower categories. )" = sample(
      likert_levels,
      150,
      replace = TRUE,
      prob = c(1, 0, 1, 1, 0)
    )
  ) %>%
  mutate(across(everything(), ~ factor(.x, levels = likert_levels)))

# function to save retyping common arguments
anno <-
  partial(
    annotate,
    "text",
    x = -1,
    angle = 90,
    size = 3,
    fontface = "bold"
  )

gg <- gglikert(df, labels_size = 2) +
  aes(y = reorder(
    .question,
    ifelse(.answer %in% c("Strongly disagree", "Disagree"),
           1, 0),
    FUN = sum,
    decreasing = TRUE
  )) +
  theme(axis.text.y = element_text(size = 8)) +
  geom_hline(
    yintercept = c(1.5, 5.5),
    linetype = "dashed",
    colour = "grey20"
  ) +
  anno(y = 1,
       label = "warning\nzone",
       color = "#A6611A") +
  anno(y = 3.5,
       label = "so-so",
       color = "black") +
  anno(y = 6,
       label = "no warning\nzone",
       color = "#018571") +
  labs(y = NULL)

gg +
  # replace scale for y so as to manipulate label wrapping
  scale_y_discrete(labels = label_wrap(68)) +
  theme(
    # set to inside to enable use of `legend.position.inside`
    legend.position = "inside",
    # move legend to the left and down a smidge
    legend.position.inside = c(0, -0.1), 
    # maintain horizontal direction
    legend.direction = "horizontal",
    # add some margin to prevent clipping
    plot.margin = margin(
      t = 1,
      r = 1,
      b = 25,
      l = 1
    )
  )
#> Scale for y is already present.
#> Adding another scale for y, which will replace the existing scale.

创建于 2024-04-24,使用 reprex v2.1.0

© www.soinside.com 2019 - 2024. All rights reserved.