Jak ustawić pionowo dwa wykresy o tej samej skali x, ale innej skali Y w R?


9

Pozdrowienia,

Obecnie wykonuję następujące czynności w języku R:

require(zoo)
data <- read.csv(file="summary.csv",sep=",",head=TRUE)
cum  = zoo(data$dcomp, as.Date(data$date))
data = zoo(data$compressed, as.Date(data$date))
data <- aggregate(data, identity, tail, 1)
cum  <- aggregate(cum, identity, sum, 1)
days = seq(start(data), end(data), "day")
data2 = na.locf(merge(data, zoo(,days)))

plot(data2,xlab='',ylab='compressed bytes',col=rgb(0.18,0.34,0.55))
lines(cum,type="h",col=rgb(0,0.5,0))

Snip of summary.csv:

date,revision,file,lines,nclass,nattr,nrel,bytes,compressed,diff,dcomp
2007-07-25,16,model.xml,96,11,22,5,4035,991,0,0
2007-07-27,17,model.xml,115,16,26,6,4740,1056,53,777
2007-08-09,18,model.xml,106,16,26,7,4966,1136,47,761
2007-08-10,19,model.xml,106,16,26,7,4968,1150,4,202
2007-09-06,81,model.xml,111,16,26,7,5110,1167,13,258
...

Ostatnie dwa wiersze przedstawiają potrzebne informacje, a wynik przypomina: alternatywny tekst Niebieska linia to entropia w bajtach artefaktu, który mnie interesuje. Zielone linie reprezentują entropię zmian.

Teraz na tym wykresie działa dobrze, ponieważ nie ma ogromnej różnicy w skalach. Ale mam inne wykresy, na których zielone linie stają się tak małe, że nie widać.

Rozwiązanie, którego szukałem, obejmowało dwie rzeczy:

  1. Aby przenieść zielone pionowe linie na drugi wykres, tuż poniżej pierwszego, z własną osią y, ale wspólną osią x.
  2. Aby zapewnić skalę logarytmiczną, ponieważ bardziej interesuje mnie „wielkość” niż określone wartości.

Z góry dziękuję!

PS Jeśli ktoś może mi również powiedzieć, jak mogę umieścić „drobne tiki” w skali X w odniesieniu do miesięcy, doceniam :-) Jeśli są to zbyt wiele pytań do jednego postu, mogę je dalej podzielić.

Odpowiedzi:


15

Możesz użyć par(new=TRUE)do wykreślenia na tym samym wykresie przy użyciu dwóch różnych osi Y! To powinno również rozwiązać twój problem.

Następnie znajdziesz prosty przykład, który wykreśla dwie losowe zmienne normalne, jedną na średniej 0, drugą na średniej 100 (oba sd s = 1) na tym samym wykresie. Pierwszy na czerwono na lewej osi y, drugi na niebiesko na prawej osi y. Następnie dodaje się etykiety osi.

Proszę bardzo:

x <- 1:10
y1 <- rnorm(10)
y2 <- rnorm(10)+100

plot(x,y1,pch=0,type="b",col="red",yaxt="n",ylim=c(-8,2))
par(new=TRUE)
plot(x,y2,pch=1,type="b",col="blue",yaxt="n",ylim=c(98,105))

axis(side=2)
axis(side=4)

wygląda wtedy tak (pamiętaj czerwony na lewej osi, niebieski na prawej osi): alternatywny tekst

AKTUALIZACJA:
Na podstawie komentarzy stworzyłem zaktualizowaną wersję mojego wykresu. Teraz zagłębiam się nieco w funkcjonalność wykresu bazowego, używając par(mar=c(a,b,c,d))do stworzenia większego marginesu wokół wykresu (potrzebnego do etykiety prawej osi), mtextaby wyświetlić etykiety osi i zaawansowane użycie axisfunkcji:

x <- 1:100
y1 <- rnorm(100)
y2 <- rnorm(100)+100

par(mar=c(5,5,5,5))

plot(x,y1,pch=0,type="b",col="red",yaxt="n",ylim=c(-8,2),ylab="")
axis(side=2, at=c(-2,0,2))
mtext("red line", side = 2, line=2.5, at=0)

par(new=TRUE)
plot(x,y2,pch=1,type="b",col="blue",yaxt="n",ylim=c(98,108), ylab="")
axis(side=4, at=c(98,100,102), labels=c("98%","100%","102%"))
mtext("blue line", side=4, line=2.5, at=100)

alternatywny tekst

Jak widać, jest to całkiem proste. Możesz zdefiniować pozycję swoich danych ylimw plotfunkcji, a następnie użyć atw axisfunkcji, aby wybrać, które oś znacznika chcesz zobaczyć. Co więcej, można nawet dostarczyć etykiety dla kleszczy osi (bardzo przydatnych dla nominalnej oś x) poprzez labelsw axisfunkcji (wykonanej tutaj na prawej osi). Aby dodać etykiety osi, użyj mtextz atdo pozycjonowania pionowego ( linedo pozycjonowania poziomego).

Upewnij się, aby sprawdzić ?plot, ?par, ?axis, i ?mtextaby uzyskać więcej informacji.
Świetne zasoby internetowe to: Quick-R dla wykresów: 1 , 2 i 3 .


To ciekawe, ale jak powiedzieć czytelnikowi, która skala odpowiada linii?
Hugo Sereno Ferreira

Spójrz na ten wykres: imgur.com/K8BCr.png Tam przedstawiamy etykiety osi Y i znaczniki tylko tam, gdzie odnoszą się do danych (tj. Dla lewej osi u góry wykresu, jako odpowiednie dane, i dla prawej osi u dołu wykresu, jako dane odpowiadające). Dodatkowo zastosowaliśmy różne kolory (jak w powyższym przykładzie) i typy linii i wyjaśniliśmy to w podpisie. Możesz także użyć wykresu liniowego po lewej stronie i wykresu słupkowego na prawej osi, aby rozróżnić wyraźniej.
Henrik

Podany przykład jest bardzo dobry ... Jak udało się przesunąć w pionie każdą oś?
Hugo Sereno Ferreira

2
Naprawdę dobry przykład. Jedynym problemem związanym z wykresem jest to, że obie nazwy zmiennych Y nakładają się. W tym przypadku chciałbyś jeden po lewej, a drugi po prawej (być może nawet w pozycji pionowej). Aby zmienić swój przykład z „naprawdę dobrego” na „doskonały”, możesz użyć funkcji mtext z R do tworzenia nazw zmiennych
Dave Kellen

@ Hugo @Dave: Zobacz moją aktualizację zawierającą oba komentarze.
Henrik

12

Myślę, że możesz dostać to, czego chcesz ggplot2. Korzystając z poniższego kodu, mogę utworzyć:

alternatywny tekst

Oczywiście rzeczy takie jak kolory linii można zmienić na dowolne. Na osi X określiłem linie główne w latach i linie pomocnicze w miesiącach.

require(ggplot2)
t = as.Date(0:1000, origin="2008-01-01")  
y1 = rexp(1001)
y2 = cumsum(y1)
df = data.frame(t=t, values=c(y2,y1), type=rep(c("Bytes", "Changes"), each=1001))

g = ggplot(data=df, aes(x=t, y=values)) +
  geom_line() +
  facet_grid(type ~ ., scales="free") +
  scale_y_continuous(trans="log10") +
  scale_x_date(major="years", minor="months") +
  ylab("Log values")
g

Próbowałem skonfigurować df = data.frame (t = dni, wartości = c (data2, cum), type = rep (c („Bajty”, „Zmiany”), każdy = 1001)), ale daje Błąd w rbind.zoo (...): indeksy nakładają się
Hugo Sereno Ferreira

To dlatego, że data2 i cum są obiektami zoo. Użyj as.vector (data2), aby uzyskać surowe wartości. Użyłem również 1001, ponieważ miałem 1001 obserwacji. Będziesz potrzebował czegoś innego.
csgillespie

Użytkownik Noob R tutaj: Błąd w ramce danych (t = dni, wartości = c (as.vector (data2), as.vector (cum)),: argumenty wskazują na różną liczbę wierszy: 1063, 1300, 2
Hugo Sereno Ferreira,

Wpisz „dni”, „dane2” i „cum”, aby przejrzeć swoje dane. Następnie spójrz na „długość (dni)” itp. Musisz dopasować punkty czasowe do wartości.
csgillespie
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.