Scatter plot: Um Guia Completo para Gráficos de Dispersão

Scatter plot: Um Guia Completo para Gráficos de Dispersão

 

Os gráficos de dispersão ou Scatter plot são representações gráficas do relacionamento entre duas variáveis numéricas. O Scatter plot utiliza pontos para representar essa relação, cada ponto representa o valor de uma variável no eixo horizontal e o valor de outra variável no eixo vertical.

No gráfico acima, temos o gráfico de dispersão do logaritmo do PIB (Produto Interno Bruto) per capita pela Expectativa de Vida. Cada ponto do gráfico apresenta o valor do logaritmo do PIB per capita de um país em relação a Expectativa de Vida do país.

Observa-se, que quanto maior o PIB per capita, maior a expectativa de vida. Ou seja, existe uma correlação positiva entre essas variáveis (a medida que uma variável aumenta a outra variável também aumenta).

Quando você deve usar um gráfico de dispersão?

Descrito por Francis Galton, o Scatter plot é usado para verificar se existe uma relação entre causa e efeito entre duas variáveis numéricas.

Isso não significa que uma variável causa efeito na outra, mas apenas se existe uma relação e qual intensidade entre essa relação. A relação entre duas variáveis pode ser positiva, negativa ou neutra, linear ou não linear.

O gráfico de dispersão não mostra apenas o valor individualmente, mas mostra os dados como um todo. Sendo útil para identificar outro padrões nos dados, como outlier (pontos extremos) ou possíveis grupos entre os dados.

Exemplo de estrutura de dados

Para criar gráficos de dispersão precisamos de um conjunto de dados, que tenha no mínimo duas variáveis numéricas (variáveis quantitativas). Aqui vamos utilizar o dataset ‘gapminder’.

Esse conjunto de dados ficou muito famoso após a apresentação do Hans Rosling, um doutor e estatístico sueco que apresentava e ilustrava os dados através de uma história atraente (storytelling).

Os dados gapminder resume informações da população, PIB e expectativa de vida dos países ao longo do tempo.

O conjunto de dados está disponível em https://github.com/scudilio/Visualizacao_de_dados

#Importando as bibliotecas necessárias
import pandas as pd;
import numpy as np;
import seaborn as sns; sns.set();
import matplotlib.pyplot as plt;
import plotly.express as px;

Importando dados de uma planilha Excel

O data set está numa planilha do Excel, para importar o arquivo utilizamos a função ‘read_excel’

##Importando o data set
url= ('https://github.com/scudilio/Visualizacao_de_dados/blob/master/datasets/gapminder_final.xlsx?raw=true')
df= pd.read_excel(url)
df.head()

Como construir um Scatter plot

O gráfico de dispersão mais comum é o bivariado, onde temos duas variáveis contínuas e buscamos entender a relação entre elas. Aqui utilizaremos a variável expectativa de vida e o logaritmo do PIB per capita.

Utilizamos a escala logarítmica, pois os dados do PIB per capita possui muito valores com alta variabilidade e o logaritmo reduz a escala dos dados facilitando a visualização dos dados.

Para construir o Scatter plot utilizaremos a biblioteca ‘plotly.express’. ‘Plotly’ é uma biblioteca de visualização de dados em Python, com ela é possível construir gráficos interativos de maneira simples e que são esteticamente bonitos.

Para construir o Scatter plot utilizamos a função ‘scatter’ e com apenas uma linha de código geramos o gráfico. As funções ‘upddate’ é para configurar a aparência, o título e eixos do gráfico.

import plotly.express as px
fig  = px.scatter(df, x = 'gdpPercap', y = 'lifeExp', log_x = True, width = 800)
fig.update_traces(marker = dict(size = 12, line=dict(width = 2)), selector = dict(mode = 'markers'))
fig.update_layout(title = 'Logaritmo do PIB per capita X Expectativa de vida')
fig.update_xaxes(title = 'Log(PIB per capita)')
fig.update_yaxes(title = 'Expectativa de vida')
fig.show()

Observe que quanto maior o PIB per capita de um país maior é a expectativa de vida. Vale ressaltar, que nesse primeiro gráfico plotamos todos os anos juntos, causando uma poluição visual.

Sendo esse um dos problemas dos gráficos de dispersão, muitos pontos em um gráfico só. Detalhamos esse problema a seguir

Principais problemas ao utilizar gráficos de dispersão

1. Overplotting

Quando temos muitos dados a serem plotados, os pontos podem se sobrepor a um grau que fica difícil ver a relações entre as variáveis.

Existem algumas maneiras de resolver esse problema, uma das alternativas é plotar apenas uma subconjunto dos dados. Uma amostra aleatória deve fornecer a idéia geral dos padrões dos dados.

Para aplicar essa técnica de amostragem utilizaremos a função ‘sample’, para selecionar 1000 observações aleatória do data set.

df_sample = df.sample(n=1000)
fig = px.scatter(df_sample, x = 'gdpPercap', y = 'lifeExp', log_x = True, width = 800)
fig.update_traces(marker = dict(size=12, line = dict(width=2)),selector=dict(mode = 'markers'))
fig.update_layout(title = 'Logaritmo do PIB per capita X Expectativa de vida')
fig.update_xaxes(title ='Log (PIB per capita)')
fig.update_yaxes(title = 'Expectativa de vida')
fig.show()

Observe que mesmo considerando apenas uma amostra do conjunto de dados, mantemos a ideia geral dos dados. Quanto maior o PIB per capita, maior a expectativa de vida. A segunda alternativa para resolver o overplotting, é colocar transparência nos pontos, permitindo que as sobreposições sejam visíveis. Para isso utilizamos a opção ‘opacity’

fig=px.scatter(df_sample, x = 'gdpPercap', opacity=0.5, y = 'lifeExp', log_x = True, width = 800)
fig.update_layout(title = 'Logaritmo PIB per capita X Expectativa de vida')
fig.update_xaxes(title = 'Log (PIB per capita)')
fig.update_yaxes(title = 'Expectativa de vida')
fig.show()

Observe que a transparência deixa o gráfico menos poluído visualmente. A seguir discutiremos um outro problema dos gráficos de dispersão.

2. Interpretar correlação como causalidade

Correlação não implica causalidade

O problema aqui não é o gráfico em si, mas a sua interpretação. Observar uma relação entre duas variáveis em um gráfico de dispersão, não implica que a mudança em uma variável é responsável pela mudança na outra variável.

É possível que exista uma terceira variável influenciando as duas variáveis plotadas ou que o padrão seja mera coincidência. Por isso, cuidado com a interpretação.

Diferentes tipos de Scatter plot

Para construir os diferentes tipos de Scatter plot iremos considerar apenas os dados de 2019.

1. Scartterplot Bivariado

Como comentado anteriormente, o gráfico de dispersão mais comum é o bivariado, quando temos duas variáveis numéricas e queremos entender sua relação.

Utilizamos a função ‘scatter’ para construir o gráfico, mesma função utilizada anteriormente, e acrescentamos uma opção ‘hover_name = “country”‘, essa opção faz aparecer no gráfico o nome do país correspondente ao ponto, quando o mouse tiver sobre o ponto desejado.

df_2019 = df[df["year"] == 2019]
fig = px.scatter(df_2019, x = "gdpPercap", y = "lifeExp", hover_name = "country", log_x = True, size_max = 90, width = 800)
fig.update_traces(marker = dict(size = 12, line = dict(width=2)), selector = dict(mode = 'markers'))
fig.update_layout(title = 'Logaritmo do PIB per capita X Expectativa de vida no ano de 2019')
fig.update_xaxes(title = 'Log (PIB per capita)')
fig.update_yaxes(title = 'Expectativa de vida')
fig.show()

Novamente temos a mesma conclusão, quanto maior o PIB per capita, maior é a expectativa de vida.

Agora, e se o interesse for analisar a relação do PIB per capita e expectativa de vida em cada continente?

Podemos fazer cinco gráficos distintos, uma para cada continente, para isso incluímos a opção ‘facet_col

fig = px.scatter(df_2019, x = "gdpPercap", y = "lifeExp",  hover_name = "country", 
log_x = True, size_max = 60, facet_col = 'continent')
fig.update_traces(marker = dict(size = 12,line = dict(width = 2)),selector = dict(mode = 'markers'))
fig.update_layout(title = 'Logaritmo do PIB per capita X Expectativa de vida no ano de 2019')
fig.update_xaxes(title = 'Log (PIB per capita)')
fig.update_yaxes(title = 'Expectativa de vida')
fig.show()
Observe que na África temos os piores índices de PIB per capita e expectativa de vida e a Europa é onde temos os melhores índices. Porém, fica difícil comparar a relação entre os continentes, para resolver esse problema podemos resumir esses gráficos em um só, apenas acrescentando uma variável a mais.

2. Scatter plot Trivariado

Uma variação comum do Scatter plot é a adição de uma terceira variável, o acréscimo de uma terceira variável traz mais informações para o gráfico. A terceira variável pode ser categórica ou numérica. Veremos esses dois casos a seguir.

  • Variável Categórica

Para uma terceira variável que possui valores categóricos (como continente), o mais comum é incluir cor aos pontos, onde cada cor irá associar a um grupo diferente, para isso acrescentamos a opção ‘color‘ na função ‘scatter‘.

fig = px.scatter(df_2019, x = “gdpPercap”, y = “lifeExp”, color = “continent”, 

               hover_name = "country", log_x = True, width = 800)
fig.update_traces(marker=dict(size = 12,line = dict(width = 2)),selector=dict(mode = 'markers'))
fig.update_layout(title = 'Logaritmo do PIB per capita X Expectativa de vida no ano de 2019')
fig.update_xaxes(title = 'Log (PIB per capita)')
fig.update_yaxes(title = 'Expectativa de vida')
fig.show()

Acrescentando a variável continente, observa-se que os países com menores PIB per capita e expectativa de vida são os países da África. E os países com as maiores expectativas de vidas e PIB per capita são da Europa em sua maioria. Vale ressaltar que existe alguns pontos discrepantes, que possui baixa expectativa de vida, como a República Centro-Africa e Lesoto. Além de Suazilândia que mesmo com um PIB mediano, possui uma expectativa de vida menor do que os países com PIB similar. O país com o melhor PIB e expectativa de vida é Singapura. Uma outra maneira de representar uma variável categórica num gráfico de dispersão é utilizando símbolos, para isso utilizamos a opção ‘symbol‘ na função ‘scatter‘, porém fica mais difícil a visualização.

fig = px.scatter(df_2019, x = "gdpPercap", y = "lifeExp", symbol = "continent", hover_name = "country", log_x = True, 
                 size_max = 60, height = 500, width = 1200)
fig.update_traces(marker=dict(size = 12, line = dict(width = 2)), selector=dict(mode = 'markers'))
fig.update_layout(title = 'Logaritmo do PIB per capita X Expectativa de vida no ano de 2019')
fig.update_xaxes(title = 'Log (PIB per capita)')
fig.update_yaxes(title = 'Expectativa de vida')
fig.show()

Para melhorar a visualização podemos utilizar as cores e símbolos

fig = px.scatter(df_2019, x = "gdpPercap", y = "lifeExp", symbol = "continent", color = 'continent', hover_name = "country", 
                 log_x = True, size_max = 60, width = 800)
fig.update_traces(marker = dict(size = 12,line=dict(width=2)),selector=dict(mode = 'markers'))
fig.update_layout(title = 'Logaritmo do PIB per capita X Expectativa de vida no ano de 2019')
fig.update_xaxes(title = 'Log (PIB per capita)')
fig.update_yaxes(title = 'Expectativa de vida')
fig.show()

  • Variável Numérica: Gráfico de Bolhas

Quando temos uma terceira variável numérica, como população, uma variação comum do Scatter plot é em relação ao tamanho dos pontos. Esses gráficos são conhecidos como gráficos de bolhas, onde pontos maiores indicam valores mais altos. Para construir esse gráfico, acrescentamos a opção ‘size’ na função ‘scatter‘.

fig = px.scatter(df_2019, x = "gdpPercap", y = "lifeExp", size = "pop",   
     hover_name = "country", log_x = True, size_max = 60, width = 800) 
fig.update_layout(title = 'Logaritmo do PIB per capita X Expectativa de vida no ano de 2019') 
fig.update_xaxes(title = 'Log (PIB per capita)') fig.update_yaxes(title = 'Expectativa de vida')


Observe que os pontos maiores refere-se a população da China e da Índia. Para melhorar essa visualização podemos acrescentar a opção ‘color’ na função

fig = px.scatter(df_2019, x = "gdpPercap", y = "lifeExp", size = "pop", color = 'pop', 
               hover_name = "country", log_x = True, size_max = 60, width = 800)
fig.update_layout(title = 'Logaritmo do PIB per capita X Expectativa de vida no ano de 2019')
fig.update_xaxes(title = 'Log (PIB per capita)')
fig.update_yaxes(title = 'Expectativa de vida')
fig.show()

Agora temos o tamanho das bolhas e a cor indicando o tamanho populacional, as bolhas amarelas são a China e Índia, paises com maior tamanho populacional.

3. Scatter plot Multivariado

E por último podemos visualizar esse gráfico utilizando 4 variáveis: 3 variáveis numéricas e 1 variável categórica. Aqui utilizaremos a opção size = ‘pop’, para incluir a variável numérica (tamanho população), que irá alterar o tamanho dos pontos de acordo com o tamanho populacional e color = ‘continent’ para incluir a variável categórica (continente), em que cada continente terá uma cor.

fig=px.scatter(df_2019, x = "gdpPercap", y = "lifeExp", size = "pop", color = "continent",
               hover_name = "country", log_x = True, size_max = 60, width = 800)
fig.update_layout(title = 'Logaritmo do PIB per capita X Expectativa de vida no ano de 2019')
fig.update_xaxes(title = 'Log (PIB per capita)')
fig.update_yaxes(title = 'Expectativa de vida')
fig.show()

Uma quinta variável pode ser acrescentada ao gráfico utilizando a opção ‘symbol’, porém teriamos muita informação em um único gráfico e perderíamos informações, além de uma poluição visual.

Também existe a versão 3D desse gráfico, em que acrescentaríamos um eixo a mais, ao invés de mudar o tamanho dos pontos. Assim utilizamos a função ‘scatter_3d’ e uma variável a mais, z = ‘pop’, para a construção do gráfico 3d.

df_2007 = df[df["year"] == 2007]
px.scatter_3d(df_2007, x = "gdpPercap", y = "lifeExp", z = "pop", 
              color = "continent", hover_name = "country", 
              log_x = True, log_z = True)

Apesar dos gráficos 3d serem uma opção de gráfico de dispersão, eles não são recomendados. Como podemos ver, gráficos 3d são difíceis de serem interpretados e visualizados, podendo levar a conclusão errôneas. Logo, Evite gráficos 3d!

4. Scatter plot Animado

O gráfico de dispersão animado é uma opção que podemos fazer quando temos uma variável temporal. No dataset Gapminder temos a variável ano, que mostra o PIB per capita e a Expectativa de vida ao longo do tempo (1920 – 2020).

Utilizaremos essa variável para dar animação para o gráfico, ou seja, para cada ano iremos plotar um gráfico de Scatter plot com 4 variáveis (PIB per capita, Expectativa de vida, Continente e População).

Para isso acrescentamos a opção animation_frame=”year” na função ‘scatter’

px.scatter(df, x = "gdpPercap", y = "lifeExp", animation_frame = "year", animation_group = "country",
           size = "pop", color = "continent", hover_name = "country", log_x = True, width = 900,
           size_max = 60, range_x = [100,100000], range_y = [15,90])

Observe que, na década de 1920, as expectativas de vidas eram bem baixa, a Rússia tinha expectativa de vida de 20 anos e a maior expectativa de vida era da Australia com expectativa de vida de 60 anos.

Também observa-se que a China, em 1920, tinha um dos menores PIB e expectativa de vida. E em 2020 está entre os paises desenvolvidos, com alta expectativa de vida e elevado PIB per capita.

Um país que vale comentar é Singapura, que nos anos de 1920 era uma país com baixos índices de PIB per capita e expectativa de vida e tornou-se o país com o maior PIB per capita e a maior expectativa de vida do mundo. Sendo hoje um dos maiores centros financeiros do mundo e o quarto país mais rico do mundo.

Conclusão

Gráficos de dispersão ou Scatter plot são utilizados para analisar relações entre duas variáveis numéricas. Nesse artigo abordamos diversas variações desse tipo de gráfico e também discutimos alguns problemas desses gráficos.

Além disso, utilizamos a biblioteca plotly do Python para construir gráficos mais agradáveis esteticamente e de maneira simples.

Gostou desse artigo? Você conhece alguma outra variação do gráfico de dispersão que não abordamos? Deixe um comentário.


Tags: | |

Sobre o Autor

Juliana Scudilio
Juliana Scudilio

Doutora e Mestre em Estatística pelo ICMC-USP. Bacharel em Estatística pela UFSCAR. Founder e Data Scientist da flai. Apaixonada por dados e por ensinar.

1 Comentário


Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *