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


87

我有以下情节:

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

我希望y轴仅显示整数。通过四舍五入还是通过更优雅的方法来完成此操作对我而言并不重要。


2
您是否看过任何比例功能?scale_y_continuous也许?
joran 2013年

我读了一些类似问题的答案,给人的印象是scale_y_continuous是从其他数字格式(例如科学计数法)转换而来的,但没有容纳我要查找的实数到整数的转换。我可能会误会...
Atticus13年

Answers:


41

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

41
该解决方案仅适用于您知道轴上有哪些值的情况。这不是一个好的通用解决方案。
激怒

3
后代注意事项:geom_bar不再具有y美学效果(以代替geom_col)。并且,尽管不是一般的解决方案,但在此示例中,使用特定的n调用pretty可以解决原始问题(并且比硬编码中断更灵活): q + geom_col(position='dodge', colour='black') + xlab('IR')+scale_fill_grey() + theme_bw() + scale_y_continuous('Frequency', breaks=function(x) pretty(x, n=6))
helmingstay

72

如果您有此scales软件包,则可以使用pretty_breaks()而无需手动指定中断。

q + geom_bar(position='dodge', colour='black') + 
scale_y_continuous(breaks= pretty_breaks())

17
这似乎几乎完成了默认方法的工作,并且我在休息时仍然有小数点。
kory

哪里pretty_breaks()来的?
玛丽安


12
pretty_breaks()很漂亮,但并不总是整数。显然,小数点里有美...
PatrickT

50

这是我用的:

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

17

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

int_breaks <- function(x, n = 5) {
  l <- pretty(x, n)
  l[abs(l %% 1) < .Machine$double.eps ^ 0.5] 
}

用于

+ scale_y_continuous(breaks = int_breaks)

它通过采用默认的中断,并仅保留那些整数来工作。如果显示的数据中断太少,请增加n,例如:

+ scale_y_continuous(breaks = function(x) int_breaks(x, n = 10))

如果您只有0-1.25的数据或有什么数据,这会使您丢失整数1。我在x轴上只看到0。
kory

1
为了简单起见,我喜欢这个。请注意,n可能会根据您的值范围进行一些调整。它似乎确定了(大概)多少个中断。
玛丽安

13

这些解决方案不适用于我,也无法解释解决方案。

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

2
最佳答案
马丁

3

Google提出了我这个问题。我正在尝试使用ay比例的实数。y刻度数字以百万为单位。

包装comma方法引入了一个逗号,以我的大量涌现。R-Blogger上的这篇帖子介绍了一种使用该comma方法的简单方法:

library(scales)

big_numbers <- data.frame(x = 1:5, y = c(1000000:1000004))

big_numbers_plot <- ggplot(big_numbers, aes(x = x, y = y))+
geom_point()

big_numbers_plot + scale_y_continuous(labels = comma)

享受R :)


1
这里的其他解决方案实际上并不适合我,或者看起来非常复杂。这个工作很简单。
Brian Doherty

感谢@BrianDoherty,简单性是大多数事情的关键...
托尼·克罗宁

3

现有的所有答案似乎都需要自定义功能,或者在某些情况下会失败。

这行代码使整数中断:

bad_scale_plot +
  scale_y_continuous(breaks = scales::breaks_extended(Q = c(1, 5, 2, 4, 3)))

有关更多信息,请参见文档?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也可以手动减小)。


1

此答案建立在@Axeman的答案的基础上,用kory来解决,如果数据仅从0到1,则不会在1处显示中断。这似乎是由于 pretty输出而输出似乎为1并不等于1(请参阅最后的示例)。

因此,如果您使用

int_breaks_rounded <- function(x, n = 5)  pretty(x, n)[round(pretty(x, n),1) %% 1 == 0]

+ scale_y_continuous(breaks = int_breaks_rounded)

0和1都显示为中断。

举例说明与Axeman的区别

testdata <- data.frame(x = 1:5, y = c(0,1,0,1,1))

p1 <- ggplot(testdata, aes(x = x, y = y))+
  geom_point()


p1 + scale_y_continuous(breaks = int_breaks)
p1 + scale_y_continuous(breaks =  int_breaks_rounded)

两者都将使用初始问题中提供的数据。

为什么需要四舍五入的图示

pretty(c(0,1.05),5)
#> [1] 0.0 0.2 0.4 0.6 0.8 1.0 1.2
identical(pretty(c(0,1.05),5)[6],1)
#> [1] FALSE

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.