Desenhe vários gráficos em um gráfico em R?

13

Usando o código a seguir, tentei desenhar quatro gráficos em um gráfico R. Não estou feliz com a figura, porque há muito espaço entre as parcelas, portanto, a largura das parcelas não é suficiente para analisar as parcelas.

  1. Alguém poderia me ajudar a produzir um bom gráfico com quatro gráficos?

  2. Como posso manter os rótulos do eixo x de 1 a 10 em vez dos 5 rótulos padrão?

Dados:

a1: 11.013 13,814 13,831 13,814 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

Eu usei dados a1 para b1, c1 e d1; dados a2 para b2, c2 e d2 apenas por aqui.

Figura:

insira a descrição da imagem aqui

Código:

        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)
samarasa
fonte
1
você poderia pls dar os detalhes de seus dados? possivelmente, dput (data_from_r)
suncoolsu
@suncoolsu, atualizei a pergunta com uma amostra de dados. Obrigado.
21611
E se você tivesse 2 cores e 4 tipos de linha nos mesmos eixos com uma legenda? Eu gostaria de ver o código e os resultados para isso.
Paul
@ user87: Desde 4 parcelas são de 4 experiências diferentes. Portanto, acho que é melhor desenhar 4 gráficos para analisar os resultados dos experimentos.
precisa saber é o seguinte
@ user87, não sei o que você quer dizer. Talvez se você começar uma nova pergunta alguém iria respondê-la (eu :))
Brandon Bertelsen

Respostas:

16

Se você quiser usar algo como o método que você está usando, poderá aprender o comando layout (). Alguns outros detalhes são alterados e você pode aproximar os gráficos. Você também pode colocar as coisas únicas que mudam entre os gráficos em uma lista (como dados e margens) e depois passar por um loop. Além disso, você notará que eu criei o eixo inferior com o comando eixo direto () para que você possa controlar para onde os itens vão.

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)

o enredo

Devo observar que realmente não me esforcei para tornar isso o mais agradável possível e, em vez de criar o primeiro gráfico fictício, poderia ter apenas espaço suficiente no primeiro quadro. Infelizmente, a configuração mar () tenta preencher o quadro e a margem superior influencia a distância que o rótulo acima está ausente, então eu teria que fazer todos os meus rótulos com mtext () ou text () em vez de apenas usar o cenário principal dentro da trama e eu não estava com vontade de fazer isso

John
fonte
segundo o +1 para os gráficos básicos de badass. Eu tentei em vão escrever algo legal com o comando layout (). Vou voltar aqui da próxima vez que precisar usá-lo.
precisa saber é o seguinte
13

Eu recomendaria aprender o pacote gráfico de treliça. Eu posso chegar perto do que você quer com algumas linhas. Primeiro, empacote seus dados em um quadro de dados, algo como isto:

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

que produz:

    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

Em seguida, use a estrutura 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")

que produz um bom gráfico como:

insira a descrição da imagem aqui

EDITAR:

Se você deseja ter símbolos e linhas diferentes e aparecer na sua legenda, fica complicado, porque você mesmo constrói a legenda e precisa saber como obter as cores padrão da estrutura se não as substituir por si mesma :

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

insira a descrição da imagem aqui

EDIT 2:

Você pode simplificar o código e o gráfico, se as duas categorias forem realmente tão simples quanto "X" e "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")

que usará "X" e "Y" como símbolos de ponto. Você não precisa de nenhuma legenda e pode dedicar ainda mais espaço aos próprios gráficos. (Por outro lado, você pode não gostar da aparência, ou pode achar mais difícil determinar o centro exato do ponto, embora isso não seja tão problemático quanto pode ser, pois a linha passa por cada ponto.)

EDIT 3:

Na verdade, você deve adicionar strip=F, strip.left=T,ao gráfico para colocar os rótulos A, B, C, D à esquerda dos gráficos, o que oferece mais espaço em um gráfico longo como este:

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

insira a descrição da imagem aqui

Wayne
fonte
@ Wayne: Eu estou tentando manter uma legenda no topo do gráfico usando auto.key com espaço = "top", pch = c (1,2), lty = c (2,4) argumentos, mas os valores de pch e Valores de lty não estão funcionando. Além disso, gostaria de manter o X e o Y na horizontal na legenda. Poderia me ajudar por isso.
Samara #
Sim. Preciso usar diferentes valores de pch para distinguir X e Y em um papel. Consigo usar diferentes valores de pch no gráfico adicionando o argumento pch (1,4) ao xyplot, mas ele não está refletindo na legenda. Informe-me como posso usar diferentes valores de pch para X e Y na legenda.
Samarasa
OK, eu descobri quando cheguei em casa e consultei o livro. Confira a versão editada.
21711 Wayne
Sem problemas. Eu acho que meu EDIT 3 oferece o melhor gráfico semelhante ao (mas com melhor aparência e com mais espaço gráfico) do que o original. Não mudei a lenda, o que acho bastante direto. Se você deseja que a linha passe pelo ponto da legenda, acho que você precisará levá-la ao próximo nível de complexidade e desenhar coisas draw.key que criam grobs personalizados (uma gridcoisa: lattice e ggplot2 construídos na grade) .
Wayne
Sim, agora o gráfico é melhor. No entanto, seria muito bom se obtivéssemos o ponto acima da linha na legenda, como obtemos com a função de plotagem normal.
precisa saber é
9

Aqui está uma versão da ggplot2solução @ Brandon que incorpora o comportamento da legenda desejada:

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

insira a descrição da imagem aqui

Acho lendas muito mais fáceis ggplot2, mas YMMV.

EDITAR

Abordando algumas perguntas nos comentários. Para especificar determinados tipos de ponto ou linha, você usaria scale_aesthetic_manualonde aestheticé ou shape, linetypeetc. Por exemplo:

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

A alteração do tamanho de vários rótulos de eixos é feita alterando as configurações do tema, geralmente usando opts(). Por exemplo:

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

Você realmente deve mergulhar no site e no livro dele para obter mais informações.

joran
fonte
2
Eu geralmente prefiro o ggplot2. Na verdade, eu tentei rapidamente o ggplot2 quando a estrutura estava ficando muito complexa e descobri que não conseguia entender a legenda para refletir adequadamente os estilos de ponto / linha se quisesse escolher formas e estilos de linha explicitamente. Provavelmente fiz isso da maneira errada e ele conseguiu funcionar no gráfico, mas enganei a criação de lendas do ggplot. Você pode ver se funciona para você e postar o código?
21711 Wayne
@ Jordan: Eu tentei descobrir como alterar os tipos de linha e de ponto e as cores, mas sem sucesso. Você pode nos informar como podemos alterar os tipos de linha etc. E também como podemos aumentar o tamanho dos laboratórios xey.
Samarasa
Estou no meu telefone no momento; se o @Brandon não editar a resposta dele antes de eu chegar em casa com o que você está procurando, eu o abordarei mais tarde esta noite.
joran
8

Semelhante à resposta de Wayne, eu também usaria um pacote diferente, a saber 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)

O que nos dá um gráfico como:

insira a descrição da imagem aqui

Brandon Bertelsen
fonte
1
Gosto das grades no ggplot, mas existe uma maneira de desativar o plano de fundo cinza claro?
bluepole
1
+ opts(panel.background=theme_blank())
Brandon Bertelsen
1
Se você quiser fazer outras alterações, digite theme_get()para ver o que pode ser alterado. Em seguida, siga o mesmo padrão como o meu último comentário, colocando-os=theme_blank()
Brandon Bertelsen
2
Eu mesma faria o ggplot2, mas pensei que talvez a estrutura fosse um passo mais fácil. Qualquer um deles fornece uma maneira estruturada de empilhar gráficos como este. Ajustar muitos detalhes pode ficar difícil, mas é fácil obter algo atraente e legível rapidamente. (Embora você tem que quebrar a cabeça em torno de criar o quadro de dados certo de que para representar graficamente os dados, em vez de apenas jogando coisas no gráfico.
Wayne
Descobri que Hadley forneceu ferramentas de manipulação de dados em seus outros pacotes para massagear os dados na forma correta. Em caso de dúvida, a resposta é normalmente,melt()
Brandon Bertelsen