Як відображати лише цілі значення на осі за допомогою 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

Я прочитав деякі відповіді на подібні запитання, і склалося враження, що масштаб_y_continuous перетворено з інших числових форматів (наприклад, наукові позначення), але не враховував реальне число до цілого числа, яке я шукав. Я можу помилитися ...
Atticus29,

Відповіді:


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
Це рішення підходить лише для ситуацій, коли ви знаєте, які значення знаходяться на осях. Не хороше загальне рішення.
swolf

3
Примітка для нащадків: geom_barбільше не працює з y естетикою (замінити на geom_col). І, хоча це не загальне рішення, у цьому прикладі виклик симпатичного з певним n може виправити вихідну проблему (і є більш гнучким, ніж жорсткі 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))
коди

72

Якщо у вас є scalesпакет, ви можете використовувати його pretty_breaks()без необхідності вручну вказувати перерви.

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

17
Здавалося, це робить майже те, що робить метод за замовчуванням, і я все ще мав десяткові крапки в перервах.
кори

Звідки береться pretty_breaks()?
Маріан


12
pretty_breaks()гарні, але не завжди цілі числа. Очевидно, що в десяткових
знаках

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

18

Ви можете використовувати власний етикетчик. Наприклад, ця функція гарантує отримання лише цілочисельних розривів:

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

Це призводить до втрати цілого числа 1, якщо у вас є дані лише від 0 - 1,25 або що у вас є. Я бачу лише 0 на осі х.
кори

1
Мені це подобається заради простоти. Зауважте, що nможе знадобитися деяка настройка залежно від діапазону значень. здається, це визначає, скільки буде перерв (приблизно).
Маріан

13

Ці рішення для мене не працювали і не пояснювали рішення.

breaksАргумент до scale_*_continuousфункції може бути використаний з користувальницької функцією , яка приймає межі в якості вхідних і повертають брейки , як вихід. За замовчуванням межі осей будуть розширені на 5% з кожного боку для безперервних даних (відносно діапазону даних). Через це розширення обмеження осі, швидше за все, не будуть цілими значеннями.

Рішенням, яке я шукав, було просто округлити нижню межу до найближчого цілого числа, округлити верхню межу до найближчого цілого числа, а потім зробити розриви у цілих значеннях між цими кінцевими точками. Тому я використав функцію розривів:

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 підвів мене до цього питання. Я намагаюся використовувати реальні числа в масштабі. Число шкали y - у мільйонах.

Метод пакету масштабівcomma вводить кому до моїх великих чисел. У цій публікації на R-Bloggers пояснюється простий підхід із використанням 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
Інші рішення тут насправді не працювали для мене або здавались смішно складними. Цей працював і був простим у виконанні.
Брайан Доерті

дякую @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 на коментар Кори, що якщо дані переходять лише від 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 відображаються як розриви.

Приклад для ілюстрації відмінності від Аксемана

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.