如何使用ggplot2仅在轴上显示整数值

Att*_*s29 66 r ggplot2

我有以下情节:

library(reshape)
library(ggplot2)
library(gridExtra)
require(ggplot2)



data2<-structure(list(IR = structure(c(4L, 3L, 2L, 1L, 4L, 3L, 2L, 1L
), .Label = c("0.13-0.16", "0.17-0.23", "0.24-0.27", "0.28-1"
), class = "factor"), variable = structure(c(1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L), .Label = c("Real queens", "Simulated individuals"
), class = "factor"), value = c(15L, 11L, 29L, 42L, 0L, 5L, 21L, 
22L), Legend = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), .Label = c("Real queens", 
"Simulated individuals"), class = "factor")), .Names = c("IR", 
"variable", "value", "Legend"), row.names = c(NA, -8L), class = "data.frame")
p <- ggplot(data2, aes(x =factor(IR), y = value, fill = Legend, width=.15))


data3<-structure(list(IR = structure(c(4L, 3L, 2L, 1L, 4L, 3L, 2L, 1L
), .Label = c("0.13-0.16", "0.17-0.23", "0.24-0.27", "0.28-1"
), class = "factor"), variable = structure(c(1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L), .Label = c("Real queens", "Simulated individuals"
), class = "factor"), value = c(2L, 2L, 6L, 10L, 0L, 1L, 4L, 
4L), Legend = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), .Label = c("Real queens", 
"Simulated individuals"), class = "factor")), .Names = c("IR", 
"variable", "value", "Legend"), row.names = c(NA, -8L), class = "data.frame")
q<- ggplot(data3, aes(x =factor(IR), y = value, fill = Legend, width=.15))


##the plot##
q + geom_bar(position='dodge', colour='black') + ylab('Frequency') + xlab('IR')+scale_fill_grey() +theme(axis.text.x=element_text(colour="black"), axis.text.y=element_text(colour="Black"))+ opts(title='', panel.grid.major = theme_blank(),panel.grid.minor = theme_blank(),panel.border = theme_blank(),panel.background = theme_blank(), axis.ticks.x = theme_blank())
Run Code Online (Sandbox Code Playgroud)

我希望y轴只显示整数.无论这是通过四舍五入还是通过更优雅的方法来实现,对我来说并不重要.

Sea*_*der 62

如果您有scales包,则pretty_breaks()无需手动指定中断即可使用.

q + geom_bar(position='dodge', colour='black') + 
scale_y_continuous(breaks= pretty_breaks())
Run Code Online (Sandbox Code Playgroud)

  • 这似乎几乎与默认方法有关,我在休息时仍然有小数点. (12认同)
  • pretty_breaks()很漂亮,但并不总是整数。显然,小数部分具有美感。 (5认同)
  • 'pretty_breaks()' 在 0.2.2 版 (2012-09-04) 中已被弃用,但“...保留是为了向后兼容;您应该切换到 `breaks_pretty()` 以获取新代码。” 在 [breaks_pretty() 的 CRAN 页面](https://scales.r-lib.org/reference/breaks_pretty.html) 有一条建议:“这主要对日期/时间有用,因为 `extended_breaks()` 应该在数字尺度方面做得稍微好一些。” (5认同)
  • 不起作用。仍然保留小数位 (2认同)

Dan*_*ner 42

这是我使用的:

ggplot(data3, aes(x = factor(IR), y = value, fill = Legend, width = .15)) +
  geom_col(position = 'dodge', colour = 'black') + 
  scale_y_continuous(breaks = function(x) unique(floor(pretty(seq(0, (max(x) + 1) * 1.1)))))
Run Code Online (Sandbox Code Playgroud)

  • 这在给定的示例中有效,但总的来说并不是一个好的解决方案。首先,它应该是 `seq(min(x), …` 而不是 `seq(0, …)`。此外,`* 1.1` 仅在数据为正数时添加填充,所以应该是 `*(1 + 符号(最大值(x)) * 0.1)` (3认同)
  • 这是第一个有效的答案,但如果有解释者将非常受欢迎。 (2认同)

Did*_*rts 32

使用scale_y_continuous()和参数,breaks=您可以将y轴的断点设置为要显示的整数.

ggplot(data2, aes(x =factor(IR), y = value, fill = Legend, width=.15)) +
    geom_bar(position='dodge', colour='black')+
    scale_y_continuous(breaks=c(1,3,7,10))
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案仅适用于您知道轴上有哪些值的情况.不是一个好的通用解决方案 (16认同)
  • 后人注意:“geom_bar”不再符合您的审美(用“geom_col”替换)。而且,虽然不是通用的解决方案,但在这个示例中,使用特定的 n 调用 Pretty 可以解决原始问题(并且比硬编码中断更灵活): `q + geom_col(position='dodge', color='black' ) + xlab('IR')+scale_fill_grey() + theme_bw() + scale_y_continuous('频率', Breaks=function(x) Pretty(x, n=6))` (4认同)

Nat*_*Nat 16

这些解决方案对我不起作用,也没有解释解决方案。

函数的breaks参数scale_*_continuous可以与自定义函数一起使用,该函数将限制作为输入并返回中断作为输出。默认情况下,对于连续数据(相对于数据范围),轴限制将在每侧扩展 5%。由于这种扩展,轴限制可能不是整数值。

我正在寻找的解决方案是简单地将下限四舍五入到最接近的整数,将上限向下舍入到最接近的整数,然后在这些端点之间的整数值处中断。因此,我使用了breaks函数:

brk <- function(x) seq(ceiling(x[1]), floor(x[2]), by = 1)

所需的代码片段是:

scale_y_continuous(breaks = function(x) seq(ceiling(x[1]), floor(x[2]), by = 1))

原始问题的可重现示例是:

data3 <-
  structure(
    list(
      IR = structure(
        c(4L, 3L, 2L, 1L, 4L, 3L, 2L, 1L),
        .Label = c("0.13-0.16", "0.17-0.23", "0.24-0.27", "0.28-1"),
        class = "factor"
      ),
      variable = structure(
        c(1L, 1L, 1L, 1L,
          2L, 2L, 2L, 2L),
        .Label = c("Real queens", "Simulated individuals"),
        class = "factor"
      ),
      value = c(2L, 2L, 6L, 10L, 0L, 1L, 4L,
                4L),
      Legend = structure(
        c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L),
        .Label = c("Real queens",
                   "Simulated individuals"),
        class = "factor"
      )
    ),
    row.names = c(NA,-8L),
    class = "data.frame"
  )

ggplot(data3, aes(
  x = factor(IR),
  y = value,
  fill = Legend,
  width = .15
)) +
  geom_col(position = 'dodge', colour = 'black') + ylab('Frequency') + xlab('IR') +
  scale_fill_grey() +
  scale_y_continuous(
    breaks = function(x) seq(ceiling(x[1]), floor(x[2]), by = 1),
    expand = expand_scale(mult = c(0, 0.05))
    ) +
  theme(axis.text.x=element_text(colour="black", angle = 45, hjust = 1), 
        axis.text.y=element_text(colour="Black"),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.border = element_blank(),
        panel.background = element_blank(), 
        axis.ticks.x = element_blank())
Run Code Online (Sandbox Code Playgroud)

  • 最佳答案在这里 (3认同)

小智 16

我从 Joshua Cook 那里找到了这个解决方案,效果非常好。

integer_breaks <- function(n = 5, ...) {
  fxn <- function(x) {
    breaks <- floor(pretty(x, n, ...))
    names(breaks) <- attr(breaks, "labels")
    breaks
  }
  return(fxn)
}

q + geom_bar(position='dodge', colour='black') + 
scale_y_continuous(breaks = integer_breaks())
Run Code Online (Sandbox Code Playgroud)

来源是: https ://joshuacook.netlify.app/post/integer-values-ggplot-axis/


Axe*_*man 11

您可以使用自定义贴标机.例如,此函数保证仅生成整数中断:

int_breaks <- function(x, n = 5) pretty(x, n)[pretty(x, n) %% 1 == 0] 
Run Code Online (Sandbox Code Playgroud)

用于

+ scale_y_continuous(breaks = int_breaks)
Run Code Online (Sandbox Code Playgroud)


Dro*_*let 8

您可以为此使用或accuracy的参数:scales::label_number()scales::label_comma()

fakedata <- data.frame(
  x = 1:5,
  y = c(0.1, 1.2, 2.4, 2.9, 2.2)
)

library(ggplot2)

# without the accuracy argument, you see .0 decimals
ggplot(fakedata, aes(x = x, y = y)) +
  geom_point() +
  scale_y_continuous(label = scales::comma)
Run Code Online (Sandbox Code Playgroud)

# with the accuracy argument, all displayed numbers are integers
ggplot(fakedata, aes(x = x, y = y)) +
  geom_point() +
  scale_y_continuous(label = ~ scales::comma(.x, accuracy = 1))
Run Code Online (Sandbox Code Playgroud)

# equivalent
ggplot(fakedata, aes(x = x, y = y)) +
  geom_point() +
  scale_y_continuous(label = scales::label_comma(accuracy = 1))
Run Code Online (Sandbox Code Playgroud)

# this works with scales::label_number() as well
ggplot(fakedata, aes(x = x, y = y)) +
  geom_point() +
  scale_y_continuous(label = scales::label_number(accuracy = 1))
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v2.0.0.9000)创建于 2021-08-27

  • 请注意,此方法可能会导致轴意外舍入,从而使图表看起来不准确。例如,下面的代码导致 y 轴刻度在 0, 2, __5__, 8, 10 处等距刻度。 `ggplot(data.frame(x = c("a", "b"), y = c (3, 10)), aes(x = x, y = y)) + geom_bar(stat = "身份") + s 4cale_y_连续(标签 = 尺度::label_number(精度 = 1))` (3认同)
  • 这可能会导致标签四舍五入,而不是实际修复中断本身,因此不建议这样做。 (2认同)

Nic*_*ick 5

所有现有的答案似乎都需要自定义函数或在某些情况下失败。

这一行使整数中断:

bad_scale_plot +
  scale_y_continuous(breaks = scales::breaks_extended(Q = c(1, 5, 2, 4, 3)))
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅文档 ?labeling::extended(这是一个由 调用的函数scales::breaks_extended)。

基本上,参数Q是一组很好的数字,算法试图将其用于比例中断。原始图产生非整数中断(0、2.5、5 和 7.5),因为Q包括 2.5: Q = c(1,5,2,2.5,4,3)

编辑:正如评论中所指出的,当 y 轴的范围很小时,可能会发生非整数中断。默认情况下,breaks_extended()尝试进行n = 5中断,当范围太小时这是不可能的。快速测试表明,大于 0 < y < 2.5 的范围会给出整数中断(n也可以手动减少)。


小智 5

一个答案确实在 Pretty() 函数的文档中。正如此处所指出的,将轴设置为“ggplot2”中的整数值,该函数已包含解决方案。你只需让它适用于小值。一种可能性是像作者那样编写一个新函数,对我来说,break 参数中的 lambda 函数就可以工作:

... + scale_y_continuous(breaks = ~round(unique(pretty(.))
Run Code Online (Sandbox Code Playgroud)

它将舍入由 Pretty() 生成的唯一值集,仅创建整数标签,无论值的大小如何。