Ggplot2 kullanılarak bir eksende yalnızca tam sayı değerleri nasıl görüntülenir


88

Şu arsam var:

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 ekseninin yalnızca tam sayıları göstermesini istiyorum. Bunun yuvarlama yoluyla mı yoksa daha zarif bir yöntemle mi başarılacağı benim için gerçekten önemli değil.


2
Herhangi bir ölçek işlevine baktınız mı? scale_y_continuousolabilir?
joran

Benzer sorulara bazı yanıtlar okudum ve scale_y_continuous'in diğer sayısal biçimlerden (örneğin, bilimsel gösterim) dönüştürüldüğü, ancak aradığım gerçek sayıyı tam sayıya dönüştürmediği izlenimine kapıldım. Yanılıyor olabilirim ...
Atticus29

Yanıtlar:


42

scale_y_continuous()Ve argüman ile breaks=y ekseni için kırılma noktalarını görüntülemek istediğiniz tam sayılara ayarlayabilirsiniz.

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

45
Bu çözüm sadece eksenlerde hangi değerlerin olduğunu bildiğiniz durumlar için iyidir. İyi bir genel çözüm değil.
swolf

4
Gelecek nesiller için not: geom_barartık y estetikle çalışmıyor (ile değiştirin geom_col). Ve genel bir çözüm olmasa da, bu örnekte belirli bir n ile güzel arama orijinal sorunu çözebilir (ve sabit kodlama molalarından daha esnektir): 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

73

Eğer varsa scalespaketi kullanabilirsiniz pretty_breaks()elle sonları belirtmek gerek kalmadan.

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

17
Bu, neredeyse varsayılan yöntemin yaptığını yapıyor gibi görünüyordu ve aralarda hala ondalık noktalarım vardı.
kory

Nereden pretty_breaks()geliyor?
Marian


16
pretty_breaks()güzeldir, ancak her zaman tam sayı değildir. Açıkçası ondalık sayılarda güzellik var ...
PatrickT

51

Kullandığım şey bu:

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

Bu işe yarayan ilk cevaptır, ancak bir açıklayıcı memnuniyetle karşılanacaktır.
DomQ

18

Özel bir etiketleyici kullanabilirsiniz. Örneğin, bu işlev yalnızca tam sayı kesmeleri üretmeyi garanti eder:

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

Olarak kullan

+ scale_y_continuous(breaks = int_breaks)

Varsayılan molaları alarak ve yalnızca tam sayı olanları koruyarak çalışır. Verileriniz için çok az ara gösteriyorsa, artırın n, örneğin:

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

Bu, yalnızca 0 - 1.25 arasında veriye sahipseniz veya elinizde ne varsa 1 tamsayısını kaybetmenize neden olur. X ekseninde yalnızca 0 görüyorum.
kory

1
Bunu basitlik uğruna seviyorum. nDeğer aralığınıza bağlı olarak bazı ince ayarların kullanılabileceğini unutmayın . kaç mola olacağını (kabaca) belirliyor gibi görünüyor.
Marian

15

Bu çözümler benim için işe yaramadı ve çözümleri açıklamadı.

breaksBağımsız değişken scale_*_continuousfonksiyonları çıkış olarak giriş ve döner sonları olarak sınırları alır özel bir fonksiyon ile birlikte kullanılabilir. Varsayılan olarak, sürekli veriler için eksen sınırları her iki tarafta% 5 genişletilecektir (veri aralığına göre). Bu genişleme nedeniyle eksen sınırları büyük olasılıkla tamsayı değerleri olmayacaktır.

Aradığım çözüm, alt sınırı en yakın tam sayıya yuvarlamak, üst sınırı en yakın tam sayıya yuvarlamak ve ardından bu uç noktalar arasındaki tam sayı değerlerinde kesintiler yapmaktı. Bu nedenle, breaks işlevini kullandım:

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

Gerekli kod pasajı:

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

Orijinal sorudan tekrarlanabilir örnek şudur:

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
En iyi cevap burada
Martin

Martin ile aynı fikirdeyim - Tamamen çalışan bir örnek sağlama çabasını gösterdiğiniz için teşekkürler. Daniel Gardiner'ın cevabının daha iyi bir kırılma işlevi kullandığını fark ettim , bu da eksen aralığı yüzlerce veya daha fazla olduğunda dağınıklığa neden olmaz. Ayrıca, zevk meselesi olarak, ayrı bir breaks_integersişlevi tanımlamanın ve kullanmanın yeni başlayanlar için daha yararlı olabileceğini düşünüyorum. En iyi,
DomQ

5

Mevcut yanıtların tümü, özel işlevler gerektiriyor veya bazı durumlarda başarısız oluyor.

Bu satır tam sayı kesmeleri yapar:

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

Daha fazla bilgi için belgelere bakın ?labeling::extended(tarafından çağrılan bir işlevdir scales::breaks_extended).

Temel olarak, argüman Q, algoritmanın ölçek kırmaları için kullanmaya çalıştığı bir dizi güzel sayıdır. Varsayılan değeri, özgün arsa tamsayı olmayan kırılması (0, 2.5, 5 ve 7.5) üretir Q2.5 içerir: Q = c(1,5,2,2.5,4,3).

DÜZENLEME: bir yorumda belirtildiği gibi, y ekseni küçük bir aralığa sahip olduğunda tamsayı olmayan kesmeler meydana gelebilir. Varsayılan olarak, aralık çok küçük olduğunda imkansız olan molalar breaks_extended()hakkında bilgi vermeye çalışır n = 5. Hızlı test, 0 <y <2.5'ten daha geniş aralıkların tam sayı kesmeleri verdiğini gösterir ( nmanuel olarak da azaltılabilir).


3

Google beni bu soruya getirdi. Gerçek sayıları bir ölçekte kullanmaya çalışıyorum . Y ölçeği numaraları Milyon cinsindendir.

Ölçekler paket commayöntemi tanıtır virgül benim büyük sayılara. R-Blogger'larla ilgili bu gönderi , commayöntemi kullanan basit bir yaklaşımı açıklamaktadır :

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'nin keyfini çıkarın :)


1
Buradaki diğer çözümler aslında benim için işe yaramadı veya gülünç derecede karmaşık görünüyordu. Bu işe yaradı ve yapması kolaydı.
Brian Doherty

teşekkürler @BrianDoherty, basitlik çoğu şeyin anahtarıdır ...
Tony Cronin

2

Bu çözümü Joshua Cook'tan buldum ve oldukça iyi çalış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())

Kaynak: https://joshuacook.netlify.app/post/integer-values-ggplot-axis/


Bu işlev doğru cevap olmalıdır. Herhangi birinden daha kolay çalışır!
zdebruine

1

Bu cevap, @ Axeman'ın kory'nin yorumunu ele almak için verdiği cevaba dayanmaktadır, eğer veriler sadece 0'dan 1'e giderse, 1'de hiç kesinti gösterilmez. Bu, pretty 1 özdeş olmayan gibi görünen hangi çıkışlar ile 1 (sondaki örneğe bakın).

Bu nedenle eğer kullanırsanız

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

ile

+ scale_y_continuous(breaks = int_breaks_rounded)

hem 0 hem de 1 kesmeler olarak gösterilir.

Axeman'ınkinden farkı gösteren örnek

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)

Her ikisi de ilk soruda sağlanan verilerle çalışacaktır.

Neden yuvarlamanın gerekli olduğunu gösteren örnek

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.