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)

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


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


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


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.