So zeigen Sie mit ggplot2 nur ganzzahlige Werte auf einer Achse an

87

Ich habe die folgende Handlung:

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

Ich möchte, dass die y-Achse nur ganze Zahlen anzeigt. Ob dies durch Rundung oder durch eine elegantere Methode erreicht wird, ist mir nicht wirklich wichtig.

Atticus29
quelle
2
Haben Sie sich überhaupt eine der Skalenfunktionen angesehen? scale_y_continuousvielleicht?
Joran
Ich habe einige Antworten auf ähnliche Fragen gelesen und hatte den Eindruck, dass scale_y_continuous aus anderen numerischen Formaten (z. B. wissenschaftliche Notation) konvertiert wurde, aber die von mir gesuchte Konvertierung von reellen Zahlen in Ganzzahlen nicht berücksichtigt hat. Ich könnte mich irren ...
Atticus29

Antworten:

41

Mit scale_y_continuous()und argument können breaks=Sie die Bruchstellen für die y-Achse auf Ganzzahlen setzen, die Sie anzeigen möchten.

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))
Didzis Elferts
quelle
41
Diese Lösung eignet sich nur für Situationen, in denen Sie wissen, welche Werte auf den Achsen liegen. Keine gute allgemeine Lösung.
Swolf
3
Hinweis für die Nachwelt: Funktioniert geom_barnicht mehr mit Ihrer Ästhetik (ersetzen durch geom_col). Und obwohl dies keine allgemeine Lösung ist, kann in diesem Beispiel das Aufrufen von hübsch mit einem bestimmten n das ursprüngliche Problem beheben (und ist flexibler als Unterbrechungen mit fester Codierung): 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))
Steuerstand
72

Wenn Sie das scalesPaket haben, können Sie es verwenden, pretty_breaks()ohne die Pausen manuell angeben zu müssen.

q + geom_bar(position='dodge', colour='black') + 
scale_y_continuous(breaks= pretty_breaks())
Sealander
quelle
17
Dies schien fast das zu tun, was die Standardmethode tut, und ich hatte immer noch Dezimalstellen in den Pausen.
Kory
Woher kommt pretty_breaks()das?
Marian
12
pretty_breaks()sind hübsch, aber nicht immer ganze Zahlen. Offensichtlich gibt es Schönheit in Dezimalstellen ...
PatrickT
50

Das benutze ich:

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)))))
Daniel Gardiner
quelle
17

Sie können einen benutzerdefinierten Etikettierer verwenden. Diese Funktion garantiert beispielsweise, dass nur ganzzahlige Unterbrechungen erzeugt werden:

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

Benutzen als

+ scale_y_continuous(breaks = int_breaks)

Es funktioniert, indem die Standardpausen verwendet werden und nur die Ganzzahlen beibehalten werden. Wenn zu wenige Unterbrechungen für Ihre Daten angezeigt werden, erhöhen Sie diese n, z.

+ scale_y_continuous(breaks = function(x) int_breaks(x, n = 10))
Axeman
quelle
Dieser führt dazu, dass Sie die Ganzzahl 1 verlieren, wenn Sie nur Daten von 0 bis 1,25 haben oder was Sie haben. Ich sehe nur 0 auf der x-Achse.
Kory
1
Ich mag das der Einfachheit halber. Beachten Sie, dass nje nach Wertebereich einige Anpassungen erforderlich sind. es scheint zu bestimmen, wie viele Pausen es (ungefähr) geben wird.
Marian
13

Diese Lösungen haben bei mir nicht funktioniert und die Lösungen nicht erklärt.

Das breaksArgument für die scale_*_continuousFunktionen kann mit einer benutzerdefinierten Funktion verwendet werden, die die Grenzwerte als Eingabe verwendet und Unterbrechungen als Ausgabe zurückgibt. Standardmäßig werden die Achsengrenzen für kontinuierliche Daten auf jeder Seite um 5% erweitert (relativ zum Datenbereich). Die Achsengrenzen sind aufgrund dieser Erweiterung wahrscheinlich keine ganzzahligen Werte.

Die Lösung, nach der ich gesucht habe, bestand darin, einfach die Untergrenze auf die nächste Ganzzahl zu runden, die Obergrenze auf die nächste Ganzzahl abzurunden und dann zwischen diesen Endpunkten Unterbrechungen bei Ganzzahlwerten vorzunehmen. Deshalb habe ich die Pausenfunktion verwendet:

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

Das erforderliche Code-Snippet lautet:

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

Das reproduzierbare Beispiel aus der ursprünglichen Frage lautet:

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())
Nat
quelle
2
Beste Antwort hier
Martin
3

Google hat mich zu dieser Frage gebracht. Ich versuche, reelle Zahlen in jeder Skala zu verwenden. Die y-Skalennummern sind in Millionen angegeben.

Die Skalen - Paket commaMethode führt ein Komma zu meinen großen Zahlen. Dieser Beitrag über R-Blogger erklärt einen einfachen Ansatz mit der commaMethode:

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)

Viel Spaß mit R :)

Tony Cronin
quelle
1
Die anderen Lösungen hier haben bei mir nicht wirklich funktioniert oder schienen lächerlich kompliziert. Dieser funktionierte und war einfach zu machen.
Brian Doherty
danke @BrianDoherty, Einfachheit ist der Schlüssel für die meisten Dinge ...
Tony Cronin
3

Alle vorhandenen Antworten scheinen benutzerdefinierte Funktionen zu erfordern oder schlagen in einigen Fällen fehl.

Diese Zeile macht ganzzahlige Unterbrechungen:

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

Weitere Informationen finden Sie in der Dokumentation ?labeling::extended(eine Funktion, die von aufgerufen wird scales::breaks_extended).

Grundsätzlich ist das Argument Qeine Reihe netter Zahlen, die der Algorithmus für Skalenumbrüche zu verwenden versucht. Das ursprüngliche Diagramm erzeugt nicht ganzzahlige Unterbrechungen (0, 2,5, 5 und 7,5), da der Standardwert für Qenthält 2,5 : Q = c(1,5,2,2.5,4,3).

BEARBEITEN: Wie in einem Kommentar erwähnt, können nicht ganzzahlige Unterbrechungen auftreten, wenn die y-Achse einen kleinen Bereich hat. Standardmäßig breaks_extended()versucht zu machen n = 5Pausen, was unmöglich ist , wenn der Bereich zu klein ist. Schnelle Tests zeigen, dass Bereiche, die breiter als 0 <y <2,5 sind, ganzzahlige Unterbrechungen ergeben ( nkönnen auch manuell verringert werden).

Nick
quelle
1

Diese Antwort baut auf der Antwort von @ Axeman auf, um den Kommentar von kory anzusprechen, dass, wenn die Daten nur von 0 auf 1 gehen, bei 1 keine Unterbrechung angezeigt wird. Dies scheint auf die Ungenauigkeit prettybei Ausgaben zurückzuführen zu sein, mit denen 1 nicht identisch zu sein scheint 1 (siehe Beispiel am Ende).

Deshalb, wenn Sie verwenden

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

mit

+ scale_y_continuous(breaks = int_breaks_rounded)

Sowohl 0 als auch 1 werden als Unterbrechungen angezeigt.

Beispiel zur Veranschaulichung des Unterschieds zu Axemans

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)

Beide arbeiten mit den in der ersten Frage angegebenen Daten.

Abbildung, warum eine Rundung erforderlich ist

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
Sarah
quelle
1

Ich habe diese Lösung von Joshua Cook gefunden und ziemlich gut funktioniert.

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

Die Quelle ist: https://joshuacook.netlify.app/post/integer-values-ggplot-axis/

Bruno Vidigal
quelle