Постройте два графика на одном графике в R

Я хотел бы построить 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?


person Sandra Schlichting    schedule 01.04.2010    source источник
comment
Проверьте ?curve. Используйте add=TRUE.   -  person isomorphismes    schedule 14.03.2015
comment
См. этот вопрос для получения более подробной информации. ggplot2 ответы.   -  person Axeman    schedule 24.07.2018


Ответы (16)


lines() или points() добавит к существующему графику, но не создаст новое окно. Итак, вам нужно сделать

plot(x,y1,type="l",col="red")
lines(x,y2,col="green")
person bnaul    schedule 01.04.2010
comment
Почему это не работает в следующем простом примере? ›Plot (sin)› lines (cos) Ошибка в as.double (y): невозможно привести тип builtin к вектору типа double - person Frank; 05.06.2013
comment
Это легко увидеть. С plot (sin) вы передаете функцию вместо фактических данных. plot () обнаружит это и, в свою очередь, использует plot.function () для построения вашей функции (прочтите о множественной отправке, чтобы узнать больше об этом). Однако lines.function () не определен, поэтому lines () не знает, что делать с параметром функции класса. lines могут иметь дело только с вашими данными и объектами временных рядов класса ts. - person Soumendra; 09.07.2013
comment
@Frank Сделай это так: plot(sin); curve(cos, add=TRUE). - person isomorphismes; 14.03.2015
comment
Как использовать то же самое, если x другое? Скажем, у меня есть x1 и y1 для одного графика и я добавляю еще один график x2 и y2 в тот же график. И x1, и x2 имеют одинаковый диапазон, но разные значения. - person Kavipriya; 21.10.2015
comment
Точно так же: lines(x2,y2,...) вместо lines(x,y2,...) - person bnaul; 21.10.2015
comment
Как проще всего добавить к этому легенду? - person hertzsprung; 06.01.2016
comment
Можете ли вы использовать 2 разных масштаба по оси Y для линий? - person NurShomik; 08.08.2017
comment
Можно ли заставить R масштабировать размеры графика по отношению к y1 и y2 без ручного написания минимального / максимального / предельного значения? - person SOFe; 17.11.2018
comment
Есть ли способ назначить график и линии переменной без использования ggplot? - person Nonancourt; 28.08.2019

Вы также можете использовать par и построить график на том же графике, но на другой оси. Что-то вроде следующего:

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

Если вы подробно прочитаете о par в R, вы сможете создавать действительно интересные графики. Еще одна книга, на которую стоит обратить внимание, - это R Graphics Пола Мюррела.

person Community    schedule 18.02.2011
comment
Мой R выдает ошибку: Ошибка в par (fig (new = TRUE)): не удалось найти функцию fig - person Alessandro Jacopson; 28.06.2011
comment
Сохраняет ли ваш метод правильный масштаб (ось Y) для двух графиков? - person Alessandro Jacopson; 05.06.2012
comment
@uvts_cvs Да, он сохраняет исходный график в целом. - person Sam; 23.09.2012
comment
Проблема в том, что при этом будут перезаписаны несколько элементов сюжета. Я бы включил xlab="", ylab="", ... и несколько других во второй plot. - person isomorphismes; 19.11.2013
comment
не могли бы вы взглянуть на мой вопрос, если у вас будет время? stackoverflow.com/questions/65650991/ спасибо - person stats555; 11.01.2021

При построении многослойных участков следует учитывать пакет 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 выглядит так:

введите описание изображения здесь

ОБНОВЛЕНИЕ (08.11.2013):

Как указано в комментариях, философия ggplot предлагает использовать данные в длинном формате. Вы можете обратиться к этому ответу, чтобы увидеть соответствующий код.

person redmode    schedule 27.01.2013
comment
Как предложил Хенрик, данные действительно должны быть в длинном формате, ggplot обрабатывает это более естественно, чем используемый вами широкий формат. - person krlmlr; 27.09.2013
comment
@Henrik: Нет, прежде всего спасибо за ваш ответ. Возможно, автор этого ответа может отредактировать его, чтобы он хорошо соответствовал философии ggplot ... - person krlmlr; 27.09.2013
comment
научил меня определять x на ggplot (aes ()), а затем y отдельно на geom _ * (). Отлично! - person Dan; 07.03.2017

Я думаю, что ответ, который вы ищете:

plot(first thing to plot)
plot(second thing to plot,add=TRUE)
person user3749764    schedule 17.06.2014
comment
Кажется, это не работает, выдает "add" is not a graphical parameter предупреждение, а затем просто печатает второй график поверх первого. - person Waldir Leoncio; 26.08.2014
comment
@WaldirLeoncio см. stackoverflow.com/questions/6789055/ - person Alessandro Jacopson; 07.10.2014
comment
Одним из приятных преимуществ этого является то, что кажется, что пределы осей и названия остаются неизменными. Некоторые из предыдущих методов заставляют R рисовать два набора делений на оси y, если вы не зададите дополнительные параметры. Излишне говорить, что наличие двух наборов делений на осях может ввести в заблуждение. - person RMurphy; 16.02.2017
comment
параметр add работает для некоторых методов построения графиков, но не для базового / стандартного в R - person cloudscomputes; 12.10.2017
comment
У меня такая же ошибка "add" is not a graphical parameter. Мой R R version 3.2.3 (2015-12-10). Вы можете использовать команду par(new=TRUE) между этими графиками. - person quepas; 13.11.2017

Используйте функцию 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 или _12 _...

person Spacedman    schedule 18.08.2014
comment
Здесь особенно полезна функция range (). - person JASC; 09.07.2021

tl; dr: вы хотите использовать curveadd=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 уже предполагает, что вы добавляете к существующему сюжету.

id & sine

Вот результат вызова plot(0:2); curve(sin).


За кадром посмотрите methods(plot). И проверьте body( plot.function )[[5]]. Когда вы вызываете plot(sin), R выясняет, что sin является функцией (а не значениями y) и использует метод plot.function, который вызывает curve. Итак, curve - это инструмент, предназначенный для обработки функций.

person isomorphismes    schedule 14.03.2015

если вы хотите разбить график на две колонки (2 графика рядом друг с другом), вы можете сделать это следующим образом:

par(mfrow=c(1,2))

plot(x)

plot(y) 

Ссылка на ссылку

person Hamed2005    schedule 21.10.2014

Как описано в @redmode, вы можете построить две линии на одном и том же графическом устройстве, используя ggplot. В этом ответе данные были в «широком» формате. Однако при использовании ggplot, как правило, удобнее всего хранить данные во фрейме данных в «длинном» формате. Затем, используя различные «группирующие переменные» в аргументах aesthetics, свойства линии, такие как тип линии или цвет, будут варьироваться в зависимости от переменной группировки, и появятся соответствующие легенды.

В этом случае мы можем использовать colour эстетику, которая сопоставляет цвет линий с разными уровнями переменной в наборе данных (здесь: y1 vs y2). Но сначала нам нужно преобразовать данные из широкого формата в длинный, используя, например, функция "расплав" из пакета 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()

введите описание изображения здесь

person Henrik    schedule 26.09.2013

Если вы используете базовую графику (то есть не решетчатую / сеточную графику), то вы можете имитировать функцию удержания MATLAB, используя функции точек / линий / полигонов, чтобы добавить дополнительные детали к вашим графикам без запуска нового графика. В случае многослойного макета вы можете использовать par(mfg=...), чтобы выбрать, на какой график вы добавляете объекты.

person mcabral    schedule 01.04.2010

То есть вы можете использовать точки для перекрытия сюжета.

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

points(x2,y2,col='blue')
person brainstorm    schedule 21.10.2012

Вместо того, чтобы хранить значения для построения графика в массиве, сохраните их в матрице. По умолчанию вся матрица будет рассматриваться как один набор данных. Однако, если вы добавите к сюжету такое же количество модификаторов, например 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")

Это должно работать, если только ваши наборы данных не различаются по размеру.

person cranberry    schedule 02.07.2012
comment
Это дает: Ошибка в if (as.factor) {: аргумент не интерпретируется как логический - person baouss; 07.05.2019

Вы можете использовать функцию 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")

введите описание изображения здесь

person Mateo Sanchez    schedule 22.01.2014
comment
сюжетно смотрится блестяще; это бесплатно ? - person denis; 02.06.2015
comment
@denis, есть неограниченное количество бесплатных публичных и платных частных или локальных возможностей. См. страницу планов. - person Mateo Sanchez; 04.06.2015
comment
Пакет plotly R теперь полностью бесплатен и имеет открытый исходный код (под лицензией MIT). Вы можете использовать его как с аккаунтом, так и без него. - person Carson; 07.01.2019
comment
не могли бы вы взглянуть на мой вопрос? stackoverflow.com/questions/65650991/ спасибо! - person stats555; 11.01.2021

Идиоматический 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))

введите описание изображения здесь

На основе двухлинейных графиков с различным диапазоном оси X с использованием ggplot2.

person Alessandro Jacopson    schedule 26.02.2018

Вы также можете создать свой график с помощью 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')

Это создаст следующий сюжет:

введите описание изображения здесь

person epo3    schedule 25.01.2017

Использование plotly (добавление решения из plotly с первичной и вторичной осью y - кажется, отсутствует):

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

Скриншот из рабочей демонстрации:

введите здесь описание изображения

person Saurabh Chauhan    schedule 01.02.2019
comment
Я скомпилировал код и не работает, сначала пометил ошибку в% ›% и удалил, потом пометил ошибку Error in library(plotly) : there is no package called ‘plotly’ почему? - person user9802913; 12.06.2019
comment
Вы установили пакет plotly? Вам необходимо установить пакет с помощью команды install.packages("plotly"). - person Saurabh Chauhan; 13.06.2019

мы также можем использовать решетчатую библиотеку

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

введите здесь описание изображения

person Varn K    schedule 25.09.2018