Plot dua grafik dalam plot yang sama di R

571

Saya ingin memplot y1 dan y2 dalam plot yang sama.

x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x, 1, 1)
plot(x, y1, type = "l", col = "red")
plot(x, y2, type = "l", col = "green")

Tetapi ketika saya melakukannya seperti ini, mereka tidak diplot dalam plot yang sama.

Di Matlab orang dapat melakukannya hold on, tetapi apakah ada yang tahu bagaimana melakukan ini di R?

Sandra Schlichting
sumber
3
Lihat ?curve. Gunakan add=TRUE.
isomorphismes
Lihat pertanyaan ini untuk jawaban ggplot2 yang lebih spesifik.
Axeman

Jawaban:

617

lines()atau points()akan menambah grafik yang ada, tetapi tidak akan membuat jendela baru. Jadi, Anda harus melakukannya

plot(x,y1,type="l",col="red")
lines(x,y2,col="green")
bnaul
sumber
10
Mengapa itu tidak bekerja dalam contoh sederhana berikut ini? > plot (sin)> lines (cos) Galat di as.double (y): tidak bisa memaksa ketik 'builtin' ke vektor tipe 'double'
Frank
23
Ini mudah dilihat. Dengan plot (sin), Anda melewati fungsi alih-alih data aktual. plot () akan mendeteksi ini dan pada gilirannya menggunakan plot.function () untuk merencanakan fungsi Anda (baca beberapa pengiriman untuk mempelajari lebih lanjut tentang ini). Namun, lines.function () tidak didefinisikan, jadi lines () tidak tahu apa yang harus dilakukan dengan parameter fungsi kelas. garis hanya dapat menangani data dan objek deret waktu Anda dari kelas ts.
Soumendra
27
@Frank Do itu seperti ini: plot(sin); curve(cos, add=TRUE).
isomorfisma
2
Bagaimana cara menggunakan yang sama jika x berbeda? Katakanlah, saya memiliki x1 dan y1 untuk satu grafik dan menambahkan grafik lain dari x2 dan y2 dalam grafik yang sama. Baik x1 dan x2 memiliki rentang yang sama tetapi nilai yang berbeda.
Kavipriya
1
Persis sama: lines(x2,y2,...)bukannyalines(x,y2,...)
bnaul
220

Anda juga dapat menggunakan pardan memplot pada grafik yang sama tetapi sumbu yang berbeda. Sesuatu sebagai berikut:

plot( x, y1, type="l", col="red" )
par(new=TRUE)
plot( x, y2, type="l", col="green" )

Jika Anda membaca secara terperinci tentang parin R, Anda akan dapat menghasilkan grafik yang sangat menarik. Buku lain untuk dilihat adalah R Graphics milik Paul Murrel.

Sam
sumber
3
R saya memberi saya kesalahan: Kesalahan di par (fig (new = TRUE)): tidak dapat menemukan fungsi "fig"
Alessandro Jacopson
5
Apakah metode Anda mempertahankan skala yang tepat (sumbu y) untuk kedua plot?
Alessandro Jacopson
1
@uvts_cvs Ya, ini mempertahankan grafik asli di toto.
Sam
10
Masalahnya adalah ini akan menulis ulang beberapa elemen plot. Saya akan memasukkan xlab="", ylab="", ...dan beberapa orang lain dalam yang kedua plot.
isomorfisma
118

Ketika membangun plot multilayer, seseorang harus mempertimbangkan ggplotpaket. Idenya adalah untuk membuat objek grafis dengan estetika dasar dan meningkatkannya secara bertahap.

ggplotstyle membutuhkan data untuk dikemas data.frame.

# Data generation
x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x,1,1)
df <- data.frame(x,y1,y2)

Solusi dasar:

require(ggplot2)

ggplot(df, aes(x)) +                    # basic graphical object
  geom_line(aes(y=y1), colour="red") +  # first layer
  geom_line(aes(y=y2), colour="green")  # second layer

Di sini + operatordigunakan untuk menambahkan lapisan tambahan ke objek dasar.

Dengan ggplotAnda memiliki akses ke objek grafis pada setiap tahap merencanakan. Katakanlah, pengaturan langkah-demi-langkah yang biasa dapat terlihat seperti ini:

g <- ggplot(df, aes(x))
g <- g + geom_line(aes(y=y1), colour="red")
g <- g + geom_line(aes(y=y2), colour="green")
g

gmenghasilkan plot, dan Anda bisa melihatnya di setiap tahap (baik, setelah pembuatan setidaknya satu lapisan). Pesona plot selanjutnya juga dibuat dengan objek yang dibuat. Misalnya, kita dapat menambahkan label untuk sumbu:

g <- g + ylab("Y") + xlab("X")
g

Final gterlihat seperti:

masukkan deskripsi gambar di sini

UPDATE (2013-11-08):

Sebagaimana ditunjukkan dalam komentar, ggplotfilosofi menyarankan menggunakan data dalam format panjang. Anda dapat merujuk ke jawaban ini untuk melihat kode yang sesuai.

redmode
sumber
5
Seperti yang disarankan oleh Henrik , data harus dalam format "panjang", ggplotmenangani ini lebih alami daripada format "lebar" yang Anda gunakan.
krlmlr
1
@ Henrik: Tidak, terima kasih atas jawaban Anda di tempat pertama. Mungkin pengarang jawaban ini dapat mengeditnya sehingga cocok dengan ggplotfilosofi ...
krlmlr
1
@ krlmlr, saya mencoba mengedit jawaban saya sehingga menjawab pertanyaan dengan lebih eksplisit. Silakan menyarankan pembaruan lebih lanjut. Bersulang.
Henrik
3
mengajari saya mendefinisikan x pada ggplot (aes ()) dan kemudian y dengan sendirinya di geom _ * (). Bagus!
Dan
41

Saya pikir jawaban yang Anda cari adalah:

plot(first thing to plot)
plot(second thing to plot,add=TRUE)
pengguna3749764
sumber
25
Ini sepertinya tidak berhasil, itu memberi "add" is not a graphical parameterperingatan kemudian hanya mencetak plot kedua dari yang pertama.
Waldir Leoncio
8
@WaldirLeoncio lihat stackoverflow.com/questions/6789055/…
Alessandro Jacopson
Satu manfaat bagus dari hal ini adalah tampaknya menjaga agar sumbu dan batas tetap konsisten. Beberapa metode sebelumnya menyebabkan R untuk menggambar dua set tanda centang pada sumbu y, kecuali jika Anda mengalami kesulitan menentukan lebih banyak opsi. Tak perlu dikatakan, memiliki dua set tanda centang pada kapak bisa sangat menyesatkan.
RMurphy
1
parameter add berfungsi untuk beberapa metode plot, tetapi bukan base / default di R
cloudscomputes
2
Saya mendapat kesalahan yang sama "add" is not a graphical parameter. R saya R version 3.2.3 (2015-12-10). Anda bisa menggunakan par(new=TRUE)perintah di antara plot-plot ini.
quepas
29

Gunakan matplotfungsinya:

matplot(x, cbind(y1,y2),type="l",col=c("red","green"),lty=c(1,1))

gunakan ini jika y1dan y2dievaluasi pada xtitik yang sama . Ini skala sumbu Y agar sesuai dengan mana yang lebih besar ( y1atau y2), tidak seperti beberapa jawaban lain di sini yang akan klip y2jika semakin besar dari y1(solusi ggplot sebagian besar tidak masalah dengan ini).

Atau, dan jika kedua garis tidak memiliki koordinat x yang sama, tetapkan batas sumbu pada plot pertama dan tambahkan:

x1  <- seq(-2, 2, 0.05)
x2  <- seq(-3, 3, 0.05)
y1 <- pnorm(x1)
y2 <- pnorm(x2,1,1)

plot(x1,y1,ylim=range(c(y1,y2)),xlim=range(c(x1,x2)), type="l",col="red")
lines(x2,y2,col="green")

Terkejut Q ini berumur 4 tahun dan tidak ada yang menyebutkan matplotatau x/ylim...

Spacedman
sumber
25

tl; dr: Anda ingin menggunakan curve(dengan add=TRUE) atau lines.


Saya tidak setuju par(new=TRUE)karena itu akan mencetak dua kali tanda centang dan label sumbu. Misalnya

sinus dan parabola

Output dari plot(sin); par(new=T); plot( function(x) x**2 ).

Lihat betapa kacau label sumbu vertikal! Karena rentangnya berbeda, Anda perlu menyetelnya ylim=c(lowest point between the two functions, highest point between the two functions), yang tidak semudah yang akan saya tunjukkan kepada Anda --- dan jauh lebih mudah jika Anda ingin menambahkan bukan hanya dua kurva, tetapi banyak.


Apa yang selalu membingungkan saya tentang merencanakan adalah perbedaan antara curvedan lines. (Jika Anda tidak dapat mengingat bahwa ini adalah nama-nama dari dua perintah plot yang penting, cukup nyanyikan ini.)

Inilah perbedaan besar antara curvedanlines .

curveakan merencanakan fungsi, seperti curve(sin). linesplot poin dengan nilai x dan y, seperti:lines( x=0:10, y=sin(0:10) ) .

Dan inilah perbedaan kecil: curveperlu dipanggil dengan add=TRUEapa yang Anda coba lakukan, sementara linessudah mengasumsikan Anda menambahkan ke plot yang ada.

id & sinus

Inilah hasil dari panggilan plot(0:2); curve(sin) .


Di belakang layar, periksa methods(plot). Dan periksa body( plot.function )[[5]]. Ketika Anda memanggil plot(sin)angka R yang sinmerupakan fungsi (bukan nilai y) dan menggunakan plot.functionmetode, yang akhirnya memanggil curve. Begitu curvejuga alat yang dimaksudkan untuk menangani fungsi.

isomorfisma
sumber
17

jika Anda ingin membagi plot menjadi dua kolom (2 plot bersebelahan), Anda dapat melakukannya seperti ini:

par(mfrow=c(1,2))

plot(x)

plot(y) 

Tautan Referensi

Hamed2005
sumber
16

Seperti dijelaskan oleh @redmode, Anda dapat memplot dua baris dalam perangkat grafis yang sama menggunakan ggplot. Dalam jawaban itu datanya dalam format 'lebar'. Namun, saat menggunakannya ggplotumumnya paling mudah untuk menyimpan data dalam bingkai data dalam format 'panjang'. Kemudian, dengan menggunakan berbagai 'pengelompokan variabel' diaes argumen tesis, sifat-sifat garis, seperti linetype atau warna, akan bervariasi sesuai dengan variabel pengelompokan, dan legenda yang sesuai akan muncul.

Dalam hal ini, kita dapat menggunakan colouraessthetics, yang mencocokkan warna garis ke berbagai tingkat variabel dalam kumpulan data (di sini: y1 vs y2). Tetapi pertama-tama kita perlu mencairkan data dari format lebar ke panjang, menggunakan misalnya fungsi 'melt' dari reshape2paket. Metode lain untuk membentuk kembali data dijelaskan di sini: Membentuk kembali data.frame dari format lebar ke panjang .

library(ggplot2)
library(reshape2)

# original data in a 'wide' format
x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x, 1, 1)
df <- data.frame(x, y1, y2)

# melt the data to a long format
df2 <- melt(data = df, id.vars = "x")

# plot, using the aesthetics argument 'colour'
ggplot(data = df2, aes(x = x, y = value, colour = variable)) + geom_line()

masukkan deskripsi gambar di sini

Henrik
sumber
15

Jika Anda menggunakan grafik dasar (yaitu bukan grafik kisi / grid), maka Anda dapat meniru fitur MATLAB pada fitur dengan menggunakan fungsi titik / garis / poligon untuk menambahkan rincian tambahan ke plot Anda tanpa memulai plot baru. Dalam hal tata letak banyak tempat, Anda dapat menggunakan par(mfg=...)untuk memilih plot mana yang Anda tambahkan.

mcabral
sumber
14

Anda dapat menggunakan poin untuk overplot, yaitu.

plot(x1, y1,col='red')

points(x2,y2,col='blue')
bertukar pikiran
sumber
7

Daripada menjaga nilai-nilai yang akan diplot dalam array, simpan nilai-nilai itu dalam matriks. Secara default seluruh matriks akan diperlakukan sebagai satu set data. Namun, jika Anda menambahkan jumlah pengubah yang sama ke plot, misalnya col (), seperti Anda memiliki baris dalam matriks, R akan mengetahui bahwa setiap baris harus diperlakukan secara independen. Sebagai contoh:

x = matrix( c(21,50,80,41), nrow=2 )
y = matrix( c(1,2,1,2), nrow=2 )
plot(x, y, col("red","blue")

Ini akan berfungsi kecuali set data Anda memiliki ukuran yang berbeda.

cranberi
sumber
Ini memberikan: Kesalahan dalam if (as.factor) {: argumen tidak dapat ditafsirkan sebagai logis
baouss
5

Matlab idiomatis plot(x1,y1,x2,y2)dapat diterjemahkan dalam R dengan ggplot2misalnya dengan cara ini:

x1 <- seq(1,10,.2)
df1 <- data.frame(x=x1,y=log(x1),type="Log")
x2 <- seq(1,10)
df2 <- data.frame(x=x2,y=cumsum(1/x2),type="Harmonic")

df <- rbind(df1,df2)

library(ggplot2)
ggplot(df)+geom_line(aes(x,y,colour=type))

masukkan deskripsi gambar di sini

Terinspirasi oleh Tingting Zhao plot garis ganda dengan kisaran sumbu x yang berbeda Menggunakan ggplot2 .

Alessandro Jacopson
sumber
5

Anda dapat menggunakan ggplotly()fungsi dari paket plotly untuk mengubah salah satu contoh gggplot2 di sini menjadi plot interaktif, tapi saya pikir plot semacam ini lebih baik tanpa ggplot2 :

# call Plotly and enter username and key
library(plotly)
x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x, 1, 1)

plot_ly(x = x) %>%
  add_lines(y = y1, color = I("red"), name = "Red") %>%
  add_lines(y = y2, color = I("green"), name = "Green")

masukkan deskripsi gambar di sini

Mateo Sanchez
sumber
plotly terlihat cemerlang; ini gratis ?
denis
@denis, ada plot publik gratis yang tak terbatas dan plot pribadi berbayar atau opsi di tempat. Lihat halaman paket .
Mateo Sanchez
4
Paket R plotly sekarang 100% gratis dan open source (berlisensi MIT). Anda dapat menggunakannya dengan atau tanpa akun plotly.
Carson
4

Anda juga dapat membuat plot menggunakan ggvis :

library(ggvis)

x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x,1,1)
df <- data.frame(x, y1, y2)

df %>%
  ggvis(~x, ~y1, stroke := 'red') %>%
  layer_paths() %>%
  layer_paths(data = df, x = ~x, y = ~y2, stroke := 'blue')

Ini akan membuat plot berikut:

masukkan deskripsi gambar di sini

epo3
sumber
2

Menggunakan plotly(menambahkan solusi dari plotlydengan sumbu y primer dan sekunder- Tampaknya tidak ada):

library(plotly)     
x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x, 1, 1)

df=cbind.data.frame(x,y1,y2)

  plot_ly(df) %>%
    add_trace(x=~x,y=~y1,name = 'Line 1',type = 'scatter',mode = 'lines+markers',connectgaps = TRUE) %>%
    add_trace(x=~x,y=~y2,name = 'Line 2',type = 'scatter',mode = 'lines+markers',connectgaps = TRUE,yaxis = "y2") %>%
    layout(title = 'Title',
       xaxis = list(title = "X-axis title"),
       yaxis2 = list(side = 'right', overlaying = "y", title = 'secondary y axis', showgrid = FALSE, zeroline = FALSE))

Tangkapan layar dari demo kerja:

masukkan deskripsi gambar di sini

Saurabh Chauhan
sumber
Saya mengkompilasi kode dan tidak berfungsi, pertama menandai kesalahan dalam%>% dan saya menghapusnya, lalu menandai kesalahan Error in library(plotly) : there is no package called ‘plotly’mengapa?
Bellatrix
Sudahkah Anda menginstal paket plotly? Anda perlu menginstal paket menggunakan install.packages("plotly")perintah.
Saurabh Chauhan
1

kita juga bisa menggunakan pustaka kisi

library(lattice)
x <- seq(-2,2,0.05)
y1 <- pnorm(x)
y2 <- pnorm(x,1,1)
xyplot(y1 + y2 ~ x, ylab = "y1 and y2", type = "l", auto.key = list(points = FALSE,lines = TRUE))

Untuk warna tertentu

xyplot(y1 + y2 ~ x,ylab = "y1 and y2", type = "l", auto.key = list(points = F,lines = T), par.settings = list(superpose.line = list(col = c("red","green"))))

masukkan deskripsi gambar di sini

Varn K
sumber