2017-02-12 5 views
-2

ich bin etwas zu kämpfen, die, glaube ich, sollteMehrere Intraday-Zeitreihe auf dem gleichen Chart

Bitte beachten Sie das folgende Beispiel in R. ziemlich straighforward sein:

library(dplyr) 
library(tidyverse) 

time = c('2013-01-03 22:04:21.549', '2013-01-03 22:04:22.349', '2013-01-03 22:04:23.559', '2013-01-03 22:04:25.559') 
value1 = c(1,2,3,4) 
value2 = c(400,500,444,210) 

data <- data_frame(time, value1, value2) 
data <-data %>% mutate(time = as.POSIXct(time)) 

> data 
# A tibble: 4 × 3 
       time value1 value2 
       <dttm> <dbl> <dbl> 
1 2013-01-03 22:04:21  1 400 
2 2013-01-03 22:04:22  2 500 
3 2013-01-03 22:04:23  3 444 
4 2013-01-03 22:04:25  4 210 

Mein Problem ist einfach:

Ich möchte plotten value1 AND value2 auf dem gleichen Diagramm mit zwei verschiedenen Y-Achse.

Wie Sie im Beispiel sehen können, unterscheiden sich die Einheiten zwischen den beiden Variablen stark, so dass die Verwendung nur einer Achse eine der Zeitreihen komprimiert.

Überraschenderweise hat es sich als sehr schwierig erwiesen, ein gut aussehendes Diagramm für dieses Problem zu bekommen. Ich bin verrückt (natürlich nicht wirklich sauer. Nur verwirrt;)).

In Python Pandas, könnte man einfach nutzen:

data.set_index('time', inplace = True) 
data[['value1', 'value2']].plot(secondary_y = 'value2') 

in Stata, könnte man einfach sagen:

twoway (line value1 time, sort) (line value2 time, sort) 

In R, ich weiß nicht, wie es zu tun. Fehle ich hier etwas? Base R, ggplot2, irgendein komisches Paket, jede Arbeitslösung mit anständigen Anpassungsoptionen wäre hier in Ordnung.

+2

Hadley hat wiederholt gesagt (und auf dieser Seite, wenn Sie suchen), dass er denkt, dass eine doppelte y-Achsen sind irreführend, es sei denn, sie sind nur Conversions (wie Celcius und Fahrenheit). Verwenden Sie stattdessen eine Protokollskala oder Facetten, z. 'Bibliothek (ordentlich); daten%>% sammeln (var, val, -time)%>% ggplot (aes (zeit, val, farbe = var)) + geom_line() + scale_y_log10() ' – alistaire

+0

@alistaire das ist kein duplikat, denn hier gibt es die datetime-Komponente der x-Achse, die sich von vielen Beispielen in SO unterscheidet. –

+0

@alistaire auch, Dieses Argument gegen Doppelachse ist reiner Unsinn. Öffnen Sie ein beliebiges ökonometrisches Buch, das Zeitreihen enthält, und Sie sehen überall doppelte y-Achsen-Plots. Der Punkt, dass die duale y-Achse Menschen irreführt, ist absurd. Natürlich glaubt niemand, dass die Linie, die sich in einem Doppelachsen-Diagramm kreuzt, tatsächlich an diesem Punkt kreuzt. Es ist nur ein Artefakt der Grafik! Zweiachsiges Diagramm ist eine Co-Bewegung. Wie auch immer, sonst ist ggplot2 natürlich mein liebstes Tagespaket. Hier brauche ich nur etwas, das funktioniert ... –

Antwort

1

Ein Basis-R-Hack, der Ihre Anforderungen beantworten kann. Ich werde aus dem Weg gehen, um klar zu machen, welche Komponenten (blau oder rot) für welche Komponenten verantwortlich sind. Es ist hässlich, aber es zeigt die erforderlichen Punkte. Verwenden Sie Ihre Daten:

# making sure the left and right sides have the same space 
par(mar = c(4,4,1,4) + 0.1) 
# first plot 
plot(value1 ~ time, data = data, pch = 16, col = "blue", las = 1, 
    col.axis = "blue", col.lab = "blue") 
grid(lty = 1, col = "blue") 
# "reset" the whole plot for an overlay 
par(fig = c(0,1,0,1), new = TRUE) 
# second plot, sans axes and other annotation 
plot(value2 ~ time, data = data, pch = 16, col = "red", 
    axes = FALSE, ann = FALSE) 
grid(lty = 3, col = "red") 
# add the right-axis and label 
axis(side = 4, las = 1, col.axis = "red") 
mtext("value2", side = 4, line = 3, col = "red") 

misaligned grids

habe ich die Gitter ein ästhetisches Problem hervorzuheben: sie richten nicht „ordentlich“. Wenn Sie damit einverstanden sind, können Sie jetzt aufhören.

Hier ist eine Methode (die nicht mit erheblich anderen Datenbereichen getestet wurde). (Es gibt sicherlich andere Methoden abhängig von Ihren Daten und Einstellungen.)

# one way that may "normalize" the y-axes for you, so that the grid should be identical 
y1 <- pretty(data$value1) 
y1n <- length(y1) 
y2 <- pretty(data$value2) 
y2n <- length(y2) 
if (y1n < y2n) { 
    y1 <- c(y1, y1[y1n] + diff(y1)[1]) 
} else if (y1n > y2n) { 
    y2 <- c(y2, y2[y2n] + diff(y2)[1]) 
} 

und die darauf folgende Handlung, das Hinzufügen ylim=range(...):

# making sure the left and right sides have the same space 
par(mar = c(4,4,1,4) + 0.1) 
# first plot 
plot(value1 ~ time, data = data, pch = 16, col = "blue", las = 1, ylim = range(y1), 
    col.axis = "blue", col.lab = "blue") 
grid(lty = 1, col = "blue") 
# "reset" the whole plot for an overlay 
par(fig = c(0,1,0,1), new = TRUE) 
# second plot, sans axes and other annotation 
plot(value2 ~ time, data = data, pch = 16, col = "red", ylim = range(y2), 
    axes = FALSE, ann = FALSE) 
grid(lty = 3, col = "red") 
# add the right-axis and label 
axis(side = 4, las = 1, col.axis = "red") 
mtext("value2", side = 4, line = 3, col = "red") 

aligned grids

(Obwohl der rot-blau Wechsel Gitterlinien sind grauenhaft, sie zeigen, dass die Gitter in der Tat gut ausgerichtet sind.)

NB: die Verwendung von par(fig = c(0,1,0,1), new = TRUE) ist ein bisschen zerbrechlich. Wenn Sie beispielsweise Ränder oder andere wichtige Änderungen zwischen Plots ändern, kann das Overlay leicht durchbrochen werden, und Sie werden es nicht wirklich wissen, es sei denn, Sie tun etwas Handarbeit, um zu sehen, wie der additive Prozess tatsächlich abläuft. In diesem "Prüf" -Prozess möchten Sie wahrscheinlich axes=F, ann=F aus dem zweiten Diagramm entfernen, um zu bestätigen, dass mindestens die Kästchen und die X-Achse wie vorgesehen ausgerichtet sind.

+0

erstaunlich !!! aber mann diese diagramme sind schrecklich danke lass mich das versuchen –

+1

Einige andere Links, die nützlich sein können: http://rpubs.com/kohske/dual_axis_in_ggplot2 und http://stackoverflow.com/questions/21981416/dual-y-axis- In-ggplot2-für-mehrere-Panel-Figur. – r2evans

+1

Eines der (vielen) Dinge, von denen ich denke, dass "ggplot2" gut ist, ist die visuelle "Grammatik der Grafiken", von denen viele visuell intuitiv sind. Indem ich die y-Achsen an eine offensichtliche Unterscheidung der Punkte/Linien (d. H. Der Farbe) anbinde, denke ich, dass es dazu neigt, die Bedenken zu mildern, die Skalen zu verwechseln. Obwohl meine Auswahl an Paletten hier zu wünschen übrig lässt, sollte man vorsichtig sein, um sicherzustellen, dass Sie eine offensichtliche Unterscheidung unterstützen. (Die Verwendung der gleichen Farbe/Punkt/Linie-Typ für alle Datenpunkte kann eine unverantwortliche Darstellung, unter der Annahme der "gute Handlung Stewardship".) – r2evans

1

Version 2.2.0 von ggplot2 ermöglicht es, eine sekundäre Achse zu definieren.Nun kann die zweite Zeitreihe entsprechend skaliert werden und in der gleichen Diagramm angezeigt:

data %>% 
    mutate(value2 = value2/100) %>% # scale value2 
    gather(variable, value, -time) %>% # reshape wide to long 
    ggplot(aes(time, value, colour = variable)) + 
    geom_point() + geom_line() + 
    scale_y_continuous(name = "value1", sec.axis = sec_axis(~ . * 100, name = "value2")) 

enter image description here

+0

sehr süß, aber hier betrügen Sie irgendwie, weil Sie die Skala manuell definieren. jede Möglichkeit, das automatisch zu tun? Ich habe viele verschiedene Zeitreihen ... –

+0

Ich denke, das ist sehr sauber, aber sehen Sie eine Möglichkeit, die Neuskalierung zu automatisieren? –

Verwandte Themen