在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;仅用于此处的b2,c2和d2的a2数据。

数字:

在此处输入图片说明

码:

        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 2011年

@suncoolsu,我已经用数据样本更新了问题。谢谢。
samarasa

如果在带有图例的同一轴上有2colors和4线型怎么办?我想要查看代码和结果。
保罗

@ user87:因为4个图来自4个不同的实验。因此,我认为最好绘制4个图来分析实验结果。
samarasa

@ user87,我不确定您的意思。也许如果您提出了一个新问题,那么有人会回答(我会:))
布兰登·贝特尔森

Answers:


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()代替所有标签,而不仅仅是使用情节中的主要设置,我不想这么做


其次是badass基本图形的+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)))

在此处输入图片说明

编辑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:我试图使用带有空格=“ top”,pch = c(1,2),lty = c(2,4)参数的auto.key在图的顶部保留图例,但pch值和lty值不起作用。此外,我想使图例中的X和Y保持水平。你能帮我这个忙吗?
samarasa

是。我需要使用不同的pch值来区分纸张上的X和Y。通过在xyplot中添加参数pch(1,4),我可以在图中使用不同的pch值,但是它并没有反映图例。请让我知道如何在图例中为X和Y使用不同的pch值。
samarasa

好的,我到家并查阅本书后就知道了。签出编辑后的版本。
韦恩

没问题。我认为我的EDIT 3为您提供了与原始图像相似的最佳图形(但外观更好,并且图形空间更大)。我没有移动图例,我认为这很简单。如果您想使线穿过图例中的点,我认为您必须将其带到下一个复杂度级别,并进行创建自定义杂项的draw.key东西(grid事情是:grid和ggplot2构建在网格上) 。
韦恩

是的,现在图表更好。但是,如果像在常规图函数中那样获得图例中的直线,那将是非常好的。
samarasa

9

这是@Brandon 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的传说要容易得多。

编辑

在评论中回答几个问题。要指定特定的点或线的类型,你可以使用scale_aesthetic_manual其中aesthetic的两种shapelinetype等。例如:

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 2011年

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

我发现Hadley在他的其他软件包中提供了数据处理工具,用于将数据按摩成正确的形状。如果有疑问,答案通常是,melt()
布兰登·贝特尔森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.