Намалюйте кілька графіків на одному графіку в R?


13

Використовуючи наступний код, я спробував намалювати чотири графіки на графіку в R. Я не задоволений фігурою, оскільки між ділянками є багато місця, тому ширина ділянок недостатня для аналізу ділянок.

  1. Може хтось допоможе мені скласти хороший графік, що має чотири сюжети?

  2. Як я можу зберігати мітки осі x від 1 до 10 замість 5 міток за замовчуванням?

Дані:

a1: 11.013 13.814 13.831 13.714 13.787 13.734 13.778 13.771 13.823 13.659

а2: 5,181 7,747 8,314 8,061 7,920 8,153 8,540 8,845 7,881 8,301

Я використав дані a1 для b1, c1 і d1; a2 дані для b2, c2 та d2 лише тут.

Малюнок:

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

Код:

        op=par(mfrow=c(4,1), mar=c(5.5,5.1,4.1,2.1))
        plot(a1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="A")
        lines(a2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
        par(xpd=T)
        legend(1,26.5,c("X","Y"),bty="n",horiz=T,cex=1.5,col=c("red1","darkblue"),text.col=c("red1","darkblue"),pch=c(1,3),lty=c(2,3),x.intersp=0.4,adj=0.2)
        plot(b1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="B")
        lines(b2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
        plot(c1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="C")
        lines(c2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
        plot(d1/1000, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="D")
        lines(d2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
   > mtext("Price", side=2, at=100,line=3,cex=1.1)

1
Ви могли б дати деталі своїх даних? можливо, dput (data_from_r)
suncoolsu

@suncoolsu, я оновив питання із зразком даних. Дякую.
samarasa

Що робити, якщо у вас на одних осях із легендою було 2 кольори та 4 типи ліній? Я хотів би побачити код та результати для цього.
Пол

@ user87: Оскільки 4 сюжети є з 4 різних експериментів. Тому я вважаю, що краще провести 4 сюжети для аналізу результатів експериментів.
samarasa

@ user87, я не впевнений, що ти маєш на увазі. Можливо, якщо ви запустили нове запитання, хтось відповість на нього (я б хотів :))
Брендон Бертелсен

Відповіді:


16

Якщо ви хочете дотримуватися чогось подібного до методу, який ви використовували, ви можете дізнатися команду layout (). Кілька інших деталей змінюються, і ви можете зблизити графіки набагато ближче. Ви також можете помістити в список унікальні речі, що змінюються між графіками (наприклад, дані та поля), а потім пройти цикл. Також ви зауважте, що я зробив нижню вісь командою direct axis (), щоб ви могли контролювати, куди йдуть елементи.

layout(matrix(1:5, ncol = 1), widths = 1,
        heights = c(1,5,5,5,7), respect = FALSE)
par(mar=c(0, 4, 0, 0))
plot(1, type = 'n', axes = FALSE, bty = 'n', ylab = '')
legend('left', , c("X","Y"), bty="n", horiz=T, cex=1.5, col=c("red1","darkblue"), text.col=c("red1","darkblue"), pch=c(1,3), lty=c(2,3), x.intersp=0.4,adj=0.2)
par(mar=c(0, 4, 2, 1), bty = 'o')
plot(a1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2, lwd=2.5, col="red1", lty=2, pch=1, main="A")
lines(a2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
par(xpd=T)
plot(b1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="B")
lines(b2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
plot(c1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="C")
lines(c2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
par(mar=c(4, 4, 2, 1))
plot(d1/1000, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="D")
lines(d2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
mtext("Price", side=2, at=40,line=2.5,cex=1.1)
axis(1, 1:10, cex.axis = 1.4)

сюжет

Слід зазначити, що я дійсно не доклав зусиль, щоб зробити це настільки приємно, як міг, і замість того, щоб зробити перший графік манекена, я міг просто встановити достатньо місця в першому кадрі. На жаль, параметр mar () намагається заповнити кадр, а верхнє поле впливає на відстань, на якій мітка над графіком відсутня, тому мені доведеться пройти і зробити всі мітки з mtext () або text (), а не просто використовувати головна обстановка в сюжеті, і мені не здалося, що це роблять


друге - +1 для базової графіки. Я даремно намагався написати щось приємне за допомогою команди layout (). Я збираюся повернутися сюди наступного разу, коли мені потрібно буде це використати.
Кріс Білі

13

Я рекомендую вивчити гратичний пакет грати. Я можу наблизитися до того, що ви хочете, за допомогою декількох рядків. Спочатку запакуйте свої дані в кадр даних приблизно так:

dat <- data.frame (x=rep (1:10, 8), y=c(a1, a2, b1, b2, c1, c2, d1, d2),
        var=factor (rep (c("X", "Y"), each=10)),
        graph=factor (rep (c("A", "B", "C", "D"), each=20)))

який дає:

    x           y var graph
1   1 0.556372979   X     A
2   2 0.754257646   X     A
3   3 0.815432905   X     A
4   4 0.559513013   X     A
5   5 0.763368168   X     A
6   6 0.426415259   X     A
7   7 0.597962532   X     A
8   8 0.723780143   X     A
9   9 0.228920116   X     A
10 10 0.607378894   X     A
11  1 0.865114425   Y     A
12  2 0.919804947   Y     A
13  3 0.437003794   Y     A
14  4 0.203349303   Y     A
15  5 0.620425977   Y     A
16  6 0.703170299   Y     A
17  7 0.174297656   Y     A
18  8 0.698144659   Y     A
19  9 0.732527016   Y     A
20 10 0.778057398   Y     A
21  1 0.355583032   X     B
22  2 0.015765144   X     B
23  3 0.315004753   X     B
24  4 0.257723585   X     B
25  5 0.506324279   X     B
26  6 0.028634427   X     B
27  7 0.475360443   X     B
28  8 0.577119754   X     B
29  9 0.709063777   X     B
30 10 0.308695235   X     B
31  1 0.852567748   Y     B
32  2 0.938889121   Y     B
33  3 0.080869739   Y     B
34  4 0.732318482   Y     B
35  5 0.325673156   Y     B
36  6 0.378161864   Y     B
37  7 0.830962248   Y     B
38  8 0.990504039   Y     B
39  9 0.331377188   Y     B
40 10 0.448251682   Y     B
41  1 0.967255983   X     C
42  2 0.722894624   X     C
43  3 0.039523960   X     C
44  4 0.003774719   X     C
45  5 0.218605160   X     C
46  6 0.722304874   X     C
47  7 0.576140686   X     C
48  8 0.108219812   X     C
49  9 0.258440127   X     C
50 10 0.739656846   X     C
51  1 0.528278201   Y     C
52  2 0.104415716   Y     C
53  3 0.966076056   Y     C
54  4 0.504415150   Y     C
55  5 0.655384900   Y     C
56  6 0.247340395   Y     C
57  7 0.193857228   Y     C
58  8 0.019133583   Y     C
59  9 0.799404908   Y     C
60 10 0.159209090   Y     C
61  1 0.422574508   X     D
62  2 0.823192614   X     D
63  3 0.808715876   X     D
64  4 0.770499188   X     D
65  5 0.049138399   X     D
66  6 0.747017767   X     D
67  7 0.239916970   X     D
68  8 0.152777362   X     D
69  9 0.052862276   X     D
70 10 0.937605577   X     D
71  1 0.850112019   Y     D
72  2 0.675407232   Y     D
73  3 0.273276166   Y     D
74  4 0.455995477   Y     D
75  5 0.695497498   Y     D
76  6 0.688414035   Y     D
77  7 0.454013633   Y     D
78  8 0.874853452   Y     D
79  9 0.568746031   Y     D

Потім скористайтеся гратами xyplot:

library (lattice)
xyplot (y ~ x | graph, groups=var, data=dat, type="o",
        layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price")

який дає хороший графік, як:

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

Редагувати:

Якщо ви хочете мати різні символи та лінії, і вони відображаються у вашій легенді, це ускладнюється, тому що ви буквально будуєте легенду самі, і ви повинні знати, як отримати кольори решітки за замовчуванням, якщо ви самі їх не змінили :

my.text <- levels (dat$var)
my.lty <- c(2, 3)
my.pch <- c(1, 2)
my.col <- trellis.par.get ("superpose.symbol")$col[1:2]
xyplot (y ~ x | graph, groups=var, data=dat, type="o", pch=my.pch, lty=my.lty,
        main="Main Title", layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price",
        key=list (columns=2, text=list (my.text), points=list (pch=my.pch, col=my.col)))

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

EDIT 2:

Ви можете спростити код і графік, якщо ці дві категорії дійсно такі ж прості, як "X" і "Y":

xyplot (y ~ x | graph, groups=var, data=dat, type="o", pch=c("X", "Y"), cex=1.25, lty=c(2, 3),
        layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price")

яка буде використовувати символи точок "X" та "Y". Вам взагалі не потрібна легенда, і тоді ви можете присвятити ще більше місця для самих графіків. (З іншого боку, ви, можливо, не сподобаєтеся вигляду, або вам може бути складніше визначити точний центр точки, хоча це не стільки проблеми, скільки може бути, оскільки лінія проходить через кожну точку.)

EDIT 3:

Насправді вам слід додати strip=F, strip.left=T,сюжет, щоб поставити мітки A, B, C, D, ліворуч від графіків, що дає більше місця на довгому графіку, як це:

xyplot (y ~ x | graph, groups=var, data=dat, type="o", pch=my.pch, lty=my.lty,
        main="Main Title", layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price",
        strip.left=T, strip=F,
        key=list (columns=2, text=list (my.text), points=list (pch=my.pch, col=my.col),
        lines=list (lty=my.lty, col=my.col)))

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


@Wayne: Я намагаюся зберегти легенду на вершині графіка, використовуючи auto.key з пробілами = "top", pch = c (1,2), lty = c (2,4), але значення pch і Значення lty не працюють. Більше того, я хотів би зберегти X і Y як горизонтальні в легенді. Чи можете ви мені допомогти в цьому?
samarasa

Так. Мені потрібно використовувати різні значення pch, щоб distingish X і Y на папері. Я можу використовувати різні значення pch у графіку, додавши аргумент pch (1,4) до xyplot, але це не відображається на легенді. Будь ласка, дайте мені знати, як я можу використовувати різні pch значення для X та Y в легенді.
samarasa

Гаразд, я зрозумів це, як тільки повернувся додому і порадився з книгою. Перегляньте відредаговану версію.
Уейн

Без проблем. Я думаю, що моя редакція 3 дає найкращий графік, схожий на (але краще виглядає та має більше графічного простору, ніж ваш оригінал). Я не перемістив легенду, що вважаю досить відвертою. Якщо ви хочете, щоб лінія перейшла точку в легенді, я думаю, вам доведеться перенести її на наступний рівень складності і зробити малюнок.key речі, які створюють власні гроби ( gridріч: решітка та ggplot2 будуються на сітці) .
Уейн

Так, зараз графіка краще. Однак було б дуже добре, якби ми отримали крапку над лінією в легенді, як ми отримуємо з нормальною функцією сюжету.
samarasa

9

Ось версія рішення @ Брендона, ggplot2яка включає бажану поведінку легенди:

dat <- data.frame (x=rep (1:10, 8), y=runif(80),
        var=factor (rep (c("X", "Y"), each=10)),
        graph=factor (rep (c("A", "B", "C", "D"), each=20)))

ggplot(data = dat,aes(x = x, y = y)) + 
    facet_wrap(~graph,nrow = 4) + 
    geom_point(aes(shape = var)) + 
    geom_line(aes(colour = var, group = var)) + 
    labs(x = NULL, y = NULL, shape = "", colour = "") + 
    theme_bw() + 
    opts(legend.position = "top", legend.direction = "horizontal")

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

Я вважаю, що легенди набагато простіші ggplot2, але YMMV.

EDIT

Адресуючи декілька питань у коментарях. Щоб вказати конкретну точку або лінію типу, можна використовувати scale_aesthetic_manualде aestheticабо shape, linetypeі т.д. Наприклад:

ggplot(data = dat,aes(x = x, y = y)) + 
    facet_wrap(~graph,nrow = 4) + 
    geom_point(aes(shape = var)) + 
    geom_line(aes(colour = var, linetype = var, group = var)) + 
    labs(x = NULL, y = NULL, shape = "", colour = "", linetype = "") + 
    scale_shape_manual(values = 4:5) +
    theme_bw() + 
    opts(legend.position = "top", legend.direction = "horizontal")

Зміна розміру різних міток осі відбувається за допомогою зміни налаштувань у темі, як правило, використовуючи opts(). Наприклад:

ggplot(data = dat,aes(x = x, y = y)) + 
    facet_wrap(~graph,nrow = 4) + 
    geom_point(aes(shape = var)) + 
    geom_line(aes(colour = var, linetype = var, group = var)) + 
    labs(x = "X Label", y = "Y Label", shape = "", colour = "", linetype = "") + 
    theme_bw() + 
    opts(legend.position = "top", legend.direction = "horizontal",
         axis.text.x = theme_text(size = 15),axis.title.y = theme_text(size = 25, angle = 90))

Вам слід зануритися на веб-сайт та його книгу для отримання додаткової інформації.


2
Я часто віддаю перевагу ggplot2. Насправді я зробив швидку спробу з ggplot2, коли решітка стає надто складною, і виявив, що не можу зрозуміти, як легенда правильно відображала стилі точки / лінії, якщо я хотіла чітко вибрати форми та стилі ліній. Я, мабуть, зробив це неправильно, і йому вдалося попрацювати в графіку, але обдурив створення легенди ggplot. Чи можете ви побачити, чи працює він для вас і опублікувати код?
Уейн

@Joran: Я намагався з'ясувати, щоб змінити лінійні типи і точкові типи, і кольори, але успіху не було. Чи можете ви повідомити нам, як ми можемо змінити лінійні типи тощо. А також, будь ласка, повідомте нам, як ми можемо збільшити розмір лабораторій x та y.
samarasa

Я зараз на своєму телефоні; якщо @Brandon не відредагує свою відповідь, перш ніж я повернуся додому з тим, що ти шукаєш, я дістанусь до неї пізніше сьогодні ввечері.
joran

8

Подібно до відповіді Уейна, я також би використовував інший пакет, а саме ggplot2

library(ggplot2) 

df <- data.frame(
parameter=runif(300),
Time=1:300,
split=sample(c(1:4),300,replace=T),
split2=sample(c(1:2),300,replace=T)
)

ggplot(df, aes(Time, parameter, colour=as.factor(split2))) + 
geom_line() + 
facet_wrap(~split,nrow=4)

Що дає нам такий графік, як:

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


1
Мені подобаються сітки в ggplot, але чи є спосіб вимкнути світло-сірий фон?
bluepole

1
+ opts(panel.background=theme_blank())
Брендон Бертелсен

1
Якщо ви хочете внести інші зміни, ви можете ввести, theme_get()щоб побачити, що ви можете змінити. Потім дотримуйтесь тієї ж схеми, що і мій останній коментар, встановлюючи їх=theme_blank()
Брендон Бертелсен

2
Я збирався зробити ggplot2 сам, але подумав, що, можливо, решітка буде легшим кроком. Будь-який із них пропонує структурований спосіб складання таких графіків. Переробити багато деталей може бути важко, але швидко отримати щось привабливе і читабельне легко. (Хоча вам доведеться обернути голову навколо створення правильного кадру даних, з якого можна графікувати дані, а не просто кидати речі в графік.
Wayne

Я виявив, що Хедлі надав інструменти для маніпулювання даними в інших своїх пакетах для масування даних у потрібну форму. Коли ви сумніваєтесь у відповіді, як правило,melt()
Брендон Бертелсен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.