Bagaimana cara menumpuk dua grafik secara vertikal dengan skala x yang sama, tetapi skala y berbeda dalam R?

9

Salam pembuka,

Saat ini saya sedang melakukan hal berikut di 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))

Cuplikan dari 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
...

Dua baris terakhir memplot informasi yang saya butuhkan, dan hasilnya menyerupai yang berikut: teks alternatif Garis biru adalah entropi dalam byte artefak yang saya minati. Garis hijau mewakili entropi perubahan.

Sekarang, dalam grafik ini, ini berfungsi dengan baik karena tidak ada perbedaan besar dalam skala. Tapi saya punya grafik lain di mana garis hijau menjadi sangat kecil sehingga tidak bisa dilihat.

Solusi yang saya cari, melibatkan dua hal:

  1. Untuk memindahkan garis vertikal hijau ke grafik kedua, tepat di bawah yang pertama, dengan sumbu y sendiri, tetapi berbagi sumbu x.
  2. Untuk memberikannya skala logaritmik, karena saya lebih tertarik pada "besarnya", daripada nilai-nilai tertentu.

Terima kasih sebelumnya!

NB Jika seseorang juga dapat memberi tahu saya bagaimana saya bisa menempatkan "kutu kecil" dalam skala x mengacu pada bulan, saya menghargai :-) Jika ini terlalu banyak pertanyaan untuk satu posting, saya dapat membaginya lebih lanjut.

Hugo Sereno Ferreira
sumber

Jawaban:

15

Anda dapat menggunakan par(new=TRUE)untuk memplot ke grafik yang sama menggunakan dua sumbu y yang berbeda! Ini juga harus menyelesaikan masalah Anda.

Selanjutnya Anda akan menemukan contoh sederhana yang memplot dua variabel normal acak, satu rata-rata 0 satu lainnya rata-rata 100 (keduanya sd s = 1) dalam plot yang sama. Yang pertama berwarna merah di sumbu y kiri, yang kedua berwarna biru di sumbu y kanan. Kemudian, label sumbu ditambahkan.

Ini dia:

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)

kelihatannya seperti ini (ingat merah pada sumbu kiri, biru pada sumbu kanan): teks alternatif

UPDATE:
Berdasarkan komentar saya menghasilkan versi terbaru dari grafik saya. Sekarang saya menggali sedikit lebih dalam ke fungsi grafik dasar menggunakan par(mar=c(a,b,c,d))untuk membuat margin yang lebih besar di sekitar grafik (diperlukan untuk label sumbu kanan), mtextuntuk menunjukkan label sumbu dan dan penggunaan lanjutan dari axisfungsi:

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)

teks alternatif

Seperti yang Anda lihat, itu cukup lurus ke depan. Anda dapat menentukan posisi data Anda dengan ylimdalam plotfungsi, kemudian gunakan atdalam axisfungsi untuk memilih sumbu yang ingin Anda lihat. Selain itu, Anda bahkan dapat memberikan label untuk kutu sumbu (cukup berguna untuk nominal x-axis) melalui labelsdalam axisfungsi (dilakukan di sini pada sumbu kanan). Untuk menambahkan label sumbu, gunakan mtextdengan atuntuk penentuan posisi vertikal ( lineuntuk penentuan posisi horizontal).

Pastikan untuk memeriksa ?plot, ?par, ?axis, dan ?mtextuntuk info lebih lanjut.
Sumber daya web yang luar biasa adalah: Quick-R untuk Grafik: 1 , 2 , dan 3 .

Henrik
sumber
Itu menarik, tetapi bagaimana kita memberi tahu pembaca skala mana yang sesuai dengan baris mana?
Hugo Sereno Ferreira
Lihatlah grafik ini: imgur.com/K8BCr.png Di sana, kami menyajikan label sumbu y dan centang hanya di mana mereka berlaku untuk data (yaitu, untuk sumbu kiri di bagian atas grafik, sebagai data yang sesuai, dan untuk sumbu kanan di bagian bawah grafik, sebagai data correspoding). Selain itu, kami menggunakan warna yang berbeda (seperti pada contoh di atas) dan jenis garis dan menjelaskannya dalam keterangan. Anda juga bisa menggunakan bagan garis di sebelah kiri dan bagan batang di sumbu kanan untuk membuat perbedaan lebih jelas.
Henrik
Contoh yang Anda berikan sangat baik ... Bagaimana Anda berhasil mengimbangi setiap sumbu secara vertikal?
Hugo Sereno Ferreira
2
Contoh yang sangat bagus. Satu-satunya masalah dengan grafik Anda, adalah bahwa kedua nama variabel Y tumpang tindih. Dalam hal ini Anda ingin satu di sebelah kiri dan yang lain di sebelah kanan (bahkan mungkin dalam posisi vertikal). Untuk memutakhirkan contoh Anda dari "sangat bagus" menjadi "sempurna", Anda mungkin ingin menggunakan fungsi mtext dari R untuk melakukan nama variabel
Dave Kellen
@Hugo @Dave: Lihat pembaruan saya untuk penggabungan kedua komentar.
Henrik
12

Saya pikir Anda bisa mendapatkan apa yang ingin Anda gunakan ggplot2. Dengan menggunakan kode di bawah ini, saya dapat menghasilkan:

teks alternatif

Jelas hal-hal seperti warna garis dapat diubah ke apa yang Anda inginkan. Pada sumbu x saya menentukan garis besar pada tahun dan garis kecil pada bulan.

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
csgillespie
sumber
Eh, saya mencoba mengatur df = data.frame (t = hari, nilai = c (data2, cum), ketik = rep (c ("Bytes", "Changes"), masing-masing = 1001)), tetapi memberikan Kesalahan di rbind.zoo (...): indexes overlap
Hugo Sereno Ferreira
Itu karena data2 dan cum adalah objek kebun binatang. Gunakan as.vector (data2) untuk mendapatkan nilai mentah. Juga, saya menggunakan 1001 karena saya memiliki 1001 pengamatan. Anda akan membutuhkan sesuatu yang berbeda.
csgillespie
Pengguna Noob R di sini: Kesalahan dalam data.frame (t = hari, nilai = c (as.vector (data2), as.vector (cum)),: argumen menyiratkan perbedaan jumlah baris: 1063, 1300, 2
Hugo Sereno Ferreira
Ketik "days", "data2" dan "cum" untuk melihat data Anda. Kemudian lihat "panjang (hari)", dll. Anda harus mencocokkan titik waktu dengan nilai.
csgillespie