วาดหลายแปลงบนกราฟเดียวใน 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

a2: 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

ถ้าคุณมี 2colors และ 4 line line ในแกนเดียวกันกับตำนาน? ฉันต้องการดูรหัสและผลลัพธ์สำหรับสิ่งนั้น
พอล

@ user87: เนื่องจาก 4 แปลงมาจากการทดลอง 4 แบบ ดังนั้นฉันคิดว่ามันเป็นการดีกว่าที่จะวาด 4 แปลงเพื่อวิเคราะห์ผลลัพธ์จากการทดลอง
samarasa

@ user87 ฉันไม่แน่ใจว่าคุณหมายถึงอะไร บางทีถ้าคุณเริ่มต้นคำถามใหม่ใครบางคนจะตอบมัน (ฉันจะ :))
แบรนดอน Bertelsen

คำตอบ:


16

หากคุณต้องการยึดติดกับวิธีการที่คุณใช้อยู่คุณอาจต้องการเรียนรู้คำสั่ง layout () การเปลี่ยนแปลงรายละเอียดอื่น ๆ เล็กน้อยและคุณสามารถทำให้กราฟใกล้กันมากขึ้น คุณสามารถใส่สิ่งที่ไม่ซ้ำกันซึ่งเปลี่ยนแปลงระหว่างกราฟในรายการ (เช่นข้อมูลและระยะห่าง) จากนั้นจึงวนซ้ำ นอกจากนี้คุณจะทราบว่าฉันสร้างแกนด้านล่างด้วยคำสั่งแกนโดยตรง () เพื่อให้คุณสามารถควบคุมตำแหน่งของรายการได้

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)

theplot

ฉันควรทราบว่าฉันไม่ได้ใช้ความพยายามในการทำสิ่งนี้ให้ดีเท่าที่จะทำได้และแทนที่จะทำกราฟจำลองแรกที่ฉันสามารถกำหนดพื้นที่ให้เพียงพอในเฟรมแรก น่าเสียดายที่การตั้งค่า mar () พยายามเติมเฟรมและระยะขอบบนสุดมีผลต่อระยะทางที่ป้ายกำกับด้านบนกราฟอยู่ห่างออกไปดังนั้นฉันต้องไปและสร้างป้ายกำกับทั้งหมดของฉันด้วย mtext () หรือข้อความ () แทนที่จะใช้เพียง การตั้งค่าหลักภายในพล็อตและฉันไม่รู้สึกอยากทำอย่างนั้น


รอง +1 สำหรับกราฟิกฐาน badass ฉันพยายามอย่างไร้ผลที่จะเขียนสิ่งที่ดีกับคำสั่ง layout () ฉันจะกลับมาที่นี่ในครั้งต่อไปที่ฉันต้องการใช้มัน
Chris Beeley

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

ป้อนคำอธิบายรูปภาพที่นี่

แก้ไข 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" เป็นสัญลักษณ์จุด คุณไม่จำเป็นต้องมีตำนานเลยและสามารถอุทิศพื้นที่ให้กับกราฟได้มากกว่าเดิม (ในทางกลับกันคุณอาจไม่ชอบรูปลักษณ์หรืออาจพบว่ามันยากกว่าที่จะกำหนดจุดกึ่งกลางของจุดที่แน่นอนแม้ว่าจะไม่เป็นปัญหามากเท่าที่อาจเป็นเพราะเส้นผ่านแต่ละจุด)

แก้ไข 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 พร้อมช่องว่าง = "ด้านบน", pch = c (1,2), lty = c (2,4) อาร์กิวเมนต์ แต่ค่า pch และ ค่า lty ไม่ทำงาน ยิ่งกว่านั้นฉันต้องการให้ X และ Y เป็นแนวนอนในตำนาน คุณช่วยฉันได้ไหม
samarasa

ใช่. ฉันต้องใช้ค่า pch ที่แตกต่างกันเพื่อแยก X และ Y บนกระดาษ ฉันสามารถใช้ค่า pch ที่แตกต่างกันในพล็อตได้โดยเพิ่มอาร์กิวเมนต์ pch (1,4) ลงใน xyplot แต่มันไม่ได้สะท้อนถึงตำนาน โปรดแจ้งให้เราทราบว่าฉันจะใช้ค่า pch ที่แตกต่างกันสำหรับ X และ Y ในตำนานได้อย่างไร
samarasa

ตกลงฉันคิดออกเมื่อฉันกลับถึงบ้านและปรึกษาหนังสือ ตรวจสอบรุ่นที่แก้ไข
เวย์น

ไม่มีปัญหา. ฉันคิดว่า EDIT 3 ของฉันจะให้กราฟที่ดีที่สุดที่คล้ายกับ (แต่ดูดีกว่าและมีพื้นที่กราฟมากกว่า) ต้นฉบับของคุณ ฉันไม่ได้ย้ายตำนานซึ่งฉันคิดว่าค่อนข้างตรงไปตรงมา หากคุณต้องการให้เส้นผ่านจุดในตำนานฉันคิดว่าคุณจะต้องนำไปสู่ระดับความซับซ้อนถัดไปและทำสิ่งที่วาด. key ที่สร้าง grobs ที่กำหนดเอง ( gridสิ่ง: lattice และ ggplot2 สร้างบนตาราง) .
เวย์น

ใช่ตอนนี้กราฟก็ดีขึ้นแล้ว อย่างไรก็ตามมันจะดีมากถ้าเราได้คะแนนเหนือเส้นในตำนานอย่างที่เราได้รับจากฟังก์ชั่นการวางแผนปกติ
samarasa

9

นี่คือggplot2โซลูชันของ @ Brandon ที่รวมเอาลักษณะการทำงานในตำนานที่ต้องการ:

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

แก้ไข

การตอบคำถามสองสามข้อในความคิดเห็น เพื่อระบุจุดหรือสายโดยเฉพาะอย่างยิ่งประเภทที่คุณจะใช้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 คุณเห็นไหมว่ามันใช้ได้กับคุณและโพสต์รหัสหรือไม่
เวย์น

@ จุน: ฉันพยายามคิดให้เปลี่ยน linetypes และ pointtypes และสีสันต่าง ๆ แต่ก็ไม่ประสบความสำเร็จ คุณช่วยบอกให้เรารู้ว่าเราจะเปลี่ยนลินุกซ์ได้อย่างไรและโปรดแจ้งให้เราทราบว่าเราจะเพิ่มขนาดของห้องปฏิบัติการ x และ y ได้อย่างไร
samarasa

ฉันใช้โทรศัพท์ของฉันในขณะนี้ หาก @Brandon ไม่แก้ไขคำตอบของเขาก่อนที่ฉันจะกลับบ้านด้วยสิ่งที่คุณกำลังมองหาฉันจะไปหามันในคืนนี้
joran

8

คล้ายกับคำตอบของ Wayne ฉันจะใช้แพ็คเกจอื่นเช่นกัน 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())
Brandon Bertelsen

1
หากคุณต้องการทำการเปลี่ยนแปลงอื่น ๆ คุณสามารถพิมพ์theme_get()เพื่อดูสิ่งที่คุณสามารถเปลี่ยนแปลงได้ จากนั้นทำตามรูปแบบเดียวกับความคิดเห็นล่าสุดของฉันตั้งพวกเขา=theme_blank()
แบรนดอน Bertelsen

2
ฉันกำลังจะทำ ggplot2 ด้วยตัวเอง แต่คิดว่าบางทีขัดแตะอาจจะเป็นขั้นตอนที่ง่ายขึ้น อย่างใดอย่างหนึ่งให้วิธีที่มีโครงสร้างการกองกราฟเช่นนี้ การปรับแต่งรายละเอียดมากมายอาจจะยาก แต่การได้สิ่งที่น่าดึงดูดและอ่านได้อย่างรวดเร็วนั้นเป็นเรื่องง่าย (แม้ว่าคุณจะต้องตัดหัวของรอบการสร้างกรอบข้อมูลที่เหมาะสมที่จะทำกราฟข้อมูลแทนการเพียงการขว้างปาสิ่งที่เข้ามาในกราฟ.
เวย์น

ฉันพบว่า Hadley ได้มอบเครื่องมือการจัดการข้อมูลในแพ็คเกจอื่น ๆ ของเขาสำหรับการนวดข้อมูลให้เป็นรูปร่างที่ถูกต้อง เมื่อมีข้อสงสัยคำตอบมักจะmelt()
แบรนดอน Bertelsen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.