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

572

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

Сандра Шлихтинг
источник
3
Проверьте ?curve. Использование add=TRUE.
изоморфизм
Смотрите этот вопрос для более конкретных ответов ggplot2.
Axeman

Ответы:

618

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

plot(x,y1,type="l",col="red")
lines(x,y2,col="green")
bnaul
источник
10
Почему это не работает в следующем простом примере? > plot (sin)> lines (cos) Ошибка в as.double (y): невозможно привести тип 'builtin' к вектору типа 'double'
Франк
23
Это легко увидеть. С помощью plot (sin) вы передаете функцию вместо фактических данных. plot () обнаружит это и, в свою очередь, использует plot.function () для построения вашей функции (прочитайте о нескольких рассылках, чтобы узнать больше об этом). Однако lines.function () не определена, поэтому lines () не знает, что делать с параметром функции класса. линии могут иметь дело только с вашими данными и объектами временного ряда класса ts.
Soumendra
27
@Frank сделать это следующим образом : plot(sin); curve(cos, add=TRUE).
изоморфизм
2
Как использовать то же самое, если х отличается? Скажем, у меня есть x1 и y1 для одного графика и добавить другой граф x2 и y2 в том же графике. И x1, и x2 имеют одинаковый диапазон, но разные значения.
Кавиприя
1
Это точно так же: lines(x2,y2,...)вместоlines(x,y2,...)
бнаул
220

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

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

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

Sam
источник
3
Мой R дает мне ошибку: Ошибка в номинале (рис. (Новый = ИСТИНА)): не удалось найти функцию «рис.»
Алессандро Якопсон,
5
Сохраняет ли ваш метод правильный масштаб (ось Y) для двух графиков?
Алессандро Якопсон
1
@uvts_cvs Да, он сохраняет исходный график в целом.
Сэм
10
Проблема в том, что он перепишет несколько элементов сюжета. Я бы включил xlab="", ylab="", ...и несколько других во второй plot.
изоморфизм
118

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

redmode
источник
5
Как предположил Хенрик , данные действительно должны быть в «длинном» формате, ggplotобрабатывает это более естественно, чем «широкий» формат, который вы используете.
krlmlr
1
@Henrik: Нет, спасибо за ваш ответ в первую очередь. Возможно, автор этого ответа сможет отредактировать его так, чтобы он хорошо вписывался в ggplotфилософию России ...
krlmlr
1
@krlmlr, я попытался отредактировать свой ответ так, чтобы он более явно отвечал на вопрос. Пожалуйста, не стесняйтесь предлагать дальнейшие обновления. Приветствия.
Хенрик
3
научил меня определять x на ggplot (aes ()), а затем y на geom _ * (). Ницца!
Дан
41

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

plot(first thing to plot)
plot(second thing to plot,add=TRUE)
user3749764
источник
25
Кажется, это не работает, выдает "add" is not a graphical parameterпредупреждение, а затем просто печатает второй график поверх первого.
Вальдир Леонсио
8
@WaldirLeoncio см stackoverflow.com/questions/6789055/...
Алессандро Jacopson
Одним приятным преимуществом этого является то, что он, кажется, поддерживает согласованные пределы осей и названия. Некоторые из предыдущих методов приводят к тому, что R рисует два набора меток на оси y, если только вы не потрудились указать дополнительные параметры. Излишне говорить, что наличие двух наборов отметок на осях может быть очень обманчивым.
RMurphy
1
Параметр add работает для некоторых методов
печати
2
Я получил ту же ошибку "add" is not a graphical parameter. Мой Р есть R version 3.2.3 (2015-12-10). Вы можете использовать par(new=TRUE)команду между этими графиками.
quepas
29

Используйте 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...

Spacedman
источник
25

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участки с точки х и у значений, например: 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же и инструмент, предназначенный для обработки функций.

isomorphismes
источник
17

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

par(mfrow=c(1,2))

plot(x)

plot(y) 

Ссылка Ссылка

Hamed2005
источник
16

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

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

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

Хенрик
источник
15

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

mcabral
источник
14

Вы можете использовать очки за оверплот, то есть.

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

points(x2,y2,col='blue')
мозговой штурм
источник
7

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

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

клюква
источник
Это дает: Ошибка в if (as.factor) {: аргумент не интерпретируется как логический
baouss
5

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

Алессандро Якопсон
источник
5

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

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

Матео Санчес
источник
сюжетно выглядит блестяще; это бесплатно ?
Денис
@denis, есть неограниченные бесплатные публичные заговоры и платные частные заговоры или локальные варианты. Смотрите страницу планов .
Матео Санчес
4
Пакет plotly R теперь на 100% бесплатный и с открытым исходным кодом (по лицензии MIT). Вы можете использовать его с сюжетом или без него.
Карсон
4

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

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

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

epo3
источник
2

Используя 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))

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

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

Саурабх Чаухан
источник
Я скомпилировал код и не работает, сначала пометил ошибку в%>% и удалил ее, затем пометил ошибку Error in library(plotly) : there is no package called ‘plotly’почему?
Беллатрикс
Вы установили пакет plotly? Вам необходимо установить пакет с помощью install.packages("plotly")команды.
Саурабх Чаухан
1

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

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

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

Варн К
источник