breaks_fun 函数的奇怪行为

Odd Behaviour of breaks_fun Function

我一直在处理一个对我来说就像一个谜一样的问题。我可以使用以下代码绘制以下图:

# Custom y-axis breaks ~
breaks_fun <- function(x){
  if (min(x) < 1){
    seq(1, 4)}
  else if (min(x) < 83){
    seq(85, 95, by = 5)}
  else if (min(x) < 100){
    seq(96, 99, by = 1)}
  else { 
    seq(0, 40000000, by = 5000000)}}


# Custom y-axis labels ~
plot_index_labels <- 0
labels_fun <- function(x) {
  plot_index_labels <<- plot_index_labels + 1L
  switch(plot_index_labels,
         scales::label_number(accuracy = 0.1, suffix = "X")(x),
         scales::label_percent(accuracy = 1, scale = 1, big.mark = "")(x),
         scales::label_percent(accuracy = 1, scale = 1, big.mark = "")(x),
         scales::label_number(accuracy = 1, big.mark = "", suffix = "M")(x))}


# Creates the panel ~
BSG_Combined <- 
 ggplot() +
  geom_violin(data = fulldfUp, aes(x = Species, y = Value),
              fill = "#ffffff", colour = "#000000", show.legend = FALSE, alpha = .9, size = .3, width = .7) +
  stat_summary(data = fulldfUp, aes(x = Species, y = Value),  
               fun = mean, geom = "point", shape = 21, size = 3.5, alpha = .9, colour = "#000000", fill = "#000000") +
  facet_grid(Category ~. , scales = "free", labeller = labeller(Category = ylabels)) +
  scale_y_continuous(breaks = breaks_fun, labels = labels_fun) +
  theme(panel.background = element_rect(fill = "#ffffff"),
        panel.grid.major = element_line(color = "#ededed", linetype = "dashed", size = .00005),
        panel.grid.minor = element_blank(), 
        panel.border = element_blank(),
        panel.spacing.y = unit(1, "cm"),
        axis.line = element_line(colour = "#000000", size = .3),
        axis.title = element_blank(),
        axis.text.x = element_text(colour = "#000000", size = 16, face = "bold", angle = 45, vjust = 1, hjust = 1),
        axis.text.y = element_text(color = "#000000", size = 16, face = "bold"),
        axis.ticks.x = element_line(color = "#000000", size = .3),
        axis.ticks.y = element_line(color = "#000000", size = .3),
        strip.background.y = element_rect(colour = "#000000", fill = "#d6d6d6", size = 0.3),
        strip.text = element_text(colour = "#000000", size = 20, face = "bold"),
        legend.position = "top",
        legend.margin = margin(t = 0, b = 0, r = 0, l = 0),
        legend.box.margin = margin(t = 10, b = 20, r = 0, l = 0),
        legend.key = element_rect(fill = NA),
        legend.background = element_blank())

因此,如您所见,breanks_fun 函数适用于除最后一个方面之外的所有方面。我试图以无数种方式改变这个功能——包括添加一个最终的 else if [例如(min(x) > 1000)] 但组合无效。我也可以在没有 labels = labels_fun 函数的情况下完成,结果是一样的。我已经设法在另一个数据上使用了这个完全相同的函数,但是当我尝试将它应用到这个新数据上时似乎出现了问题。

一些信息:

> summary(TotalReads$Value)
    Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
  576504  6209678 10267860 10715209 14395940 34754853

所以这个数据和我以前的数据唯一的区别就是这里的最小值和最大值之间的差异更大。但是,我看不出这会如何影响 breanks_fun 函数,因为这些样本与其他 3 个类别中存在的样本非常不同,因此 else 无论如何应该绰绰有余。

有人能找出我遗漏的东西吗? 如果有任何帮助,我将不胜感激。

此致,乔治。

问题的症结在于 breaks_fun 超出了绘图的限制,而不是默认展开的数据。请参阅 scale_y_continuous

帮助中的 expand 参数

"For position scales, a vector of range expansion constants used to add some padding around the data to ensure that they are placed some distance away from the axes. Use the convenience function expansion() to generate the values for the expand argument. The defaults are to expand the scale by 5% on each side for continuous variables, and by 0.6 units on each side for discrete variables."

对于最后一组数据,这使得下限为负数。因此,中断是在 seq(1,4) 处创建的。在 breaks_fun 中添加 print 语句以查看此内容。 (我只是使用您的摘要数据作为复制行为的数据集)

smpData <- c(576504,  6209678, 10267860, 10715209, 14395940, 34754853)
smpDf <- data.frame(
  Value = rep(smpData, 5),
  Species = rep(LETTERS[1:5], each = length(smpData))
)


breaks_fun <- function(x){
  print(x)
  ....<other code>...

#>[1] -1132413 36463770

看来你有两个选择。第一,不使用 min 来设置间隔,而是使用 maxbreaks_fun 变成(有点符合我的编码风格):

breaks_fun <- function(x){
  caseVal <- max(x)

  if (caseVal < 1){
    seq(1, 4)
  } else if (caseVal < 83){
    seq(85, 95, by = 5)
  } else if (caseVal < 100){
    seq(96, 99, by = 1)
  } else {
    seq(0, 40000000, by = 5000000)
  }
}

或者,您可以设置 expand 参数,但您的绘图将基于 x-axis。

scale_y_continuous(
    breaks = breaks_fun, labels = labels_fun, expand = c(0, 0)
  )

您还可以将其与显式设置 limits 参数相结合,为您提供一些间距,但请务必同时调整 expand 以使限制保持 positive/satisfy 您的 switch 语句在 breaks_fun.