alt text

GET00183 - Visualização de Dados

Jony Arrais Pinto Junior

A seguir, apresentaremos algumas visualizações gráficas que podem ser úteis em alguns contextos que ainda não discutimos ao longo do curso.

1 - Gráfico de dispersão 3-D

Suponha que o nosso interesse seja o de avaliar a relação entre quilometragem, cilindrada do motor e o peso do carro graficamente e de forma conjunta. As três variáveis envolvidas são quantitativas e um possível gráfico para visualizarmos a relação das 3 variáveis de interesse seria o gráfico de dispersão 3-D.

Atividade: Importe o arquivo Base_carros.txt e armazene-o em um objeto chamado base_carros.

Os dados foram extraídos da revista Motor Trend US 1974, trata-se da base mtcars do R. A base de dados possui 32 observações e 11 variáveis, dentre elas:

  • mpg - Milhas por galão;
  • cyl- número de cilindros;
  • disp - cilindrada do motor (em polegadas cúbicas - cu. in.);
  • wt - peso (em 1000 libras);
  • hp - potência do motor.
# Visualizando o objeto
base_carros
# A tibble: 32 x 12
     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb nome       
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>      
 1  21       6  160    110  3.9   2.62  16.5     0     1     4     4 Mazda RX4  
 2  21       6  160    110  3.9   2.88  17.0     0     1     4     4 Mazda RX4 …
 3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1 Datsun 710 
 4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1 Hornet 4 D…
 5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2 Hornet Spo…
 6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1 Valiant    
 7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4 Duster 360 
 8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2 Merc 240D  
 9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2 Merc 230   
10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4 Merc 280   
# … with 22 more rows

Vamos usar o pacote scatterplot3d para criarmos o nosso primeiro gráfico de dispersão 3-D.

# carregando pacote
library(scatterplot3d)

# criando um gráfico de dispersão 3-D simples
with(base_carros, {
   scatterplot3d(x = disp,
                 y = wt, 
                 z = mpg,
                 main="Gráfico de dispersão 3-D")
})

O gráfico precisa de algumas modificações para ficar mais fácil de interpretar. Vamos modificar o gráfico substituindo os pontos por círculos vermelhos preenchidos, além disso, vamos adicionar linhas no plano x-y e modificar os rótulos dos eixos.

# modificando o gráfico de dispersão 3-D
with(base_carros, {
  scatterplot3d(x = disp, 
                y = wt, 
                z = mpg,
                # escolhendo um círculo preenchido
                pch=19,
                # cor do círculo
                color="red", 
                # incluindo linhas no plano horizontal
                type = "h",
                main = "Gráfico de dispersão 3-D",
                xlab = "Cilindrada do motor (polegadas cúbicas)",
                ylab = "Peso (por 1000 libras)",
                zlab = "Milhas por galão")
})

A seguir, vamos indicar a marca do carro nos pontos. Podemos fazer isso salvando os resultados da função scatterplot3d em um objeto, usando a função xyz.convert para converter coordenadas de 3-D (x, y, z) em projeções 2-D (x, y) e aplicar o texto função para adicionar rótulos ao gráfico

# criando o gráfico de dispersão 3-D como um objeto
with(base_carros, {
  Disp_3d <- scatterplot3d(
    x = disp, 
    y = wt, 
    z = mpg,
    pch = 19,
    color = "red", 
    type = "h",
               main = "Gráfico de dispersão 3-D",
                xlab = "Cilindrada do motor (polegadas cúbicas)",
                ylab = "Peso (por 1000 libras)",
                zlab = "Milhas por galão")
  
  # convertendo projeções 3-D em 2-D
  Disp_3d.coords <- Disp_3d$xyz.convert(disp, wt, mpg) 
  
  # plotando o texto com encolhimento de 50% e à direita do ponto
  text(Disp_3d.coords$x, 
       Disp_3d.coords$y,   
       labels = nome,  
       cex = .5, 
       pos = 4)
})

Vamos avaliar os possíveis valores obtidos pela variável número de cilindros.

# carregando o pacote
library(expss)
library(tidyverse)

base_carros |> 
  select(cyl) |> 
  fre()
select(base_carros, cyl)  Count   Valid percent   Percent   Responses, %   Cumulative responses, % 
 4  11 34.4 34.4 34.4 34.4
 6  7 21.9 21.9 21.9 56.2
 8  14 43.8 43.8 43.8 100.0
 #Total  32 100 100 100
 <NA>  0 0.0

A seguir, vamos criar uma variável atribuindo uma cor para cada valor de cilindro e iremos incluir essa informação no gráfico.

# Definindo cores para cada valor do cilindro
base_carros = base_carros |> 
  mutate(cores = if_else(cyl == 4, "red", if_else(cyl == 6, "blue", "green")))

# criando o gráfico de dispersão 3-D como um objeto
with(base_carros, {
  Disp_3d <- scatterplot3d(
    x = disp, 
    y = wt, 
    z = mpg,
    pch = 19,
    color = cores, 
    type = "h",
               main = "Gráfico de dispersão 3-D",
                xlab = "Cilindrada do motor (polegadas cúbicas)",
                ylab = "Peso (por 1000 libras)",
                zlab = "Milhas por galão")
  
  # convertendo projeções 3-D em 2-D
  Disp_3d.coords <- Disp_3d$xyz.convert(disp, wt, mpg) 
  
  # plotando o texto com encolhimento de 50% e à direita do ponto
  text(Disp_3d.coords$x, 
       Disp_3d.coords$y,   
       labels = nome,  
       cex = .5, 
       pos = 4)
  
  # adicionando a legenda
legend(#localização da legenda
       "topleft", 
       inset=.05,
       # para suprimir a caixa da legenda e encolendo o texto em 50 %
       bty="n", 
       cex=.5, 
       title="Número of cilindros",
       c("4", "6", "8"), 
       fill=c("red", "blue", "green"))
  
})

Podemos ver facilmente que o Toyota Corolla faz a maior distância e tem baixa cilindrada, baixo peso e 4 cilindros.

2 - Gráfico de bolhas

É um gráfico usado para avaliar a relação de três variáveis. De uma forma geral, podemos dizer que um gráfico de bolhas é basicamente um gráfico de dispersão no qual o tamanho do ponto é proporcional aos valores de uma terceira variável quantitativa.

A seguir, vamos representar graficamente o peso do carro em relação à sua quilometragem e usar o tamanho do ponto para representar a potência.

# criando um gráfico de bolhas
base_carros |> 
  ggplot(mapping = aes(x = wt, 
                       y = mpg, 
                       size = hp)) +
  geom_point()

É possível melhorarmos a aparência padrão de gráfico fazendo simples modificações. Por exemplo, é possível aumentarmos o tamanho das bolhas, escolhermos uma forma e uma cor de ponto diferente e adicionarmos alguma transparência.

# melhorando o gráfico de bolhas

base_carros |> 
  ggplot(mapping = aes(x = wt, 
                       y = mpg, 
                       size = hp)) +
  geom_point(alpha = .5, 
             fill="cornflowerblue", 
             color="black", 
             shape=21) +
  scale_size_continuous(range = c(1, 14)) +
  labs(title = "Quilometragem automática por peso e potência",
       subtitle = "Motor Trend US Magazine (1973-74 models)",
       x = "Peso (por 1000 libras)",
       y = "Milhas por galão",
       size = "Potência") 

O argumento range da função scale_size_continuous especifica o tamanho mínimo e máximo do símbolo no gráfico. O default é o intervalo = c (1, 6).

O argumento shape da função geom_point especifica um círculo com uma cor de borda e cor de preenchimento.

Pelo gráfico, podemos ver claramente que as milhas por galão diminuem com o aumento do peso e da potência do carro. No entanto, há um carro com baixo peso, alta potência e grande consumo de combustível. Quem seria o carro?

Podemos dizer que os gráficos de bolhas são controversos pelo mesmo motivo que os gráficos de setores são controversos. As pessoas são melhores em julgar a extensão do que o volume. No entanto, eles são bastante populares.

3 - Diagramas aluviais

Os diagramas aluviais podem ser usados para visualizar as distribuições de frequência ao longo do tempo ou tabelas de frequência envolvendo várias variáveis categóricas.

Para ilustrar a visualização, iremos utilizar o arquivo survey85.csv.

Atividade: Importe o arquivo survey85.csv e armazene-o em um objeto chamado survey.

A base de dados possui variáveis referentes a uma pesquisa survey realizada em 1985 contendo remuneração e outras características de trabalhadores, tais como:

  • salário por hora em dólares (remuneracao);
  • número de anos de educação (educacao);
  • sexo;
  • é hispânico? (hispanico);
  • é do sul? (sul);
  • é casado? (casado);
  • tempo de experiência de trabalho (exper);
  • idade;
  • setor de trabalho (setor).
# Visualizando o objeto
survey
# A tibble: 533 x 10
   remuneracao educacao raca   sexo  hispanico sul   casado exper idade setor   
         <dbl>    <dbl> <chr>  <chr> <chr>     <chr> <chr>  <dbl> <dbl> <chr>   
 1        9          10 Branco M     N         N     S         27    43 constru…
 2        5.5        12 Branco M     N         N     S         20    38 vendas  
 3        3.8        12 Branco F     N         N     N          4    22 vendas  
 4       10.5        12 Branco F     N         N     S         29    47 adminis…
 5       15          12 Branco M     N         N     S         40    58 constru…
 6        9          16 Branco F     N         N     S         27    49 adminis…
 7        9.57       12 Branco F     N         N     S          5    23 servico 
 8       15          14 Branco M     N         N     N         22    42 vendas  
 9       11           8 Branco M     N         N     S         42    56 fabrica 
10        5          12 Branco F     N         N     S         14    32 vendas  
# … with 523 more rows

Inicialmente iremos criar um resumo que contempla as variáveis setor, raça e sexo. Como são muitas categorias de setor, estamos filtrando a base para alguns setores de interesse.

# resumindo os dados
tabela_survey <- survey %>%
  filter(setor %in% c("administrativo","servico","vendas")) |> 
  group_by(setor, raca, sexo) %>%
  count()

# visualizando o objeto
tabela_survey
# A tibble: 11 x 4
# Groups:   setor, raca, sexo [11]
   setor          raca       sexo      n
   <chr>          <chr>      <chr> <int>
 1 administrativo Branco     F        67
 2 administrativo Branco     M        15
 3 administrativo Não Branco F         9
 4 administrativo Não Branco M         6
 5 servico        Branco     F        40
 6 servico        Branco     M        26
 7 servico        Não Branco F         9
 8 servico        Não Branco M         8
 9 vendas         Branco     F        14
10 vendas         Branco     M        21
11 vendas         Não Branco F         3

Com o diagrama a seguir, é possível, visualmente entendermos a distribuição de cada variável e a relação entre elas (setor, raça e sexo).

# carregando pacote
library(ggalluvial)

# criando o diagrama
tabela_survey |> 
  ggplot(mapping = aes(axis1 = setor,
                       axis2 = raca,
                       y = n)) +
  geom_alluvium(aes(fill = sexo)) +
  geom_stratum() +
  geom_text(aes(label = after_stat(stratum)),
            stat = "stratum") +
  scale_x_discrete(limits = c("setor", "raca"),
                   expand = c(.1, .1)) +
  labs(title = "Survey 1985",
       subtitle = "estratificado por setor, sexo e raça",
       y = "Frequência") +
  theme_minimal()

No gráfico acima, percebemos que existe uma maior frequência de brancos do que não brancos na amostra. Dos setores, venda é o que possui menor frequência. Que o percentual de Brancos no setor administrativo é grande, e que entre estes a maioria é do sexo feminino.

A seguir apresentamos uma modificação que pode ser útil no diagrama.

# criando outro diagrama
tabela_survey |> 
  ggplot(mapping = aes(axis1 = setor,
                       axis2 = raca,
                       axis3 = sexo,
                       y = n)) +
  geom_alluvium(aes(fill = setor)) +
  geom_stratum() +
  geom_text(aes(label = after_stat(stratum)),
            stat = "stratum") +
  scale_x_discrete(limits = c("setor", "raca","sexo"),
                   expand = c(.1, .1)) +
  labs(title = "Survey 1985",
       subtitle = "estratificado por setor, sexo e raça",
       y = "Frequência") +
  theme_minimal()

4 - Gráfico de radar

Um gráfico de radar (também conhecido como mapa de aranha ou estrela) compara um ou mais grupos (ou observações) com relação a três ou mais variáveis quantitativas.

Inicialmente, vamos instalar o pacote ggradar.

# Instalando o pacote ggradar
devtools::install_github("ricardo-bion/ggradar")

Após a instalação, vamos calcular as médias das variáveis idade, salário por hora em dólares, número de anos de educação e tempo de experiência de trabalho.

# calculando as médias das variáveis e reescalonando as mesmas
resumo_graf <- survey |>
  filter(setor %in% c("administrativo", "construcao", "fabrica", "servico"," vendas")) |> 
  group_by(setor) |> 
  summarise(idade = mean(idade, na.rm = TRUE),
            salario = mean(remuneracao, na.rm = TRUE),
            educacao = mean(educacao, na.rm = TRUE),
            experiencia = mean(exper, na.rm = TRUE)) |> 
  mutate_at(.vars = vars(-setor),
            .funs = scales::rescale)

# Visualizando o objeto
resumo_graf
# A tibble: 4 x 5
  setor          idade salario educacao experiencia
  <chr>          <dbl>   <dbl>    <dbl>       <dbl>
1 administrativo 0       0.299   1            0    
2 construcao     1       1       0            1    
3 fabrica        0.208   0.505   0.0230       0.554
4 servico        0.586   0       0.253        0.658
# carregando o pacote
library(ggradar)

# generate radar chart
ggradar(resumo_graf, 
        grid.label.size = 4,
        axis.label.size = 4, 
        group.point.size = 5,
        group.line.width = 1.5,
        legend.text.size= 10) +
  labs(title = "Idade, experiência, salário e educação")

4 - Matriz de gráfico de dispersão

Uma matriz de gráfico de dispersão é uma coleção de gráficos de dispersão organizados em uma grade.

# carregando o pacote
library(GGally)

# retirando as variáveis nome e cores
base_carros_disp = base_carros |> 
  select( mpg, cyl, disp, hp, cores)

# criando uma matriz de gráfico de dispersão
ggpairs(base_carros_disp)

Na diagonal principal ele apresenta o gráfico da densidade para as variáveis quantitativas e um gráfico de barras para as variáveis qualitativas.

Acima da diagonal principal, no cruzamento de duas variáveis quantitativas, ele nos mostra o valor da correlação das duas variáveis. No cruzamento de uma variável qualitativa e uma quantitativa, ele nos mostra o comportamento do boxplot da variável quantitativa para cada categoria da variável qualitativa.