Como corrigir a proporção do ggplot?

88

Estou tentando redimensionar uma plotagem para caber no meu documento, mas estou tendo dificuldades para fazer com que o diagrama plotado seja um quadrado.

Exemplo:

pdf(file = "./out.pdf", width = 5, height = 5)
p <- ggplot(mydata, aes(x = col1, y = col2))
print(p)
aux <- dev.off()

Embora os limites para xey sejam iguais, o gráfico no resultado não é quadrado. Eu acho que R torna o painel envolvente 5x5 ", mas não se preocupa com o tamanho real do diagrama.

Como posso remover meus diagramas?

torque
fonte

Respostas:

113

No ggplotmecanismo para preservar a proporção de aspecto de sua plotagem é adicionar uma coord_fixed()camada à plotagem. Isso preservará a proporção da imagem em si, independentemente da forma da caixa delimitadora real.

(Eu também sugiro que você use ggsavepara salvar o gráfico resultante em pdf / png / etc, em vez da pdf(); print(p); dev.off()sequência.)

library(ggplot2)
df <- data.frame(
    x = runif(100, 0, 5),
    y = runif(100, 0, 5))

ggplot(df, aes(x=x, y=y)) + geom_point() + coord_fixed()

insira a descrição da imagem aqui

Andrie
fonte
3
Você sabe por que o ggplot insiste em colocar o rótulo do eixo y bem à esquerda? Adoraria saber como prevenir isso ...
Chase
@chase Uma solução complicada é modificar a hjustposição do título - tente opts(axis.title.y=theme_text(hjust=10)). Mas, infelizmente, parece que não. Consulte groups.google.com/group/ggplot2/browse_thread/thread/… para uma discussão da lista de e-mails ggplot e a resposta de @Baptiste.
Andrie
3
Esse comportamento é corrigido na versão de desenvolvimento.
hadley
5
Com o título mais geral da pergunta, você poderia também adicionar informações sobre como calcular a proporção (o argumento para coord_fixed), dado que não use os mesmos limites em ambos os eixos?
htorque de
1
Na sequência do comentário de @htorque; se y for, em vez disso, definido como y=runif(100, 0, 50)o aspecto do gráfico não é mais quadrado. coord_fixed()faz com que a escala de cada eixo seja igual apenas parece?
um ben diferente de
79

Para garantir uma proporção de aspecto específica, por exemplo, para quadrado, use theme(aspect.ratio=1).

A resposta de Andrie não fornece o quadro completo, pois o exemplo fornece dados talvez não naturais, onde o intervalo de x é igual ao intervalo de y. No entanto, se os dados fossem:

df <- data.frame(
  x = runif(100, 0, 50),
  y = runif(100, 0, 5))
ggplot(df, aes(x=x, y=y)) + geom_point() + coord_fixed()

então o enredo ficaria assim:

insira a descrição da imagem aqui

A função coord_fixed () também tem um argumento para ajustar a proporção dos eixos:

ratio proporção da imagem, expressa como y / x

Para que o enredo pudesse ser alinhado com:

ggplot(df, aes(x=x, y=y)) + geom_point() + coord_fixed(ratio=10)

insira a descrição da imagem aqui

Mas você precisa ajustar isso com os limites das variáveis ​​ou área do gráfico (nem todos os limites são bem divisíveis por números inteiros como esses exemplos).

um ben diferente
fonte
12

Para completar: se você quiser levar em consideração os limites do eixo muito diferentes:

df <- data.frame(
  x = runif(100, 0, 5000),
  y = runif(100, 0, 5))
ratio.display <- 4/3
ratio.values <- (max(df$x)-min(df$x))/(max(df$y)-min(df$y))
plot <- ggplot(df, aes(x=x, y=y)) + geom_point()
plot + coord_fixed(ratio.values / ratio.display)

Resultando em:

Graipher
fonte
14
como isso é melhor do que plot + theme(aspect.ratio=4/3)? O ggplot pode ter várias camadas, com vários conjuntos de dados, e os eixos podem ter fatores de expansão arbitrários, portanto, calcular a razão de y / x de uma fonte de dados parece bastante frágil.
baptiste
2
Porque isso aparentemente não é facilmente detectável. O que é comprovado pelo fato de que existem três respostas aqui, mas nenhuma menciona. Você deve colocá-lo em uma resposta, é definitivamente a melhor solução.
Graipher