2015-08-29 27 views
5

Vorrei tracciare una singola linea che è multicolore, ei colori sono basati sul valore corrispondente in un fattore. Ad esempio, una serie temporale di prezzo giornaliero di chiusura delle scorte, in cui i giorni in cui è salito di più di un certo importo sono in blu, e i giorni in cui sono andati fatti da molti sono in rosso, e gli altri giorni è in nero noioso.Stampa di serie temporali utilizzando colori diversi in base al fattore

miei dati è in una xts oggetto (con il fattore messo in là con as.numeric(myfactor)), e mi piacerebbe essere con il quantmod chartSeries o chart_Series funzioni. Ma se questo è impossibile allora qualcosa che usa plot sarebbe sufficiente.

alcuni dati di esempio:

library(xts) 
x = xts(data.frame(v=(rnorm(50)+10)*10, type=floor(runif(50)*4)), 
    order.by=as.Date("2001-01-01")+1:50) 

E posso tracciare in questo modo:

library(quantmod) 
chartSeries(x$v) 
addTA(x$type, type='p') 

che assomiglia a questo: plot using chartSeries

Vale a dire Ho pensato che sarebbe stato più facile abbinare le informazioni nel grafico in basso con quello in alto se si utilizzavano segmenti di linee colorate.

+1

Dovresti pubblicare alcuni dati. Immagino che tu non voglia quello che la maggior parte delle persone chiamerebbe una "linea", ma piuttosto desidera "segmenti" colorati. –

+0

@BondedDust Ho aggiunto alcuni dati di test. 'segments' potrebbe essere quello che voglio, anche se sembra abbastanza basso (nessun supporto per i timestamp sull'asse x?) –

risposta

1

Questo codice è iniziato come una mod secondaria del codice di esempio su ?segments ed è per questo che il titolo del grafico sembra strano, ma ho deciso di lasciarlo in ogni caso. La logica è che i termini all'interno di "[.]" Selezioneranno i colori in base alla differenza tra i valori successivi formati come la differenza tra tail(y,-1) e head(y,-1), con il valore predefinito "nero" e le soglie pari a 1 in questo caso , ma che potrebbe facilmente essere modificata:

set.seed(123) 
x <- 1:12; y <- rnorm(12) 
plot(x, y, main = "arrows(.) and segments(.)") 

s <- seq(length(x)-1) 
arrows(x[s], y[s], x[s+1], y[s+1], 
     col= c("black", "red", "blue")[1+       # default=1 
             (tail(y,-1)-head(y,-1) < -1) + # big down (1+1) 
            2*(tail(y,-1)-head(y,-1) > 1) ]) # big up (1+2) 

Se si voleva solo segmenti di linea noiosi è possibile utilizzare la funzione di segments piuttosto che arrows.

enter image description here

mi rendo conto che a leggere la questione ancora una volta che hai detto che già avuto una variabile fattore nella vostra XTS-oggetto, anche se la mia comprensione è che XTS-oggetti potrebbero non essere in grado di contenere le colonne fattore di tipo , dal momento che sono elaborazioni della classe zoo e il coredata è una matrice R (quindi nessun attributo di livello). Ma forse i quant-guys hanno una soluzione per questo? Quindi questo sarebbe un altro motivo per cui devi pubblicare alcuni dati e PER FAVORE, usa il dput per presentare l'oggetto. Costruire oggetti xts dall'output della console è una vera seccatura.

2

Quindi ecco una soluzione ggplot. È un po 'più coinvolto, ma offre opzioni di formattazione più sofisticate.

library(quantmod) 
sp500 <- getSymbols("^GSPC", from="2015-01-01", auto.assign=FALSE) 
sp500 <- Cl(sp500)       # extract close 
sp500 <- merge(sp500, dailyReturn(sp500)) # add daily returns 
sp500 <- merge(lag(Cl(sp500),1), sp500) # merge with close lagged by 1 day 

names(sp500) <- c("ymin", "ymax", "return") 
library(ggplot2) 
library(scales) 
df <- with(sp500, 
      data.frame(xmin=c(lag(index(sp500),1)), 
         xmax=index(sp500), 
         ymin, ymax, return)) 
df$status <- with(df,ifelse(return>0.01,"up",ifelse(return< -0.01,"down","neutral"))) 
ggplot(df) + 
    geom_segment(aes(x=xmin, xend=xmax, y=ymin, yend=ymax, color=status)) + 
    scale_color_manual(values=c(up="green", down="red", neutral="grey50"), 
        breaks=c("up","down"), 
        labels=c("Gain > 1%", "Loss > 1%")) + 
    scale_x_date(breaks=date_breaks("months"), labels=date_format("%b"))+ 
    labs(x=NULL, y="Closing Price", title="S&P 500") + 
    theme(panel.background =element_rect(fill="black"), 
     panel.grid = element_blank()) 

Come con l'altra risposta l'idea di base è quella di disegnare segmenti codice colore in base alla grandezza del guadagno/perdita. Quindi iniziamo estraendo i prezzi di chiusura, aggiungiamo una colonna di resi e quindi aggiungiamo un'altra colonna di prezzi di chiusura ritardata di 1 giorno. Quindi creiamo un data.frame da questo con due colonne di date, anch'esse ritardate di 1 giorno. Quindi aggiungiamo una colonna (status) per indicare se il guadagno/perdita era> 1%. Quindi lo usiamo per guidare geom_segment(...), codice colore status. Nella chiamata scale_color_manual(...), impostiamo i colori su rosso e verde ed escludiamo il colore neutro dalla legenda. Il resto è tutta la formattazione.