Vẽ hai đồ thị trong cùng một đồ thị trong R


571

Tôi muốn cốt truyện y1 và y2 trong cùng một cốt truyện.

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")

Nhưng khi tôi làm như thế này, chúng không được vẽ trong cùng một cốt truyện.

Trong Matlab người ta có thể làm hold on, nhưng có ai biết làm điều này trong R không?


3
Kiểm tra ?curve. Sử dụng add=TRUE.
đẳng cấu

Xem câu hỏi này để biết câu trả lời ggplot2 cụ thể hơn.
Axeman

Câu trả lời:


617

lines()hoặc points()sẽ thêm vào biểu đồ hiện có, nhưng sẽ không tạo ra một cửa sổ mới. Vì vậy, bạn cần phải làm

plot(x,y1,type="l",col="red")
lines(x,y2,col="green")

10
Tại sao nó không hoạt động trong ví dụ đơn giản sau đây? > âm mưu (sin)> dòng (cos) Lỗi trong as.double (y): không thể ép buộc loại 'dựng sẵn' thành vectơ loại 'kép'
Frank

23
Điều này là dễ thấy. Với cốt truyện (sin), bạn đang truyền một hàm thay vì dữ liệu thực tế. cốt truyện () sẽ phát hiện ra điều này và lần lượt sử dụng cốt truyện Tuy nhiên, lines.function () không được xác định, vì vậy lines () không biết phải làm gì với một tham số của hàm lớp. các dòng chỉ có thể xử lý dữ liệu và các đối tượng chuỗi thời gian của lớp ts.
Soumendra

27
@Frank Làm như thế này : plot(sin); curve(cos, add=TRUE).
đẳng cấu

2
Làm thế nào để sử dụng giống nhau nếu x là khác nhau? Giả sử, tôi có x1 và y1 cho một biểu đồ và thêm một biểu đồ khác của x2 và y2 trong cùng một biểu đồ. Cả x1 và x2 có cùng phạm vi nhưng giá trị khác nhau.
Kavipriya

1
Nó hoàn toàn giống nhau: lines(x2,y2,...)thay vìlines(x,y2,...)
bnaul

220

Bạn cũng có thể sử dụng parvà vẽ đồ thị trên cùng một biểu đồ nhưng trục khác nhau. Một cái gì đó như sau:

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

Nếu bạn đọc một cách chi tiết về partrong R, bạn sẽ có thể tạo các biểu đồ thực sự thú vị. Một cuốn sách khác để xem là Đồ họa R của Paul Murrel.


3
My R cho tôi một lỗi: Lỗi trong mệnh (fig (new = TRUE)): không thể tìm thấy hàm "fig"
Alessandro Jacopson

5
Phương pháp của bạn có bảo toàn đúng tỷ lệ (trục y) cho hai ô không?
Alessandro Jacopson

1
@uvts_cvs Có, nó giữ nguyên biểu đồ gốc trong toto.
Sam

10
Vấn đề với điều này là nó sẽ viết lại một số yếu tố cốt truyện. Tôi sẽ bao gồm xlab="", ylab="", ...và một vài người khác trong thứ hai plot.
đẳng cấu

118

Khi xây dựng các ô đa lớp người ta nên xem xét ggplotgói. Ý tưởng là tạo ra một đối tượng đồ họa với tính thẩm mỹ cơ bản và tăng cường nó dần dần.

ggplotphong cách đòi hỏi dữ liệu được đóng gói trong data.frame.

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

Giải pháp cơ bản:

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

Ở đây + operatorđược sử dụng để thêm các lớp bổ sung cho đối tượng cơ bản.

Với ggplotbạn có quyền truy cập vào đối tượng đồ họa trên mọi giai đoạn của âm mưu. Nói, thiết lập từng bước thông thường có thể trông như thế này:

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

gtạo ra cốt truyện và bạn có thể thấy nó ở mọi giai đoạn (tốt, sau khi tạo ra ít nhất một lớp). Bùa mê tiếp theo của cốt truyện cũng được thực hiện với đối tượng được tạo. Ví dụ: chúng ta có thể thêm nhãn cho các trục:

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

Hình thức cuối cùng gnhư:

nhập mô tả hình ảnh ở đây

CẬP NHẬT (2013-11-08):

Như đã chỉ ra trong các bình luận, ggplottriết lý của đề nghị sử dụng dữ liệu ở định dạng dài. Bạn có thể tham khảo câu trả lời này để xem mã tương ứng.


5
Theo đề xuất của Henrik , dữ liệu thực sự phải ở định dạng "dài", ggplotxử lý việc này một cách tự nhiên hơn định dạng "rộng" mà bạn sử dụng.
krlmlr

1
@Henrik: Không, cảm ơn bạn đã trả lời ngay từ đầu. Có lẽ tác giả của câu trả lời này có thể chỉnh sửa nó để nó rất phù hợp với ggplottriết lý 's ...
krlmlr

1
@krlmlr, tôi đã cố gắng chỉnh sửa câu trả lời của mình để nó giải quyết rõ ràng hơn câu hỏi. Xin vui lòng đề nghị cập nhật thêm. Chúc mừng.
Henrik

3
đã dạy tôi định nghĩa x trên ggplot (aes ()) và sau đó y tự nó trên geom _ * (). Đẹp!
Dan

41

Tôi nghĩ rằng câu trả lời bạn đang tìm kiếm là:

plot(first thing to plot)
plot(second thing to plot,add=TRUE)

25
Điều này dường như không hoạt động, nó đưa ra một "add" is not a graphical parametercảnh báo sau đó chỉ in cốt truyện thứ hai so với cốt truyện thứ nhất.
Waldir Leoncio


Một lợi ích tốt đẹp của điều này là nó dường như giữ cho giới hạn trục và tiêu đề nhất quán. Một số phương pháp trước đó khiến R vẽ hai bộ dấu tick trên trục y, trừ khi bạn gặp rắc rối trong việc chỉ định thêm tùy chọn. Không cần phải nói, có hai bộ dấu tick trên các trục có thể rất sai lệch.
RMurphy

1
tham số add hoạt động cho một số phương thức cốt truyện, nhưng không phải là cơ sở / mặc định trong R
cloudscomputes

2
Tôi đã nhận được cùng một lỗi "add" is not a graphical parameter. R của tôi là R version 3.2.3 (2015-12-10). Bạn có thể sử dụng par(new=TRUE)lệnh giữa các lô này.
quepas

29

Sử dụng matplotchức năng:

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

sử dụng điều này nếu y1y2được đánh giá tại cùng một xđiểm. Nó chia tỷ lệ trục Y để phù hợp với bất kỳ cái nào lớn hơn ( y1hoặc y2), không giống như một số câu trả lời khác ở đây sẽ cắt y2nếu nó lớn hơn y1(các giải pháp ggplot hầu hết đều ổn với điều này).

Ngoài ra, và nếu hai dòng không có cùng tọa độ x, hãy đặt giới hạn trục trên ô đầu tiên và thêm:

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")

Thật ngạc nhiên khi Q này 4 tuổi và không ai nhắc đến matplothay x/ylim...


25

tl; dr: Bạn muốn sử dụng curve(với add=TRUE) hoặc lines.


Tôi không đồng ý par(new=TRUE)vì điều đó sẽ in hai dấu tick và nhãn trục. Ví dụ

sin và parabola

Đầu ra của plot(sin); par(new=T); plot( function(x) x**2 ).

Nhìn làm thế nào lộn xộn các nhãn trục dọc! Vì các phạm vi là khác nhau, bạn sẽ cần phải thiết lập ylim=c(lowest point between the two functions, highest point between the two functions), ít dễ dàng hơn những gì tôi sắp chỉ cho bạn --- và cách dễ dàng hơn nếu bạn muốn thêm không chỉ hai đường cong, mà nhiều.


Điều luôn làm tôi bối rối về âm mưu là sự khác biệt giữa curvelines. (Nếu bạn không thể nhớ rằng đây là tên của hai lệnh vẽ đồ thị quan trọng, hãy hát nó.)

Đây là sự khác biệt lớn giữa curvelines.

curvesẽ vẽ một hàm, như thế nào curve(sin). linesvẽ các điểm với các giá trị x và y, như : lines( x=0:10, y=sin(0:10) ).

Và đây là một sự khác biệt nhỏ: curvecần phải được gọi add=TRUEcho những gì bạn đang cố gắng thực hiện, trong khi linesđã giả định rằng bạn đang thêm vào một cốt truyện hiện có.

id & sin

Đây là kết quả của cuộc gọi plot(0:2); curve(sin).


Đằng sau hậu trường, hãy kiểm tra methods(plot). Và kiểm tra body( plot.function )[[5]]. Khi bạn gọi plot(sin)R hình ra đó sinlà một hàm (không phải giá trị y) và sử dụng plot.functionphương thức, kết thúc cuộc gọi curve. Vì vậy, curvecác công cụ có nghĩa là để xử lý các chức năng.



16

Theo mô tả của @redmode, bạn có thể vẽ hai dòng trong cùng một thiết bị đồ họa bằng cách sử dụng ggplot. Trong câu trả lời đó, dữ liệu ở định dạng 'rộng'. Tuy nhiên, khi sử dụng ggplotthường thuận tiện nhất là giữ dữ liệu trong khung dữ liệu ở định dạng 'dài'. Sau đó, bằng cách sử dụng các 'nhóm biến' khác nhau trongaes đối số của bộ ba, các thuộc tính của dòng, chẳng hạn như linetype hoặc màu, sẽ thay đổi tùy theo biến nhóm và các huyền thoại tương ứng sẽ xuất hiện.

Trong trường hợp này, chúng ta có thể sử dụng colouraessthetic, khớp màu của các dòng với các mức khác nhau của một biến trong tập dữ liệu (ở đây: y1 vs y2). Nhưng trước tiên, chúng ta cần làm tan dữ liệu từ định dạng rộng sang dài, ví dụ như sử dụng hàm 'tan' từ reshape2gói. Các phương pháp khác để định hình lại dữ liệu được mô tả ở đây: Định hình lại data.frame từ định dạng rộng sang dài .

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()

nhập mô tả hình ảnh ở đây


15

Nếu bạn đang sử dụng đồ họa cơ sở (tức là không phải đồ họa lưới / lưới), thì bạn có thể bắt chước tính năng giữ MATLAB bằng cách sử dụng các hàm điểm / đường / đa giác để thêm chi tiết vào các ô của bạn mà không bắt đầu một âm mưu mới. Trong trường hợp bố trí nhiều trang, bạn có thể sử dụng par(mfg=...)để chọn cốt truyện mà bạn thêm vào.


14

Bạn có thể sử dụng điểm cho overplot, đó là.

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

points(x2,y2,col='blue')

7

Thay vì giữ các giá trị được vẽ trong một mảng, hãy lưu trữ chúng trong một ma trận. Theo mặc định, toàn bộ ma trận sẽ được coi là một tập dữ liệu. Tuy nhiên, nếu bạn thêm cùng số lượng công cụ sửa đổi vào cốt truyện, ví dụ col (), khi bạn có các hàng trong ma trận, R sẽ chỉ ra rằng mỗi hàng phải được xử lý độc lập. Ví dụ:

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

Điều này sẽ hoạt động trừ khi bộ dữ liệu của bạn có kích thước khác nhau.


Điều này mang lại: Lỗi trong if (as.factor) {: đối số không thể hiểu là logic
baouss

5

Matlab thành ngữ plot(x1,y1,x2,y2)có thể được dịch bằng R với ggplot2ví dụ theo cách này:

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))

nhập mô tả hình ảnh ở đây

Lấy cảm hứng từ các ô kép của Tingting Zhao với phạm vi trục x khác nhau bằng ggplot2 .


5

Bạn có thể sử dụng ggplotly()chức năng từ plotly gói để biến bất kỳ của gggplot2 ví dụ ở đây thành một cốt truyện tương tác, nhưng tôi nghĩ rằng loại này của cốt truyện là tốt hơn mà không 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")

nhập mô tả hình ảnh ở đây


âm mưu trông rực rỡ; nó có miễn phí không
chối

@denis, có âm mưu công cộng miễn phí không giới hạn và âm mưu riêng được trả tiền hoặc các tùy chọn tại chỗ. Xem trang kế hoạch .
Mateo Sanchez

4
Gói R hoàn toàn hiện miễn phí 100% và nguồn mở (được MIT cấp phép). Bạn có thể sử dụng nó có hoặc không có tài khoản.
Carson

4

Bạn cũng có thể tạo cốt truyện của mình bằng 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')

Điều này sẽ tạo ra cốt truyện sau:

nhập mô tả hình ảnh ở đây


2

Sử dụng plotly(thêm giải pháp từ plotlyvới trục y chính và phụ- Có vẻ như bị thiếu):

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))

Ảnh chụp màn hình từ bản demo làm việc:

nhập mô tả hình ảnh ở đây


Tôi đã biên dịch mã và không hoạt động, đầu tiên đánh dấu lỗi trong%>% và tôi đã xóa nó, sau đó đánh dấu lỗi Error in library(plotly) : there is no package called ‘plotly’tại sao?
Bellatrix

Bạn đã cài đặt gói plotly? Bạn cần cài đặt gói bằng install.packages("plotly")lệnh.
Saurabh Chauhan

1

chúng ta cũng có thể sử dụng thư viện mạng

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))

Đối với màu sắc cụ thể

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"))))

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.