结合两个scale_而不覆盖params

时间:2018-01-24 21:47:22

标签: r ggplot2

关于如何在 ggplot2 中合并两个scale_类型调用,有很多问题。但是,大多数都涉及到这样的事情:

ggplot(iris, aes(Sepal.Length, Sepal.Width)) + 
    geom_point() + 
    scale_x_log10() + 
    scale_x_continuous("some new label")

#> Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.

此处的解决方案非常简单,只需使用trans中的scale_x_continuous参数即可。

我的情况是我有很多 ggplot2 辅助函数可以快速完成绘图。这些函数在函数内部调用scale_x,因此不能轻易地编辑它。例如:

#helper function
table2 = function(x, prop = F, include_NA = T, sort_descending = T) {

  #NA param
  if (include_NA) {
    NA_param = "always"
  } else {
    NA_param = "no"
  }

  #get regular table
  tbl = table(x, useNA = NA_param)

  #as data frame
  d = tibble::data_frame("Group" = names(tbl),
                         "Count" = as.numeric(tbl)
  )

  #percent/prob
  if (!prop) d$Percent = d$Count / sum(d$Count) * 100 else d$Proportion = d$Count / sum(d$Count)

  #sort?
  if (!is.null(sort_descending)) {
    if (sort_descending) {
      d %<>% dplyr::arrange(-Count)
    } else {
      d %<>% dplyr::arrange(Count)
    }
  }

  d
}

GG_boxplot = function(df, y, x) {
  #determine sample sizes
  sample_n = df[c(x, y)] %>%
    na.omit() %>%
    {table2(.[[x]], include_NA = F, sort_descending = NULL)}

  #plot
  ggplot(df, aes_string(x = x, y = y)) +
    geom_boxplot() +
    scale_x_discrete(labels = function(x) {str_c(x, "\nn = ", sample_n$Count)})
}

用例:

GG_boxplot(iris, "Sepal.Length", "Species")

MailSo

因此,这是一种很容易的方法,可以轻松地将类级别的样本大小添加到标签中。但是,如果我们想用轴更改其他内容,那么这些标签会被覆盖,除非我们可以使用例如特殊情况。 xlab

GG_boxplot(iris, "Sepal.Length", "Species") + xlab("no problem")

enter image description here

但是,如果想要做一些更加花哨的事情,就会出现问题:

#> GG_boxplot(iris, "Sepal.Length", "Species") + scale_x_discrete(position = "top")
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.

enter image description here

有没有一种解决这类覆盖问题的好方法?

我试过两种方法试图告诉 ggplot2 不要覆盖以前的设置但没有运气:

> GG_boxplot(iris, "Sepal.Length", "Species") + scale_x_discrete(position = "top", labels = NULL)
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.
> GG_boxplot(iris, "Sepal.Length", "Species") + scale_x_discrete(position = "top", labels = waiver())
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.

1 个答案:

答案 0 :(得分:1)

Hacky回答

如果保存从函数返回的绘图,则可以访问存在的刻度标签,并重新设置所需的刻度部分。

p <- GG_boxplot(iris, "Sepal.Length", "Species")
p + scale_x_discrete(position = 'top', 
                     labels = ggplot_build(p)$layout$panel_scales$x[[1]]$labels)

labels =位返回从绘图p中写入现有标签的函数。