Ответ 1
lines()
или points()
добавит существующий граф, но не создаст новое окно. Поэтому вам нужно будет сделать
plot(x,y1,type="l",col="red")
lines(x,y2,col="green")
Я хотел бы построить y1 и y2 в том же сюжете.
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")
Но когда я делаю это так, они не строятся в одном сюжете вместе.
В Matlab можно сделать hold on
, но кто-нибудь знает, как это сделать в R?
lines()
или points()
добавит существующий граф, но не создаст новое окно. Поэтому вам нужно будет сделать
plot(x,y1,type="l",col="red")
lines(x,y2,col="green")
Вы также можете использовать par
и график на одном и том же графике, но с другой осью. Что-то следующее:
plot( x, y1, type="l", col="red" )
par(new=TRUE)
plot( x, y2, type="l", col="green" )
Если вы подробно читаете о par
в R
, вы сможете создавать действительно интересные графики. Еще одна книга, на которую стоит обратить внимание - это Графика Пола Меррела R.
При построении многослойных графиков следует рассмотреть пакет ggplot
. Идея состоит в том, чтобы создать графический объект с базовой эстетикой и увеличить его постепенно.
ggplot
требует, чтобы данные были упакованы в data.frame
.
# Data generation
x <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x,1,1)
df <- data.frame(x,y1,y2)
Основное решение:
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
Здесь + operator
используется для добавления дополнительных слоев к базовому объекту.
С ggplot
у вас есть доступ к графическому объекту на каждом этапе построения графика. Скажем, обычная пошаговая настройка может выглядеть так:
g <- ggplot(df, aes(x))
g <- g + geom_line(aes(y=y1), colour="red")
g <- g + geom_line(aes(y=y2), colour="green")
g
g
создает график, и вы можете видеть его на каждом этапе (ну, после создания хотя бы одного слоя). Дальнейшие чары сюжета также сделаны с созданным объектом. Например, мы можем добавить метки для осей:
g <- g + ylab("Y") + xlab("X")
g
Финал g
выглядит следующим образом:
ОБНОВЛЕНИЕ (2013-11-08):
Как указано в комментариях, философия ggplot
предполагает использование данных в длинном формате.
Вы можете обратиться к этому ответу fooobar.com/questions/16926/..., чтобы увидеть соответствующий код.
Я думаю, что ответ, который вы ищете, это:
plot(first thing to plot)
plot(second thing to plot,add=TRUE)
Используйте функцию matplot
:
matplot(x, cbind(y1,y2),type="l",col=c("red","green"),lty=c(1,1))
используйте это, если y1
и y2
оцениваются в тех же точках x
. Он масштабирует ось Y, чтобы соответствовать тому, что больше (y1
или y2
), в отличие от некоторых других ответов здесь, которые будут обрезать y2
, если он станет больше, чем y1
(решения ggplot в основном согласуются с этим).
В качестве альтернативы, и если две линии не имеют одинаковых x-координат, задайте границы оси на первом графике и добавьте:
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")
Я удивлен, что этому Q 4 года, и никто не упомянул matplot
или x/ylim
...
tl; dr: Вы хотите использовать curve
(с add=TRUE
) или lines
.
Я не согласен с par(new=TRUE)
, потому что это будет двойной печать меток и меток осей. Например,
Вывод plot(sin); par(new=T); plot( function(x) x**2 )
.
Посмотрите, как перепутаны метки вертикальной оси! Поскольку диапазоны различны, вам нужно установить ylim=c(lowest point between the two functions, highest point between the two functions)
, что менее просто, чем то, что я собираюсь показать вам, - и еще проще, если вы хотите добавить не только две кривые, но и многие другие.
Что всегда меня путало в построении, это разница между curve
и lines
. (Если вы не можете вспомнить, что это имена двух важных команд построения, просто петь его.)
curve
и lines
. curve
построит функцию, такую как curve(sin)
. lines
указывает точки с значениями x и y, например: lines( x=0:10, y=sin(0:10) )
.
И здесь незначительная разница: curve
нужно вызвать с помощью add=TRUE
для того, что вы пытаетесь сделать, а lines
уже предполагает, что вы добавляете к существующему сюжету.
Здесь результат вызова plot(0:2); curve(sin)
.
За кулисами посмотрите methods(plot)
. И проверьте body( plot.function )[[5]]
. Когда вы вызываете plot(sin)
R, выясняется, что sin
является функцией (а не значениями y) и использует метод plot.function
, который заканчивается вызовом curve
. Таким образом, curve
- это инструмент, предназначенный для обработки функций.
Как описано в @redmode, вы можете построить две линии в одном графическом устройстве, используя ggplot
. В этом ответе данные были в "широком" формате. Однако при использовании ggplot
как правило, наиболее удобно хранить данные в фрейме данных в "длинном" формате. Затем, используя различные "переменные группировки" в аргументах aes
thetics, свойства линии, такие как тип линии или цвет, будут меняться в зависимости от переменной группировки, и будут появляться соответствующие легенды.
В этом случае мы можем использовать эстетику colour
, которая сопоставляет цвет линий с различными уровнями переменной в наборе данных (здесь: y1 против y2). Но сначала нам нужно расплавить данные из широкого в длинный формат, используя, например, функцию 'melt' из пакета reshape2
. Другие методы изменения данных описаны здесь: Изменение формы data.frame из широкого в длинный формат.
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()
Если вы используете базовую графику (т.е. не решетчатую/сетчатую графику), то вы можете имитировать функцию удерживания MATLAB, используя функции точек/линий/полигонов, чтобы добавить дополнительные детали к вашим сюжетам, не запустив новый график. В случае макета мультипликации вы можете использовать par(mfg=...)
для выбора сюжета, в который вы добавляете.
если вы хотите разделить экран, вы можете сделать это следующим образом:
(например, для двух графиков рядом)
par(mfrow=c(1,2))
plot(x)
plot(y)
Вы можете использовать точки для надстройки, то есть.
plot(x1, y1,col='red')
points(x2,y2,col='blue')
Вместо сохранения значений, которые должны быть построены в массиве, сохраните их в матрице. По умолчанию вся матрица будет рассматриваться как один набор данных. Однако, если вы добавите к графику столько же модификаторов, как, например, col(), поскольку у вас есть строки в матрице, R будет определять, что каждая строка должна обрабатываться независимо. Например:
x = matrix( c(21,50,80,41), nrow=2 )
y = matrix( c(1,2,1,2), nrow=2 )
plot(x, y, col("red","blue")
Это должно работать, если ваши наборы данных не имеют разного размера.
Идиоматический plot(x1,y1,x2,y2)
Matlab plot(x1,y1,x2,y2)
можно перевести в R с помощью ggplot2
например, следующим образом:
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))
Вдохновлен Tingting Zhao Двойные линейные графики с различным диапазоном оси X Использование ggplot2.
Вы также можете создать свой сюжет, используя 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')
Это создаст следующий график:
Вы можете использовать ggplotly()
из пакета plotly, чтобы превратить любой из приведенных здесь примеров gggplot2 в интерактивный график, но я думаю, что этот тип графика лучше без 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")
мы также можем использовать решетку библиотеки
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))
Для конкретных цветов
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"))))
Использование plotly
(добавление решения из plotly
с первичным и вторичным y axis- Кажется, что отсутствует):
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))
Скриншот из рабочего демо: