代码之家  ›  专栏  ›  技术社区  ›  Homer Jay Simpson

使用ggplot2在R中相等地调整面板和y轴文本的大小

  •  0
  • Homer Jay Simpson  · 技术社区  · 1 年前

    我有以下玩具数据帧和 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)
    

    enter image description here 如何使用ggplot2在R中成功?

    编辑 如果可以删除背景主题中的线条。完全空白

    0 回复  |  直到 1 年前
        1
  •  2
  •   Andy Baxter    1 年前

    一种选择是分割元素,并将它们重新添加到50/50宽度共享输出中,使用 patchwork :

    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))
    

        2
  •  1
  •   the-mad-statter    1 年前

    这将需要根据您的输出大小/设备进行一些手动调整,但它可以让您对最终图形进行精细控制,图形占据整个绘图空间。

    要点是通过使用 y_label_wrap 中的论点 gglikert()

    y_label_wrap y轴标签的每行字符数,请参见比例::label_wrap()

    然后我们应该调整图例,因为在我们编辑之前它已经被剪切了。

    根据您的问题编辑,我们可以使用 panel(panel.grid = element_blank()) 以删除所有网格线。

    根据您的评论问题,听起来您可能对 totals_hjust 我现在设定为0.5的论点。

    totals_hjust x轴上总计标签的水平调整

    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 = 3,
        fontface = "bold"
      )
    
    gg <- gglikert(
      df, 
      labels_size = 2, 
      y_label_wrap = 68,
      totals_hjust = 0.5
    ) +
      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 +
      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",
        # remove gridlines
        panel.grid = element_blank(),
        # add some margin to prevent clipping
        plot.margin = margin(
          t = 1,
          r = 1,
          b = 25,
          l = 1
        )
      )
    

    创建于2024-04-24 reprex v2.1.0