2016-01-27 6 views
5

Mam pytanie dotyczące kolorów linii w ggplot2. Potrzebuję wykreślić dane dotyczące promieniowania słonecznego, ale mam tylko 6 godzinnych danych, więc geom_line nie daje "miłego" wyjścia. Próbowałem już geom_smooth, a wynik jest zbliżony do tego, czego potrzebuję. Ale mam nowe pytanie, czy można zmienić kolor linii w zależności od wartości y?Zmień kolor linii w zależności od wartości y za pomocą ggplot2

kod wykorzystywany do działki jest

library(ggplot2) 
library(lubridate) 

# Lectura de datos 
datos.uvi=read.csv("serie-temporal-1.dat",sep=",",header=T,na.strings="-99.9") 
datos.uvi=within(datos.uvi, fecha <- ymd_h(datos.uvi$fecha.hora)) 

# geom_smooth 
ggplot(data=datos.uvi, aes(x=fecha, y=Rad_Global_.mW.m2., colour="GLOBAL")) + 
    geom_smooth(se=FALSE, span=0.3) 

w żądanym Wyjście, powinien być czerwony dla wartości mocy promieniowania 250, zielony w przedziale 250-500 i niebieski do wartości wyższych niż 500. Solar radiation plot

Czy to możliwe z geom_smooth? Próbowałem ponownie użyć kodu here, ale nie mogłem znaleźć punktu.

Dane stosowane do działki:

dput(datos.uvi) 
structure(list(fecha.hora = c(2016012706L, 2016012712L, 2016012718L, 
2016012800L, 2016012806L, 2016012812L, 2016012818L, 2016012900L, 
2016012906L, 2016012912L, 2016012908L, 2016013000L), latitud = c(37.75, 
37.75, 37.75, 37.75, 37.75, 37.75, 37.75, 37.75, 37.75, 37.75, 
37.75, 37.75), longitud = c(-1.25, -1.25, -1.25, -1.25, -1.25, 
-1.25, -1.25, -1.25, -1.25, -1.25, -1.25, -1.25), altitud = c(300L, 
300L, 300L, 300L, 300L, 300L, 300L, 300L, 300L, 300L, 300L, 300L 
), cobertura_nubosa = c(0.91, 0.02, 0.62, 1, 0.53, 0.49, 0.01, 
0, 0, 0.13, 0.62, 0.84), longitud_de_onda_inicial.nm. = c(284.55, 
284.55, 284.55, 284.55, 284.55, 284.55, 284.55, 284.55, 284.55, 
284.55, 284.55, 284.55), Rad_Global_.mW.m2. = c(5e-04, 259.2588, 
5, 100.5, 1, 886.5742, 110, 40, 20, 331.3857, 0, 0), Rad_Directa_.mW.m2. = c(0, 
16.58034, 0, 0, 0, 202.5683, 0, 0, 0, 89.81712, 0, 0), Rad_Difusa_.mW.m2. = c(0, 
242.6785, 0, 0, 0, 684.0059, 0, 0, 0, 241.5686, 0, 0), Angulo_zenital_.º. = c(180, 
56.681, 180, 180, 180, 56.431, 180, 180, 180, 56.176, 180, 180 
), blank = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), 
    fecha = structure(c(1453874400, 1453896000, 1453917600, 1453939200, 
    1453960800, 1453982400, 1454004000, 1454025600, 1454047200, 
    1454068800, 1454054400, 1454112000), tzone = "UTC", class = c("POSIXct", 
    "POSIXt"))), row.names = c(NA, -12L), .Names = c("fecha.hora", 
"latitud", "longitud", "altitud", "cobertura_nubosa", "longitud_de_onda_inicial.nm.", 
"Rad_Global_.mW.m2.", "Rad_Directa_.mW.m2.", "Rad_Difusa_.mW.m2.", 
"Angulo_zenital_.º.", "blank", "fecha"), class = "data.frame") 

góry dzięki.

+0

Nie jestem naprawdę skuteczny, ale może mógłbyś stworzyć podzbiór regionów, które chciałbyś (ponownie) pokolorować, a następnie dodać geom_line (dane = podzbiór ....) lub utworzyć dodatkową kolumnę w bieżącym zestawie danych, który przypisz kolor dla niektórych regionów, które chcesz pokolorować inaczej – MLavoie

+1

Możesz sprawdzić [Warunkowe kolorowanie geom_smooth] (http://stackoverflow.com/questions/32908222/conditional-colouring-of-a-geom-smooth/ 32911114 # 32911114). Będziesz musiał dostosować warunek koloru ('color = y> 0') zgodnie z twoimi przerwami i 'zająć się' y = 0 ... – Henrik

Odpowiedz

7

Oblicz wygładzenie poza ggplot2 a następnie użyć geom_segment:

fit <- loess(Rad_Global_.mW.m2. ~ as.numeric(fecha), data = datos.uvi, span = 0.3) 
#note the warnings 

new.x <- seq(from = min(datos.uvi$fecha), 
      to = max(datos.uvi$fecha), 
      by = "5 min") 

new.y <- predict(fit, newdata = data.frame(fecha = as.numeric(new.x))) 


DF <- data.frame(x1 = head(new.x, -1), x2 = tail(new.x, -1) , 
       y1 = head(new.y, -1), y2 = tail(new.y, -1)) 
DF$col <- cut(DF$y1, c(-Inf, 250, 500, Inf)) 


ggplot(data=DF, aes(x=x1, y=y1, xend = x2, yend = y2, colour=col)) + 
    geom_segment(size = 2) 

resulting plot

Zobacz, co dzieje się w punktach cięcia. Jeśli może być bardziej atrakcyjne wizualnie, aby x-siatka dla przewidywania bardzo dobrze, a następnie użyj geom_point zamiast tego. Jednak wykreślenie będzie wtedy powolne.

+1

Dzięki @Roland bardzo blisko tego, czego potrzebuję, dostosowanie x-siatki i zmniejszenie rozmiaru segmentu działa dobrze – pacomet

4

To nie jest to, o co prosiłeś, ale może służyć temu samemu celowi: zamiast kolorować linię, pokoloruj tło. Najpierw tworzymy ramkę danych prostokąta/ograniczenia współrzędnych.

rect_data <- data.frame(xmin=min(datos.uvi$fecha), 
          xmax=max(datos.uvi$fecha), 
          ymin=c(0,250,500), 
          ymax=c(250,500,max(datos.uvi$Rad_Global_.mW.m2.)), 
          col=c("red","green","blue")) 

Następnie dodać je do fabuły, używając scale_fill_identity()

ggplot(data=datos.uvi) + 
    geom_smooth(aes(x=fecha, y=Rad_Global_.mW.m2.),colour="black",se=FALSE, span=0.3) + 
    geom_rect(data=rect_data, aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax,fill=col),alpha=0.1)+ 
    scale_fill_identity() 

enter image description here

+0

Hi @heroka, chociaż nie do końca to, czego potrzebuję, to bardzo dobre podejście to daje ten sam rezultat. Przyjąłem odpowiedź Rolanda, ale twoja zasługuje na bycie selekcyjną. Dzięki – pacomet

+1

Bez obaw, odpowiedź Rolands jest lepsza i odpowiada na faktyczne pytanie. Jest to bardziej "tutaj jest inny sposób na rozwiązanie większego problemu zamiast rozwiązania mniejszego problemu" - odpowiedź. – Heroka