Cách chỉ hiển thị các giá trị số nguyên trên trục bằng ggplot2


87

Tôi có cốt truyện sau:

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

Tôi muốn trục y chỉ hiển thị số nguyên. Cho dù điều này được thực hiện thông qua làm tròn hoặc thông qua một phương pháp thanh lịch hơn không thực sự quan trọng đối với tôi.


2
Bạn đã xem xét bất kỳ chức năng tỷ lệ nào chưa? scale_y_continuouscó lẽ?
joran

Tôi đã đọc một số câu trả lời cho các câu hỏi tương tự và có ấn tượng rằng scale_y_continuous được chuyển đổi từ các định dạng số khác (ví dụ: ký hiệu khoa học), nhưng không phù hợp với chuyển đổi số thực thành số nguyên mà tôi đang tìm kiếm. Tôi có thể nhầm ...
Atticus. 29

Câu trả lời:


41

Với scale_y_continuous()và đối số, breaks=bạn có thể đặt các điểm ngắt cho trục y thành số nguyên mà bạn muốn hiển thị.

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
Giải pháp này chỉ tốt cho các tình huống mà bạn biết giá trị nào nằm trên trục. Không phải là một giải pháp chung tốt.
swolf

3
Lưu ý cho hậu thế: geom_barkhông còn tác dụng với mỹ y (thay thế bằng geom_col). Và, trong khi không phải là một giải pháp chung, trong ví dụ này gọi khá với một cụ thể n có thể khắc phục vấn đề ban đầu (và linh hoạt hơn phá vỡ cứng mã hóa): 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

Nếu bạn có scalesgói, bạn có thể sử dụng pretty_breaks()mà không cần phải chỉ định ngắt theo cách thủ công.

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

17
Điều này dường như làm gần như những gì phương pháp mặc định thực hiện và tôi vẫn có dấu chấm thập phân trong thời gian nghỉ.
kory

Từ đâu pretty_breaks()đến?
Marian


13
pretty_breaks()là đẹp, nhưng không phải lúc nào cũng là số nguyên. Rõ ràng là có vẻ đẹp trong số thập phân ...
PatrickT

50

Đây là những gì tôi sử dụng:

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

18

Bạn có thể sử dụng người ghi nhãn tùy chỉnh. Ví dụ: hàm này đảm bảo chỉ tạo ra các ngắt số nguyên:

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

Sử dụng như là

+ scale_y_continuous(breaks = int_breaks)

Nó hoạt động bằng cách lấy các ngắt mặc định và chỉ giữ lại những ngắt là số nguyên. Nếu nó hiển thị quá ít ngắt cho dữ liệu của bạn, hãy tăng lên n, ví dụ:

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

Điều này khiến bạn mất số nguyên 1 nếu bạn chỉ có dữ liệu từ 0 - 1.25 hoặc những gì có bạn. Tôi chỉ thấy 0 trên trục x.
kory

1
Tôi thích điều này vì lợi ích đơn giản. Lưu ý rằng ncó thể sử dụng một số điều chỉnh tùy thuộc vào phạm vi giá trị của bạn. nó dường như xác định số lần nghỉ sẽ có (đại khái).
Đức Mẹ

13

Những giải pháp này không làm việc cho tôi và không giải thích các giải pháp.

Đối breakssố cho các scale_*_continuoushàm có thể được sử dụng với một hàm tùy chỉnh lấy các giới hạn làm đầu vào và trả về các ngắt làm đầu ra. Theo mặc định, giới hạn trục sẽ được mở rộng 5% ở mỗi bên đối với dữ liệu liên tục (liên quan đến phạm vi dữ liệu). Các giới hạn trục có thể sẽ không phải là giá trị nguyên do sự mở rộng này.

Giải pháp mà tôi đang tìm kiếm chỉ đơn giản là làm tròn giới hạn dưới lên đến số nguyên gần nhất, làm tròn giới hạn trên xuống số nguyên gần nhất và sau đó ngắt ở các giá trị nguyên giữa các điểm cuối này. Do đó, tôi đã sử dụng hàm ngắt:

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

Đoạn mã bắt buộc là:

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

Ví dụ có thể tái tạo từ câu hỏi ban đầu là:

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
Câu trả lời hay nhất ở đây
Martin

3

Google đã đưa tôi đến câu hỏi này. Tôi đang cố gắng sử dụng các số thực theo tỉ lệ ay. Các số tỷ lệ y tính bằng Hàng triệu.

Các quy mô gói commaphương pháp giới thiệu một dấu phẩy để một số lượng lớn của tôi. Bài đăng này trên R-Bloggers giải thích một cách tiếp cận đơn giản bằng commaphương pháp:

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)

Thưởng thức R :)


1
Các giải pháp khác ở đây không thực sự hiệu quả với tôi, hoặc có vẻ phức tạp đến mức nực cười. Điều này đã hoạt động và rất đơn giản để làm.
Brian Doherty

cảm ơn @BrianDoherty, đơn giản là chìa khóa cho hầu hết mọi thứ ...
Tony Cronin

3

Tất cả các câu trả lời hiện có dường như yêu cầu các chức năng tùy chỉnh hoặc không thành công trong một số trường hợp.

Dòng này thực hiện ngắt số nguyên:

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

Để biết thêm thông tin, hãy xem tài liệu ?labeling::extended(là một hàm được gọi bởi scales::breaks_extended).

Về cơ bản, đối số Qlà một tập hợp các số đẹp mà thuật toán cố gắng sử dụng để ngắt tỷ lệ. Cốt truyện gốc sản xuất phá vỡ không số nguyên (0, 2,5, 5, và 7.5) vì giá trị mặc định cho Qbao gồm 2.5: Q = c(1,5,2,2.5,4,3).

CHỈNH SỬA: như đã chỉ ra trong một nhận xét, ngắt không phải số nguyên có thể xảy ra khi trục y có một phạm vi nhỏ. Theo mặc định, breaks_extended()cố gắng thực hiện khoảng n = 5ngắt, điều này là không thể khi phạm vi quá nhỏ. Thử nghiệm nhanh cho thấy rằng các phạm vi rộng hơn 0 <y <2,5 cho phép ngắt số nguyên ( ncũng có thể được giảm theo cách thủ công).


1

Câu trả lời này được xây dựng dựa trên câu trả lời của @ Axeman để giải quyết nhận xét của kory rằng nếu dữ liệu chỉ đi từ 0 đến 1, thì không có ngắt nào được hiển thị ở 1. Điều này dường như là do sự không chính xác trong prettykết quả đầu ra có vẻ như là 1 không giống với 1 (xem ví dụ ở cuối).

Do đó nếu bạn sử dụng

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

với

+ scale_y_continuous(breaks = int_breaks_rounded)

cả 0 và 1 đều được hiển thị dưới dạng ngắt.

Ví dụ để minh họa sự khác biệt với 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)

Cả hai sẽ hoạt động với dữ liệu được cung cấp trong câu hỏi ban đầu.

Minh họa lý do tại sao cần làm tròn số

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

1

Tôi đã tìm thấy giải pháp này từ Joshua Cook và hoạt động khá tốt.

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

Nguồn là: https://joshuacook.netlify.app/post/integer-values-ggplot-axis/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.