2016-06-11 5 views
2

Ich versuche, eine Heatmap aus den folgenden Daten zu erstellen:Warum coord_equal meine Heatmap zu brechen

> head(myData.aggregated) 
      datetime value  date    time 
1 2016-03-31 14:19:00  3 2016-03-31 2016-06-11 14:19:00 
2 2016-03-31 14:49:00 69 2016-03-31 2016-06-11 14:49:00 
3 2016-03-31 15:49:00  5 2016-03-31 2016-06-11 15:49:00 
4 2016-03-31 16:19:00  7 2016-03-31 2016-06-11 16:19:00 
5 2016-03-31 17:49:00  2 2016-03-31 2016-06-11 17:49:00 
6 2016-03-31 18:19:00  7 2016-03-31 2016-06-11 18:19:00 

> tail(myData.aggregated) 
       datetime value  date    time 
90 2016-04-06 13:19:00  1 2016-04-06 2016-06-11 13:19:00 
91 2016-04-06 13:49:00 25 2016-04-06 2016-06-11 13:49:00 
92 2016-04-06 14:19:00  7 2016-04-06 2016-06-11 14:19:00 
93 2016-04-06 14:49:00  1 2016-04-06 2016-06-11 14:49:00 
94 2016-04-06 22:19:00  3 2016-04-06 2016-06-11 22:19:00 
95 2016-04-06 22:49:00 14 2016-04-06 2016-06-11 22:49:00 

Und die folgenden ggplot2 Befehle.

ggplot(myData.aggregated, aes(x = time, y = date, fill = scale(value))) + geom_tile() + coord_equal() 

Sobald ich coord_equal() addiere, ist das Ergebnis ein leerer Graph. Kann mir jemand erklären, warum das passiert und wie ich es beheben kann? Mein Ziel ist es, für jedes 30-Minuten-Intervall eine Heatmap mit quadratischen Kacheln zu erhalten.

Update 1:

> dput(head(myData.aggregated)) 
structure(list(datetime = structure(c(1459426740, 1459428540, 
1459432140, 1459433940, 1459439340, 1459441140), class = c("POSIXct", 
"POSIXt"), tzone = ""), value = c(3L, 69L, 5L, 7L, 2L, 7L), date = structure(c(16891, 
16891, 16891, 16891, 16891, 16891), class = "Date"), time = structure(c(1465647540, 
1465649340, 1465652940, 1465654740, 1465660140, 1465661940), class = c("POSIXct", 
"POSIXt"), tzone = "")), .Names = c("datetime", "value", "date", 
"time"), row.names = c(NA, 6L), class = "data.frame") 
+0

Bitte in Ihre Frage die Ausgabe von 'dput (myDataSample)' wo 'myDataSample' ist ein Beispiel für Ihren Datenrahmen, der das gleiche Problem zeigt, wenn mit Ihrem Code ausgeführt wird. – eipi10

+0

Was ist 'x' in' scale (x) '? Meintest du "Maßstab (Wert)"? – eipi10

+0

genau, ich meinte 'Maßstab (Wert)' – Oliver

Antwort

6

TL; DR: Die y-Achse erstreckt sich über sechs Einheiten und die x-Achse erstreckt sich über Zehner-Tausenden von Einheiten. Wenn Sie coord_equal hinzufügen, wird die Y-Achse auf etwa 1/10.000stel der physikalischen Länge der X-Achse gequetscht, wodurch der Diagrammbereich effektiv verschwindet. Die date Spalte (Y-Achse) ist zufällig in Tagen und die time Spalte (X-Achse) in Sekunden, aber beide werden von ggplot als unitlose Zahlen behandelt. Sie können die Y-Achse auch in Sekunden angeben, aber das wird Ihnen immer noch eine Grafik mit einem unerwünschten Seitenverhältnis von mindestens 6: 1 geben. Siehe unten für Code und weitere Details.


Hier ist, was geschieht: date in Date Format ist und daher in Tagen denominiert ist, mit einem Bereich von 6 Tagen. time ist in POSIXct Format, das in Sekunden angegeben wird, mit einer Reichweite (da wir nur an der Tageszeit interessiert sind, unabhängig von Datum) von Zehntausenden von Sekunden (bis zu einem Maximum von 86.400 Sekunden, oder die Länge eines Tages).

Die zugrunde liegenden Werte von Date und POSIXct Formate sind nur numerische Werte mit jeweils Date und POSIXct Klassen angebracht. Wenn Sie also coord_equal hinzufügen, nimmt eine Einheit auf der y-Achse die gleiche physikalische Entfernung wie 1 Einheit auf der x-Achse ein, da ggplot (scheinbar) coord_equal basierend auf den numerischen Größen der Werte berechnet, ohne Berücksichtigung ihrer Datum-Uhrzeit-Klasse. Aber die gesamte Y-Achse überspannt 6 Einheiten, während die X-Achse Zehntausende von Einheiten umfasst. Wenn Sie also coord_equal benötigen, wird das y: x-Seitenverhältnis auf etwa 1: 10.000 oder so verkleinert, wodurch die Darstellung für alle praktischen Zwecke verschwindet.

Sie können sowohl die x- als auch die y-Achse in Sekunden angeben, aber selbst dann erstreckt sich die y-Achse mindestens sechsmal so lange (6 Tage) wie die x-Achse (maximal ein Tag), was zu ay führt : x Seitenverhältnis von mindestens 6: 1 mit coord_equal, was besser ist als 1: 10.000, aber immer noch nicht sehr praktisch.

Hier ist ein Beispiel mit gefälschten Daten:

# Fake data 
set.seed(4959) 
dat = data.frame(datetime=seq(as.POSIXct("2016-03-31"), as.POSIXct("2016-04-06"), by="hour")) 
dat$value = sample(1:50, nrow(dat), replace=TRUE) 

ggplot(dat, 
     aes(x = as.POSIXct(as.numeric(datetime) %% 86400, 
          tz="UTC", origin=as.Date("2016-01-01")), 
      y = as.POSIXct(as.Date(datetime)), 
      fill = scale(value))) + 
    geom_tile() + 
    labs(y="Date", x="Time") + 
    scale_x_datetime(date_labels="%H:%m") + 
    coord_equal() 

In dem obigen Code, die y-Werte erstellen wir Date-Format, das die Tageszeit beseitigt und dann konvertieren zurück zu POSIXct denen den ersten konvertieren konvertieren Einheit zu Sekunden, aber mit der Zeit gleich Mitternacht an diesem Tag für alle datetime Werte an einem bestimmten Datum.

Um die X-Werte zu erstellen, möchten wir nur die Uhrzeit in Sekunden nach Mitternacht, also berechnen wir den Rest des numerischen Werts von datetime nach Division durch 86400 (Anzahl der Sekunden an einem Tag).Die tz=UTC ist notwendig, um die Stunden richtig zu bekommen und origin (das kann ein beliebiges Datum sein; wir wollen nur die Tageszeit) ist notwendig, um die Funktion ohne Fehler zu erhalten.

Unten ist, wie die Handlung mit und ohne coord_equal aussieht. Beachten Sie, dass mit coord_equal die X-Achse, die sich über einen Tag (von Mitternacht bis Mitternacht) erstreckt, dieselbe Länge wie ein Tag auf der Y-Achse hat. Das liegt daran, dass wir die y- und x-Werte in Sekunden angegeben haben. Solange jedoch die y-Achse mehrere Tage umfasst und die x-Achse nur einen Tag überspannt, führt coord_equal zu einem unerwünschten Seitenverhältnis.

enter image description here

Unten finden Sie eine Demonstration, wie die y-Achse wird auf der x-Achse relativ zerquetscht, wenn die y-Werte in Tagen lauten anstatt Sekunden und coord_equal angegeben:

ggplot(dat, 
     aes(x = as.POSIXct(as.numeric(datetime) %% 86400, 
          tz="UTC", origin=as.Date("2016-01-01")), 
      y = as.Date(datetime), 
      fill = scale(value))) + 
    geom_tile() + 
    labs(y="Date", x="Time") + 
    scale_x_datetime(date_labels="%H:%m") + 
    coord_equal() 

enter image description here

Verwandte Themen