如何使用 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())

我希望 y 轴只显示整数。这是通过舍入还是通过一种更优雅的方法实现的,对我来说并不真正重要。

111344 次浏览

With scale_y_continuous() and argument breaks= you can set the breaking points for y axis to integers you want to display.

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

如果您有 scales包,您可以使用 pretty_breaks()而不必手动指定中断。

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

我用的是这个:

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

可以使用自定义标签。例如,此函数保证只生成整数分割符:

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

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

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

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

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

The required code snippet is:

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

This answer builds on @Axeman's answer to address the comment by kory that if the data only goes from 0 to 1, no break is shown at 1. This seems to be because of inaccuracy in pretty with outputs which appear to be 1 not being identical to 1 (see example at the end).

因此,如果你使用

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都显示为休止符。

Example to illustrate difference from Axeman's

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

Google brought me to this question. I'm trying to use 真正的数字 in a y scale. The y scale numbers are in Millions.

天平 < 强大 > 天平 comma方法为我的大数引入了 逗号。这篇关于 博主的文章解释了一种使用 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:)

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

这行代表整数分割:

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也可以手动降低)。

我从约书亚 · 库克那里找到了这个解决方案,并且效果很好。

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

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

你可以使用 scales::label_number()或者 scales::label_comma()accuracy参数:

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)

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

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

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

Created on 2021-08-27 by the Reprex 软件包 (v2.0.0.9000)

如果你的值是整数,这里有另一种方法来处理 group = 1as.factor(value):

library(tidyverse)


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")
data3 %>%
mutate(value = as.factor(value)) %>%
ggplot(aes(x =factor(IR), y = value, fill = Legend, width=.15)) +
geom_col(position = 'dodge', colour='black', group = 1)

Reprex 软件包于2022.04-05年度创作(v2.0.1)

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

... + scale_y_continuous(breaks = ~round(unique(pretty(.))

它将围绕 pretty ()生成的唯一值集,只创建整数标签,而不管这些值的大小。

我就是这么做的

scale_x_continuous(labels = function(x) round(as.numeric(x)))