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

485

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

  • 1
    Проверьте ?curve . Используйте add=TRUE .
  • 0
    Смотрите этот вопрос для более конкретных ответов ggplot2.
Теги:
ggplot2
plot
r-faq

16 ответов

548
Лучший ответ

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

plot(x,y1,type="l",col="red")
lines(x,y2,col="green")
  • 9
    Почему это не работает в следующем простом примере? > plot (sin)> lines (cos) Ошибка в as.double (y): невозможно привести тип 'builtin' к вектору типа 'double'
  • 22
    Это легко увидеть. С помощью plot (sin) вы передаете функцию вместо фактических данных. plot () обнаружит это и, в свою очередь, использует plot.function () для построения вашей функции (прочитайте о нескольких рассылках, чтобы узнать больше об этом). Однако lines.function () не определена, поэтому lines () не знает, что делать с параметром функции класса. линии могут иметь дело только с вашими данными и объектами временного ряда класса ts.
Показать ещё 7 комментариев
179

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

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

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

  • 3
    Мой R выдает ошибку: Ошибка в параметре (рис. (Новый = ИСТИНА)): не удалось найти функцию «рис.»
  • 5
    Сохраняет ли ваш метод правильный масштаб (ось Y) для двух графиков?
Показать ещё 3 комментария
96

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

Изображение 4280

ОБНОВЛЕНИЕ (2013-11-08):

Как указано в комментариях, философия ggplot предполагает использование данных в длинном формате. Вы можете обратиться к этому ответу https://stackoverflow.com/questions/2564258/plot-two-graphs-in-same-plot-in-r, чтобы увидеть соответствующий код.

  • 5
    Как предположил Хенрик , данные действительно должны быть в «длинном» формате, ggplot обрабатывает это более естественно, чем «широкий» формат, который вы используете.
  • 1
    @Henrik: Нет, спасибо за ваш ответ в первую очередь. Возможно, автор этого ответа сможет отредактировать его так, чтобы он хорошо ggplot философию ggplot ...
Показать ещё 2 комментария
34

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

plot(first thing to plot)
plot(second thing to plot,add=TRUE)
  • 21
    Кажется, это не работает, это дает "add" is not a graphical parameter предупреждение о "add" is not a graphical parameter а просто печатает второй график поверх первого.
  • 7
    @WaldirLeoncio, см. Stackoverflow.com/questions/6789055 / ...
Показать ещё 3 комментария
25

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

22

tl; dr: Вы хотите использовать curveadd=TRUE) или lines.


Я не согласен с par(new=TRUE), потому что это будет двойной печать меток и меток осей. Например,

Изображение 4281

Вывод 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 уже предполагает, что вы добавляете к существующему сюжету.

Изображение 4282

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


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

16

Как описано в @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()

Изображение 4283

15

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

14

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

(например, для двух графиков рядом)

par(mfrow=c(1,2))

plot(x)

plot(y) 

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

10

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

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

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

5

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

Изображение 4284

Вдохновлен Tingting Zhao Двойные линейные графики с различным диапазоном оси X Использование ggplot2.

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

Это создаст следующий график:

Изображение 4285

3

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

Изображение 4286

  • 0
    сюжетно выглядит блестяще; это бесплатно ?
  • 0
    @denis, есть неограниченные бесплатные публичные заговоры и платные частные заговоры или локальные варианты. Смотрите страницу планов .
Показать ещё 1 комментарий
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"))))

Изображение 4287

0

Использование 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))

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

Изображение 4288

Ещё вопросы

Сообщество Overcoder
Наверх
Меню