ggplot2 – Tutorial básico

Introdução

A linguagem R [@R2012], por meio do pacote (R Base Graphics) permite
realizar uma série de gráficos para análise de dados. Contudo, quando
exige-se personalizações, tal ação pode demandar um pouco mais de
tempo. Uma alternativa para agilizar o processo é o pacote ggplot2,
desenvolvido por @WICKHAM2009. O que difere o ggplot2 é a que ao invés
de usar a lógica de desenhar elementos na tela, o ggplot2 segue uma
“gramática de gráficos estatísticos”.

Imagine que o ggplot2 permite construir gráficos por camadas, dessa
forma é possível uma sobreposição de elementos que podem ajudar na sua
análise.

O objetivo do “post” é uma introdução ao ggplot2, mostrando algumas
expressões básicas e algumas dicas de formatação.

GGPLOT2

Basicamente para gerar os gráficos precisamos definir:

  • Uma base de dados (um data.frame);
  • Atributos (aesthetics);
  • A forma dos objetos geométricos;
  • Transformações estatísticas (quando necessário);
  • Facetas (quando necessário);
  • Formatação específicas (quando necessário).

Além de instalar o ggplot2, para nos ajudar (facilitar) vamos instalar
mais dois pacotes, gridExtra e ggthemes

install.packages("ggplot2")
install.packages("gridExtra")
install.packages("ggthemes")

Após basta carregá-los.

library(ggplot2)
library(ggthemes)
library(gridExtra)
library(dplyr)
library(plyr)

Dados

Vamos supor que vamos comparar a produtividade (kg ha-1) de
uma cultura para diferentes doses de um determinado nutriente (kg
ha-1). O experimento foi realizado para duas classes de solo
(A, B), que podem ser encontrados em dois estados (GO, MT).

ESTADO <- rep(c("GO", "MT"), each = 20)
SOLO <- rep(c("SOLO A", "SOLO B"), each = 10)
DOSE <- rep(seq(5, 50, 5), 2)
PROD <- c(seq(40, 50, 5), seq(53, 56), seq(55, 53),
          seq(45, 55, 5), seq(56, 59), seq(58, 56))

DADOS_1 <- data.frame(ESTADO, SOLO, DOSE, PROD = c(PROD, PROD * 1.12))

Gráfico de dispersão (scatterplot) e linhas

Há outras sequências lógicas para a construção dos gráficos, iremos
desenvolver uma que acho mais didática. O primeiro gráfico será
verificar o comportamento da produtividade para as diferentes doses de
nutriente.

GGPLOT_PLOT_1 <-
    ggplot() +
    geom_point(data = DADOS_1,
               aes(x = DOSE, y = PROD)) 
GGPLOT_PLOT_1

Produtividade em função da dose

  • A função ggplot() cria uma camada principal para receber as demais
    camadas.
  • O sinal + indica que mais comandos serão adicionados na
    sequência.
  • geom_point indica o objeto geométrico (tipo de gráfico)
  • aes estéticas indica o mapeamento, basicamente qual variável irá
    no eixo x e y. Além disso, qual coluna do data frame irá ser
    utilizada para criar o agrupamento de dados (quando desejado).

Usando o mesmo exemplo, vamos indicar por cores o solo de cada ponto
amostral, ou seja, agrupar os dados por classe de solo. O agrupamento
dos dados pode ser feito por meio de cor (colour), forma (shape),
preenchimento (fill), tamanho (size).

GGPLOT_PLOT_2 <-
    ggplot() +
    geom_point(data = DADOS_1,
               aes(x = DOSE, y = PROD, colour = SOLO)) 
GGPLOT_PLOT_2

Produtividade em função da dose, agrupado por solo

Já é possível notar que no Solo B a produtividade foi superior. Vamos
agora definir os rótulos e formatar os eixos do gráfico e . Para
verificar o que cada linha de código realiza, observe os
comentários. Cada elemento pode ser configurado como desejado, maiores
detalhes podem ser visto clicando AQUI.

GGPLOT_PLOT_3 <-
    ggplot() +
    geom_point(data = DADOS_1,
               aes(x = DOSE, y = PROD, colour = SOLO)) +
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) + # rótulo x
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + # rótulo y
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) + # intervalo x
    scale_y_continuous(breaks = seq(0,100,10), limits = c(0,70)) + # intervalo y
    theme(legend.position="bottom") + # posição da legenda
    theme(text=element_text(size = 10)) # tamanho da fonte                                   
GGPLOT_PLOT_3

Produtividade em função da dose, agrupado por solo com algumas formatações

Um modo prático de trocar as cores do gráfico é utilizar o pacote
ggthemes. Detalhe, utilize as funções do ggthemes antes de
personalizar outras elementos com a função theme().

GGPLOT_PLOT_4 <-
    ggplot() +
    geom_point(data = DADOS_1,
               aes(x = DOSE, y = PROD, colour = SOLO)) +
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) +
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    scale_y_continuous(breaks = seq(0,100,10), limits = c(0,70)) +
    theme_bw() + # DEVE vir antes theme()
    theme(legend.position="bottom") +
    theme(text=element_text(size = 10))
GGPLOT_PLOT_4

Produtividade em função da dose, agrupado por solo com algumas formatações e theme_bw()

Veja mais opções do ggthmes clicando AQUI.

Até aqui, conseguimos verificar que há um comportamento diferente da
produtividade nas classes de solo A e B. De acordo com nossos dados,
os referidos solos podem ser encontrados em dois estados, GO e MT. Há
vários recursos para separar as produtividades de cada Estado, vamos
realizar algumas:

a. Fazer dois gráficos
b. Criar uma legenda para o Estado
c. Utilizar o recurso "facet"

Opção "a", vamos fazer dois gráficos. Basta apenas utilizar a função
subset para filtrar os dados no argumento data. Posteriormente,
utilizando a função grid.arrange() do pacote gridExtra, colocamos
os gráficos lado a lado.

PLOT_GO <-
    ggplot() +
    geom_point(data = subset(DADOS_1, ESTADO == "GO"),
               aes(x = DOSE, y = PROD, colour = SOLO)) +
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) +
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    scale_y_continuous(breaks = seq(0,100,10), limits = c(0,70)) +
    theme_bw() +
    theme(legend.position="bottom") +
    ggtitle("GO") +
    theme(text=element_text(size = 10))
PLOT_MT <-
    ggplot() +
    geom_point(data = subset(DADOS_1, ESTADO == "MT"),
               aes(x = DOSE, y = PROD, colour = SOLO)) +
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) +
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    scale_y_continuous(breaks = seq(0,100,10), limits = c(0,70)) +
    theme_bw() +
    theme(legend.position="bottom") +
    ggtitle("MT") +
    theme(text=element_text(size = 10))
GGPLOT_PLOT_4a <- grid.arrange(PLOT_GO, PLOT_MT, ncol = 2)

Produtividade em função da dose, agrupado por solo e estados dividos em dois gráficos

Para o opção "b", vamos agrupar por classe de solo e estado.

GGPLOT_PLOT_4b <-
    ggplot() +
    geom_point(data = DADOS_1,
               aes(x = DOSE, y = PROD, colour = SOLO, shape = ESTADO)) +
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) +
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    scale_y_continuous(breaks = seq(0,100,10), limits = c(0,70)) +
    theme_bw() +
    theme(legend.position="right") +
    theme(text=element_text(size = 10))
GGPLOT_PLOT_4b

Produtividade em função da dose, agrupado por solo e estados

Na opção "c" vamos utilizar o recurso de "Facet", é simples de usar e
fica sofisticado na apresentação. Continuamos utilizar o conceito de agrupamento,
contudo utilizaremos a função facet_grid. Também há uma função
denominada facet_wrap, veja as diferenças clicando AQUI.
Observe que retiramos no aes o argumento shape = ESTADO.

GGPLOT_PLOT_4c <-
    ggplot() +
    geom_point(data = DADOS_1,
               aes(x = DOSE, y = PROD, colour = SOLO)) +
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) +
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    scale_y_continuous(breaks = seq(0,100,10), limits = c(0,70)) +
    theme_bw() +
    theme(legend.position="bottom") +
    theme(text=element_text(size = 10)) +
    facet_grid(. ~ ESTADO)
GGPLOT_PLOT_4c

Produtividade em função da dose, agrupado por solo e utilizando a função facet_grid()

Também é possível eliminar a necessidade de legenda, para isso basta:

GGPLOT_PLOT_4cc <-
    ggplot() +
    geom_point(data = DADOS_1,
               aes(x = DOSE, y = PROD)) +
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) +
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    scale_y_continuous(breaks = seq(0,100,10), limits = c(0,70)) +
    theme_bw() +
    theme(text=element_text(size = 10)) +
    facet_grid(SOLO ~ ESTADO)
GGPLOT_PLOT_4cc

Produtividade em função da dose, agrupado por solo e utilizando a função facet_grid()

Observação:

Como dito anteriormente, há outras lógicas para construção de um
gráfico. Como exemplo vamos especificar data e aes logo na
primeira função que geram a camada "base" dos gráficos, e de modo
individual, definir a forma geométrica:

GGPLOT_PLOT_5 <-
    ggplot(data = DADOS_1, # data frame de origem dos dados
           aes(x = DOSE, y = PROD, colour = SOLO, shape = ESTADO)) + # agrupamento
    geom_point() + # forma geométrica 
    geom_line()+   # forma geométrica 
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) + 
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    scale_y_continuous(breaks = seq(0,100,10), limits = c(0,70)) +
    theme_bw() + 
    theme(legend.position="right") +
    theme(text=element_text(size = 10))
GGPLOT_PLOT_5

Produtividade em função da dose, agrupado por solo e estados

Gráfico de Barras

Para o gráfico de barras utilizamos geom_bar. O único detalhe é usar o
argumento stat = identity. Veja o help do geom_bar() para maiores
detalhes. No exemplo a seguir, como temos dois estados, vamos usar
apenas os resultados do estado de GO

GGPLOT_PLOT_6 <-
    ggplot() +
    geom_bar(data = subset(DADOS_1, ESTADO == "GO"),
             aes(x = DOSE, y = PROD, fill = SOLO),
             stat = "identity")+
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) + 
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    theme_bw() +
    theme(legend.position="bottom") +
    theme(text=element_text(size = 10))
GGPLOT_PLOT_6

Gráfico de barra sobreposto

A função geom_bar automaticamente sobrepõe as barras. Para que as
mesmas fiquem lado a lado basta usar a opção dodge.

GGPLOT_PLOT_6a <-
    ggplot() +
    geom_bar(data = subset(DADOS_1, ESTADO == "GO"),
             aes(x = DOSE, y = PROD, fill = SOLO),
             stat = "identity",
             position = "dodge") +
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) + 
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    theme_bw() +
    theme(legend.position="bottom") +
    theme(text=element_text(size = 10))
GGPLOT_PLOT_6a

Gráfico de barra lado a lado

Como desejamos visualizar os resultados de ambos os Estados (GO e MT),
vamos usar a função facet_grid().

GGPLOT_PLOT_6b <-
    ggplot() +
    geom_bar(data = DADOS_1,
             aes(x = DOSE, y = PROD, fill = SOLO),
             stat = "identity",
             position = "dodge")+
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) + 
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    facet_grid(. ~ ESTADO) +
    theme_bw() +
    theme(legend.position="bottom")+
    theme(text=element_text(size = 10))
GGPLOT_PLOT_6b

Gráfico de barra lado a lado com a função facet_grid()

Representando o ajuste de uma modelo

A função geom_smooth() permite representar o ajuste de um modelo para
um conjunto de dados. Maiores detalhes sobre a função podem ser
verificadas AQUI.
Inicialmente vamos utilizar somente os dados do Estado de GO.

GGPLOT_PLOT_7 <-
    ggplot() +
    geom_point(data = subset(DADOS_1, ESTADO == "GO"),
             aes(x = DOSE, y = PROD, colour = SOLO)) +
    geom_smooth(data = subset(DADOS_1, ESTADO == "GO"),
                aes(x = DOSE, y = PROD, colour = SOLO),
                method = lm,
                formula = y ~ poly(x, 2, raw = TRUE ))+
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) + 
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    theme_bw() +
    theme(legend.position="bottom") +
    theme(text=element_text(size = 10))
GGPLOT_PLOT_7

Modelo ajustado para diferentes classes de solo para o Estado do GO

Podemos utilizar o recurso facet_grid() para visualizar os ajustes
para os dois estados.

GGPLOT_PLOT_7a <-
    ggplot() +
    geom_point(data = DADOS_1,
             aes(x = DOSE, y = PROD, colour = SOLO)) +
    geom_smooth(data = DADOS_1,
                aes(x = DOSE, y = PROD, colour = SOLO),
                method = lm,
                formula = y ~ poly(x, 2, raw = TRUE )) +
    facet_grid(. ~ ESTADO) +
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) + 
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    theme_bw() +
    theme(legend.position="bottom") +
    theme(text=element_text(size = 10))
GGPLOT_PLOT_7a

Modelo ajustado para diferentes classes de solo para ambos Estados

Como o conceito do geo_smooth() já foi apresentado, vamos inserir o
coeficiente determinístico para os tratamentos testados. Há várias
maneiras para adicionar elementos no gráfico, vamos utilizar uma
simples. Inicialmente realiza-se o ajuste do modelo com a função
lm(). Para fazer as regressões de uma única vez foi utilizado o pacote
plyr.

LM <- dlply(DADOS_1, c("ESTADO", "SOLO"),
            function(df)
                (lm(PROD ~ poly(DOSE, 2, raw=TRUE), data = df)))

LM_DF <- ldply(LM, function(x) {
    r.sq <- summary(x)$r.squared
    intercept <- summary(x)$coefficients[1]
    beta <- summary(x)$coefficients[2]
    beta1 <- summary(x)$coefficients[3]
    data.frame(r.sq, intercept, beta, beta1)})

Apresentando os dados em tabela (função kable() do pacote knitr).

kable(LM_DF, format = 'markdown')
ESTADO SOLO r.sq intercept beta beta1
GO SOLO A 0.9857696 35.00000 1.193939 -0.0169697
GO SOLO B 0.9677414 41.16667 1.026364 -0.0148485
MT SOLO A 0.9857696 39.20000 1.337212 -0.0190061
MT SOLO B 0.9677414 46.10667 1.149527 -0.0166303

Fazendo o gráfico

GGPLOT_PLOT_7b <-
    ggplot() +
    geom_point(data = DADOS_1,
               aes(x = DOSE, y = PROD, colour = SOLO)) +
    facet_grid(SOLO~ESTADO) +
    geom_smooth(data = DADOS_1,
                aes(x = DOSE, y = PROD, colour = SOLO),
                method = lm,
                formula = y ~ poly(x, 2, raw = TRUE ))+
    geom_text(data = LM_DF,
              aes (x = 25,
                   y = 45,
                   label=paste("R^2==",LM_DF$r.sq, sep = "")),
              size = 2.8,                   
              parse = TRUE) +
    xlab(expression(paste("Dose"~ (kg~ha^-1)))) + 
    ylab(expression(paste("Produtividade"~(sc~ha^-1)))) + 
    scale_x_continuous(breaks = seq(0,100,5), limits = c(0,55)) +
    theme_bw() +
    theme(legend.position="bottom") +
    theme(text=element_text(size = 10)) +
    guides(colour = FALSE) ## oculta a legenda
GGPLOT_PLOT_7b

Modelo ajustado para diferentes classes de solo para ambos Estados

References

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s