Gambar beberapa plot pada satu grafik di R?


13

Dengan menggunakan kode berikut, saya mencoba menggambar empat plot pada grafik R. Saya tidak senang dengan gambar tersebut karena ada banyak ruang di antara plot, oleh karena itu lebar plot tidak cukup memadai untuk menganalisis plot.

  1. Bisakah seseorang membantu saya menghasilkan grafik yang bagus dengan empat plot?

  2. Bagaimana saya bisa menjaga label sumbu x dari 1 hingga 10 bukan 5 label default?

Data:

a1: 11.013 13.814 13.831 13.714 13.787 13.734 13.778 13.771 13.823 13.659

a2: 5.181 7.747 8.314 8.061 7.920 8.153 8.540 8.845 7.881 8.301

Saya telah menggunakan data a1 untuk b1, c1, dan d1; a2 data untuk b2, c2, dan d2 hanya untuk di sini.

Angka:

masukkan deskripsi gambar di sini

Kode:

        op=par(mfrow=c(4,1), mar=c(5.5,5.1,4.1,2.1))
        plot(a1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="A")
        lines(a2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
        par(xpd=T)
        legend(1,26.5,c("X","Y"),bty="n",horiz=T,cex=1.5,col=c("red1","darkblue"),text.col=c("red1","darkblue"),pch=c(1,3),lty=c(2,3),x.intersp=0.4,adj=0.2)
        plot(b1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="B")
        lines(b2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
        plot(c1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="C")
        lines(c2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
        plot(d1/1000, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="D")
        lines(d2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
   > mtext("Price", side=2, at=100,line=3,cex=1.1)

1
bisakah Anda memberikan detail data Anda? mungkin, dput (data_from_r)
suncoolsu

@suncoolsu, saya telah memperbarui pertanyaan dengan sampel data. Terima kasih.
samarasa

Bagaimana jika Anda memiliki 2 warna dan 4 jenis garis pada sumbu yang sama dengan legenda? Saya ingin melihat kode dan hasil untuk itu.
Paul

@ user87: Karena 4 plot berasal dari 4 percobaan yang berbeda. Karena itu, saya pikir lebih baik menggambar 4 plot untuk menganalisis hasil dari eksperimen.
samarasa

@ user87, saya tidak yakin apa yang Anda maksud. Mungkin jika Anda memulai pertanyaan baru seseorang akan menjawabnya (saya akan :))
Brandon Bertelsen

Jawaban:


16

Jika Anda ingin tetap menggunakan sesuatu seperti metode yang telah Anda gunakan maka Anda mungkin ingin mempelajari perintah tata letak (). Beberapa perubahan detail lainnya dan Anda bisa mendapatkan grafik lebih dekat bersama. Anda juga bisa memasukkan hal-hal unik yang berubah di antara grafik dalam daftar (seperti data dan margin) dan kemudian melalui loop. Juga, Anda akan perhatikan saya membuat sumbu bawah dengan perintah direct axis () sehingga Anda dapat mengontrol ke mana barang-barang itu pergi.

layout(matrix(1:5, ncol = 1), widths = 1,
        heights = c(1,5,5,5,7), respect = FALSE)
par(mar=c(0, 4, 0, 0))
plot(1, type = 'n', axes = FALSE, bty = 'n', ylab = '')
legend('left', , c("X","Y"), bty="n", horiz=T, cex=1.5, col=c("red1","darkblue"), text.col=c("red1","darkblue"), pch=c(1,3), lty=c(2,3), x.intersp=0.4,adj=0.2)
par(mar=c(0, 4, 2, 1), bty = 'o')
plot(a1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2, lwd=2.5, col="red1", lty=2, pch=1, main="A")
lines(a2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
par(xpd=T)
plot(b1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="B")
lines(b2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
plot(c1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="C")
lines(c2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
par(mar=c(4, 4, 2, 1))
plot(d1/1000, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="D")
lines(d2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
mtext("Price", side=2, at=40,line=2.5,cex=1.1)
axis(1, 1:10, cex.axis = 1.4)

jalan cerita

Saya harus mencatat bahwa saya benar-benar tidak berusaha membuat ini sebaik yang saya bisa dan alih-alih membuat grafik tiruan pertama saya bisa saja mengatur ruang yang cukup di frame pertama. Sayangnya pengaturan mar () mencoba untuk mengisi bingkai dan margin atas mempengaruhi jarak label di atas grafik sehingga saya harus pergi dan membuat semua label saya dengan mtext () atau teks () alih-alih hanya menggunakan pengaturan utama dalam plot dan saya tidak merasa ingin melakukan itu


kedua +1 untuk grafis basis badass. Saya telah mencoba dengan sia-sia untuk menulis sesuatu yang bagus dengan perintah layout (). Saya akan kembali ke sini lain kali saya harus menggunakannya.
Chris Beeley

13

Saya akan merekomendasikan mempelajari paket grafik kisi. Saya bisa mendekati apa yang Anda inginkan dengan beberapa baris. Pertama, kemas data Anda dalam bingkai data, sesuatu seperti ini:

dat <- data.frame (x=rep (1:10, 8), y=c(a1, a2, b1, b2, c1, c2, d1, d2),
        var=factor (rep (c("X", "Y"), each=10)),
        graph=factor (rep (c("A", "B", "C", "D"), each=20)))

yang menghasilkan:

    x           y var graph
1   1 0.556372979   X     A
2   2 0.754257646   X     A
3   3 0.815432905   X     A
4   4 0.559513013   X     A
5   5 0.763368168   X     A
6   6 0.426415259   X     A
7   7 0.597962532   X     A
8   8 0.723780143   X     A
9   9 0.228920116   X     A
10 10 0.607378894   X     A
11  1 0.865114425   Y     A
12  2 0.919804947   Y     A
13  3 0.437003794   Y     A
14  4 0.203349303   Y     A
15  5 0.620425977   Y     A
16  6 0.703170299   Y     A
17  7 0.174297656   Y     A
18  8 0.698144659   Y     A
19  9 0.732527016   Y     A
20 10 0.778057398   Y     A
21  1 0.355583032   X     B
22  2 0.015765144   X     B
23  3 0.315004753   X     B
24  4 0.257723585   X     B
25  5 0.506324279   X     B
26  6 0.028634427   X     B
27  7 0.475360443   X     B
28  8 0.577119754   X     B
29  9 0.709063777   X     B
30 10 0.308695235   X     B
31  1 0.852567748   Y     B
32  2 0.938889121   Y     B
33  3 0.080869739   Y     B
34  4 0.732318482   Y     B
35  5 0.325673156   Y     B
36  6 0.378161864   Y     B
37  7 0.830962248   Y     B
38  8 0.990504039   Y     B
39  9 0.331377188   Y     B
40 10 0.448251682   Y     B
41  1 0.967255983   X     C
42  2 0.722894624   X     C
43  3 0.039523960   X     C
44  4 0.003774719   X     C
45  5 0.218605160   X     C
46  6 0.722304874   X     C
47  7 0.576140686   X     C
48  8 0.108219812   X     C
49  9 0.258440127   X     C
50 10 0.739656846   X     C
51  1 0.528278201   Y     C
52  2 0.104415716   Y     C
53  3 0.966076056   Y     C
54  4 0.504415150   Y     C
55  5 0.655384900   Y     C
56  6 0.247340395   Y     C
57  7 0.193857228   Y     C
58  8 0.019133583   Y     C
59  9 0.799404908   Y     C
60 10 0.159209090   Y     C
61  1 0.422574508   X     D
62  2 0.823192614   X     D
63  3 0.808715876   X     D
64  4 0.770499188   X     D
65  5 0.049138399   X     D
66  6 0.747017767   X     D
67  7 0.239916970   X     D
68  8 0.152777362   X     D
69  9 0.052862276   X     D
70 10 0.937605577   X     D
71  1 0.850112019   Y     D
72  2 0.675407232   Y     D
73  3 0.273276166   Y     D
74  4 0.455995477   Y     D
75  5 0.695497498   Y     D
76  6 0.688414035   Y     D
77  7 0.454013633   Y     D
78  8 0.874853452   Y     D
79  9 0.568746031   Y     D

Lalu, gunakan kisi-kisi xyplot:

library (lattice)
xyplot (y ~ x | graph, groups=var, data=dat, type="o",
        layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price")

yang menghasilkan grafik yang bagus seperti:

masukkan deskripsi gambar di sini

EDIT:

Jika Anda ingin memiliki simbol dan garis yang berbeda dan memiliki itu muncul dalam legenda Anda, itu menjadi rumit, karena Anda benar-benar membangun legenda sendiri, dan Anda harus tahu cara mendapatkan warna kisi default jika Anda tidak menimpanya sendiri :

my.text <- levels (dat$var)
my.lty <- c(2, 3)
my.pch <- c(1, 2)
my.col <- trellis.par.get ("superpose.symbol")$col[1:2]
xyplot (y ~ x | graph, groups=var, data=dat, type="o", pch=my.pch, lty=my.lty,
        main="Main Title", layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price",
        key=list (columns=2, text=list (my.text), points=list (pch=my.pch, col=my.col)))

masukkan deskripsi gambar di sini

EDIT 2:

Anda dapat menyederhanakan kode dan grafik, jika dua kategori benar-benar sesederhana "X" dan "Y":

xyplot (y ~ x | graph, groups=var, data=dat, type="o", pch=c("X", "Y"), cex=1.25, lty=c(2, 3),
        layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price")

yang akan menggunakan "X" dan "Y" sebagai simbol titik. Anda tidak perlu legenda sama sekali, dan kemudian dapat mencurahkan lebih banyak ruang untuk grafik itu sendiri. (Di sisi lain, Anda mungkin tidak suka tampilan, atau mungkin merasa lebih sulit untuk menentukan pusat titik yang tepat, meskipun itu tidak menjadi masalah karena mungkin karena garis melewati setiap titik.)

EDIT 3:

Sebenarnya, Anda harus menambahkan strip=F, strip.left=T,plot, untuk menempatkan label A, B, C, D, di sebelah kiri grafik, yang memberi Anda lebih banyak ruang pada grafik panjang seperti ini:

xyplot (y ~ x | graph, groups=var, data=dat, type="o", pch=my.pch, lty=my.lty,
        main="Main Title", layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price",
        strip.left=T, strip=F,
        key=list (columns=2, text=list (my.text), points=list (pch=my.pch, col=my.col),
        lines=list (lty=my.lty, col=my.col)))

masukkan deskripsi gambar di sini


@Wayne: Saya mencoba menjaga legenda di atas grafik menggunakan auto.key dengan spasi = "top", pch = c (1,2), argumen lty = c (2,4), tetapi nilai pch dan nilai lty tidak berfungsi. Selain itu, saya ingin menjaga X dan Y sebagai horizontal dalam legenda. Bisakah Anda membantu saya untuk ini?
samarasa

Iya. Saya perlu menggunakan nilai pch yang berbeda untuk membedakan X dan Y di atas kertas. Saya dapat menggunakan nilai pch yang berbeda dalam plot dengan menambahkan argumen pch (1,4) ke xyplot, tetapi tidak mencerminkan legenda. Tolong beritahu saya bagaimana saya bisa menggunakan nilai pch berbeda untuk X dan Y dalam legenda.
samarasa

OK, saya menemukan jawabannya begitu saya sampai di rumah dan membaca buku itu. Lihat versi yang diedit.
Wayne

Tidak masalah. Saya pikir EDIT 3 saya memberi Anda grafik terbaik yang mirip dengan (tapi lebih tampan dan dengan lebih banyak ruang grafik daripada) asli Anda. Saya tidak menggerakkan legenda, yang menurut saya cukup mudah. Jika Anda ingin agar garis melewati titik dalam legenda, saya pikir Anda harus membawanya ke tingkat kompleksitas berikutnya dan melakukan draw.key hal-hal yang membuat grob kustom ( gridhal: kisi dan ggplot2 build on grid) .
Wayne

Yap, sekarang grafiknya lebih baik. Namun, akan sangat bagus jika kita mendapatkan poin melewati garis dalam legenda seperti yang kita dapatkan dengan fungsi plot normal.
samarasa

9

Berikut adalah versi ggplot2solusi @ Brandon yang menggabungkan perilaku legenda yang diinginkan:

dat <- data.frame (x=rep (1:10, 8), y=runif(80),
        var=factor (rep (c("X", "Y"), each=10)),
        graph=factor (rep (c("A", "B", "C", "D"), each=20)))

ggplot(data = dat,aes(x = x, y = y)) + 
    facet_wrap(~graph,nrow = 4) + 
    geom_point(aes(shape = var)) + 
    geom_line(aes(colour = var, group = var)) + 
    labs(x = NULL, y = NULL, shape = "", colour = "") + 
    theme_bw() + 
    opts(legend.position = "top", legend.direction = "horizontal")

masukkan deskripsi gambar di sini

Saya menemukan legenda menjadi jauh lebih mudah ggplot2, tetapi YMMV.

EDIT

Mengatasi beberapa pertanyaan di komentar. Untuk menentukan titik atau garis tertentu jenis, Anda akan menggunakan scale_aesthetic_manualmana aestheticyang baik shape, linetype, dll Misalnya:

ggplot(data = dat,aes(x = x, y = y)) + 
    facet_wrap(~graph,nrow = 4) + 
    geom_point(aes(shape = var)) + 
    geom_line(aes(colour = var, linetype = var, group = var)) + 
    labs(x = NULL, y = NULL, shape = "", colour = "", linetype = "") + 
    scale_shape_manual(values = 4:5) +
    theme_bw() + 
    opts(legend.position = "top", legend.direction = "horizontal")

Mengubah ukuran berbagai label sumbu dilakukan dengan mengubah pengaturan pada tema, biasanya menggunakan opts(). Contohnya:

ggplot(data = dat,aes(x = x, y = y)) + 
    facet_wrap(~graph,nrow = 4) + 
    geom_point(aes(shape = var)) + 
    geom_line(aes(colour = var, linetype = var, group = var)) + 
    labs(x = "X Label", y = "Y Label", shape = "", colour = "", linetype = "") + 
    theme_bw() + 
    opts(legend.position = "top", legend.direction = "horizontal",
         axis.text.x = theme_text(size = 15),axis.title.y = theme_text(size = 25, angle = 90))

Anda harus benar-benar masuk ke situs web dan bukunya untuk informasi lebih lanjut.


2
Saya sering lebih suka ggplot2. Sebenarnya saya membuat percobaan cepat dengan ggplot2 ketika kisi menjadi terlalu kompleks, dan menemukan bahwa saya tidak bisa mendapatkan legenda untuk mencerminkan gaya titik / garis dengan benar jika saya ingin memilih bentuk dan gaya garis secara eksplisit. Saya mungkin melakukannya dengan cara yang salah, dan berhasil bekerja dalam grafik, tetapi menipu legenda penciptaan ggplot. Bisakah Anda melihat apakah itu bekerja untuk Anda dan memposting kode?
Wayne

@Joran: Saya mencoba mencari cara untuk mengubah linetypes dan pointtypes, dan warna, tetapi tidak berhasil. Bisakah Anda memberi tahu kami bagaimana kami dapat mengubah linetypes, dll. Dan tolong beri tahu kami bagaimana kami dapat meningkatkan ukuran laboratorium x dan y.
samarasa

Saya sedang menggunakan telepon saya saat ini; jika @Brandon tidak mengedit jawabannya sebelum saya pulang dengan apa yang Anda cari, saya akan membahasnya nanti malam.
joran

8

Mirip dengan jawaban Wayne, saya juga akan menggunakan paket yang berbeda, yaitu ggplot2

library(ggplot2) 

df <- data.frame(
parameter=runif(300),
Time=1:300,
split=sample(c(1:4),300,replace=T),
split2=sample(c(1:2),300,replace=T)
)

ggplot(df, aes(Time, parameter, colour=as.factor(split2))) + 
geom_line() + 
facet_wrap(~split,nrow=4)

Yang memberi kita bagan seperti:

masukkan deskripsi gambar di sini


1
Saya suka kisi-kisi di ggplot, tetapi apakah ada cara untuk mematikan latar belakang abu-abu terang?
bluepole

1
+ opts(panel.background=theme_blank())
Brandon Bertelsen

1
Jika Anda ingin membuat perubahan lain, Anda bisa mengetik theme_get()untuk melihat apa yang bisa Anda ubah. Kemudian ikuti pola yang sama dengan komentar terakhir saya, mengaturnya=theme_blank()
Brandon Bertelsen

2
Saya akan melakukan ggplot2 sendiri, tetapi berpikir mungkin kisi akan menjadi langkah yang lebih mudah. Salah satu menyediakan cara terstruktur untuk menumpuk grafik seperti ini. Membuat banyak detail mungkin sulit, tetapi mendapatkan sesuatu yang menarik dan dapat dibaca dengan cepat itu mudah. (Meskipun Anda harus membungkus kepala Anda dengan membuat kerangka data yang tepat untuk membuat grafik data, alih-alih hanya melemparkan barang ke dalam grafik.
Wayne

Saya telah menemukan bahwa Hadley telah menyediakan alat manipulasi data dalam paket lainnya untuk memijat data ke dalam bentuk yang tepat. Ketika ragu biasanya jawabannya,melt()
Brandon Bertelsen
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.