Tópico 7 – DataViz: Visualizando Dados 📈

Um pouco de como representar dados de forma visual!

Resultados Esperados

  1. Junto com a aula passada, ferramentas simples para exploração de dados
  2. Aprender a base de pandas para realizar um plot simples
  3. Aprender conceitos básicos de visualização dados

Material Adaptado do DSC10 (UCSD)

#In: 
# Descomente e execute as linhas a seguir para usar o BabyPandas e o PandasTutor
# (faça isso apenas se não tiver instalado ainda)
# ! pip install babypandas
#In: 
import numpy as np
import babypandas as bpd

import matplotlib.pyplot as plt
plt.style.use('ggplot')

from IPython.display import HTML, display, IFrame

Além: atalhos de teclado

Existem vários atalhos de teclado integrados aos Jupyter Notebooks projetados para ajudar você a economizar tempo. Para vê-los, clique no botão do teclado na barra de ferramentas acima ou pressione a tecla H do teclado (desde que você não esteja editando ativamente uma célula).

Atalhos particularmente úteis:

AçãoAtalho de teclado
Executar célula + pular para a próxima célulaMUDANÇA + ENTER
Salve o cadernoCTRL/CMD + S
Criar nova célula acima/abaixoA/B
Excluir célulaDD

Agenda

  • Por que visualizar?
  • Terminologia.
  • Gráficos de dispersão.
  • Gráficos de linha.
  • Gráficos de barra.

Por que visualizar?

Marcha de Napoleão

Por que visualizar?

  • Os computadores são melhores que os humanos para processar números, mas os humanos são melhores para identificar padrões visuais.

  • As visualizações permitem-nos compreender rapidamente muitos dados – tornam mais fácil identificar tendências e comunicar os nossos resultados a outras pessoas.

  • Existem vários tipos de visualizações; nesta aula, veremos gráficos de dispersão, gráficos de linhas, gráficos de barras e histogramas, mas existem muitos outros.
  • A escolha certa depende do tipo de dados.

Terminologia

Indivíduos e variáveis

<img src='https://raw.githubusercontent.com/flaviovdf/fcd/master/assets/07-DataViz/images/ind-var.png' largura=90%/>
  • Indivíduo (linha): Pessoa/lugar/coisa para a qual os dados são registrados. Também chamada de observação.

  • Variável (coluna): Algo que é registrado para cada indivíduo. Também chamado de recurso.

Tipos de variáveis

Existem dois tipos principais de variáveis:

  • Numérico: Faz sentido fazer aritmética com os valores.
  • Categórico: Os valores se enquadram em categorias, que podem ou não ter alguma ordem para eles.

Exemplos de variáveis ​​numéricas

  • Salários dos jogadores da NBA 🏀.
  • Individual: um jogador da NBA.
  • Variável: seu salário.

  • Ganhos brutos do filme 💰.
  • Individual: um filme.
  • Variável: seu rendimento bruto.

  • Doses de reforço administradas por dia 💉.
  • Individual: data.
  • Variável: número de doses de reforço administradas naquela data.

Exemplos de variáveis ​​​​categóricas

  • Gêneros de filmes 🎬.
  • Individual: um filme.
  • Variável: seu gênero.

  • CEPs 🏠.
  • Pessoa física: residente nos EUA.
  • Variável: CEP.
  • Apesar de parecerem números, os CEPs são categóricos (a aritmética não faz sentido).

  • Nível de experiência anterior em programação para alunos do DSC 10 🧑‍🎓.
  • Individual: aluno do DSC 10.
  • Variável: seu nível de experiência anterior em programação, por ex. nenhum, baixo, médio ou alto.
  • Existe uma ordem para essas categorias!

Verificação de conceito ✅

Qual destas não é uma variável numérica?

A. Economia de combustível em milhas por galão.

B. Número de trimestres na UCSD.

C. Faculdade na UCSD (sexto, sétimo, etc).

D. Número da conta bancária.

E. Mais de uma destas não são variáveis ​​numéricas.

Tipos de visualizações

O tipo de visualização que criamos depende dos tipos de variáveis ​​que estamos visualizando.

  • Gráfico de dispersão: numérico versus numérico.
  • Gráfico de linhas: numérico sequencial (tempo) vs.
  • Gráfico de barras: categórico vs. numérico.
  • Histograma: numérico.
  • Cobriremos na próxima vez.

Observação: Podemos trocar as palavras “plot”, “chart” e “graph”; todos eles significam a mesma coisa.

Gráficos de dispersão

Conjunto de dados dos 50 atores de maior bilheteria

ColunaConteúdo
'Ator'Nome do ator
'Total Bruto'Receita total bruta de bilheteria interna, em milhões de dólares, de todos os filmes do ator
'Número de filmes'O número de filmes em que o ator esteve
'Média por Filme'Total bruto dividido pelo número de filmes
'Filme #1'O filme de maior bilheteria em que o ator já esteve
'Bruto'Receita bruta de bilheteria interna, em milhões de dólares, do filme número 1 do ator
#In: 
actors = bpd.read_csv('https://raw.githubusercontent.com/flaviovdf/fcd/master/assets/07-DataViz/data/actors.csv').set_index('Actor')
actors
Total GrossNumber of MoviesAverage per Movie#1 MovieGross
Actor
Harrison Ford4871.741118.8Star Wars: The Force Awakens936.7
Samuel L. Jackson4772.86969.2The Avengers623.4
Morgan Freeman4468.36173.3The Dark Knight534.9
Tom Hanks4340.84498.7Toy Story 3415.0
Robert Downey, Jr.3947.35374.5The Avengers623.4
..................
Jeremy Renner2500.321119.1The Avengers623.4
Philip Seymour Hoffman2463.74061.6Catching Fire424.7
Sandra Bullock2462.63570.4Minions336.0
Chris Evans2457.823106.9The Avengers623.4
Anne Hathaway2416.52596.7The Dark Knight Rises448.1

50 rows × 5 columns

Gráficos de dispersão

Qual é a relação entre 'Número de Filmes' e 'Total Bruto'?

#In: 
actors.plot(kind='scatter', x='Number of Movies', y='Total Gross');

png

Gráficos de dispersão

  • Os gráficos de dispersão visualizam a relação entre duas variáveis ​​numéricas.
  • Para criar um a partir de um DataFrame df, use
    df.plot(
      kind='scatter', 
      x=x_column_for_horizontal, 
      y=y_column_for_vertical
    )
    
  • O gráfico de dispersão resultante tem um ponto por linha de df.
  • Se você colocar um ponto e vírgula após uma chamada para .plot, isso ocultará a saída de texto estranha exibida.

Gráficos de dispersão

Qual é a relação entre 'Número de Filmes' e 'Média por Filme'?

#In: 
actors.plot(kind='scatter', x='Number of Movies', y='Average per Movie');

png

Observe que no gráfico acima, há uma associação negativa e um valor discrepante.

Quem esteve em 60 ou mais filmes?

#In: 
actors[actors.get('Number of Movies') >= 60]
Total GrossNumber of MoviesAverage per Movie#1 MovieGross
Actor
Samuel L. Jackson4772.86969.2The Avengers623.4
Morgan Freeman4468.36173.3The Dark Knight534.9
Bruce Willis3189.46053.2Sixth Sense293.5
Robert DeNiro3081.37939.0Meet the Fockers279.3
Liam Neeson2942.76346.7The Phantom Menace474.5

Quem é o estranho?

Quem quer que sejam, fizeram poucos filmes de alta bilheteria.

#In: 
actors[actors.get('Number of Movies') < 10]
Total GrossNumber of MoviesAverage per Movie#1 MovieGross
Actor
Anthony Daniels3162.97451.8Star Wars: The Force Awakens936.7

Anthony Daniels

Gráficos de linha 📉

Conjunto de dados agregando filmes por ano

ColunaConteúdo
'Ano'Ano
'Total Bruto em Bilhões'Total bruto de bilheteria doméstica, em bilhões de dólares, de todos os filmes lançados
'Número de filmes'Número de filmes lançados
'Filme #1'Filme de maior bilheteria
#In: 
movies_by_year = bpd.read_csv('https://raw.githubusercontent.com/flaviovdf/fcd/master/assets/07-DataViz/data/movies_by_year.csv').set_index('Year')
movies_by_year
Total Gross in BillionsNumber of Movies#1 Movie
Year
20225.64380Top Gun: Maverick
20214.48439Spider-Man: No Way Home
20202.11456Bad Boys for Life
201911.36910Avengers: Endgame
201811.89993Black Panther
............
19810.9056Superman II
19801.6468Star Wars: Episode V - The Empire Strikes Back
19791.2340Superman
19780.8313Grease
19770.449Star Wars: Episode IV - A New Hope

46 rows × 3 columns

Gráficos de linha

Como o número de filmes mudou ao longo do tempo? 🤔

#In: 
movies_by_year.plot(kind='line', y='Number of Movies');

png

Gráficos de linha

  • Os gráficos de linhas mostram tendências em variáveis ​​numéricas ao longo do tempo.
  • Para criar um a partir de um DataFrame df, use
    df.plot(
      kind='line', 
      x=x_column_for_horizontal, 
      y=y_column_for_vertical
    )
    

Dica de plotagem

  • Dica: se você quiser que o eixo x seja o índice, omita o argumento x=!
  • Não funciona para gráficos de dispersão, mas funciona para a maioria dos outros tipos de gráficos.
#In: 
movies_by_year.plot(kind='line', y='Number of Movies');

png

Desde o ano 2000

Podemos criar um gráfico de linhas de apenas 2.000 em diante consultando movies_by_year antes de chamar .plot.

#In: 
movies_by_year[movies_by_year.index >= 2000].plot(kind='line', y='Number of Movies');

png

O que você acha que explica as quedas em torno de 2008 e 2020?

Como isso afetou o total bruto?

#In: 
movies_by_year[movies_by_year.index >= 2000].plot(kind='line', y='Total Gross in Billions');

png

Qual foi o filme de maior bilheteria de 2016? 🐟

#In: 
...
Ellipsis

Gráficos de barras 📊

Conjunto de dados das 200 melhores músicas dos EUA no Spotify no sábado (21/01/23)

Downloaded from here – check it out!

#In: 
charts = (bpd.read_csv('https://raw.githubusercontent.com/flaviovdf/fcd/master/assets/07-DataViz/data/regional-us-daily-2023-01-21.csv')
          .set_index('rank')
          .get(['track_name', 'artist_names', 'streams', 'uri'])
         )
charts
track_nameartist_namesstreamsuri
rank
1FlowersMiley Cyrus3356361spotify:track:0yLdNVWF3Srea0uzk55zFn
2Kill BillSZA2479445spotify:track:1Qrg8KqiBpW07V7PNxwwwL
3Creepin' (with The Weeknd & 21 Savage)Metro Boomin, The Weeknd, 21 Savage1337320spotify:track:2dHHgzDwk4BJdRwy9uXhTO
4Superhero (Heroes & Villains) [with Future & C...Metro Boomin, Future, Chris Brown1235285spotify:track:0vjeOZ3Ft5jvAi9SBFJm1j
5Rich FlexDrake, 21 Savage1109704spotify:track:1bDbXMyjaUIooNwFE9wn0N
...............
196Burn, Burn, BurnZach Bryan267772spotify:track:5jfhLCSIFUO4ndzNRh4w4G
197LET GOCentral Cee267401spotify:track:3zkyus0njMCL6phZmNNEeN
198Major DistributionDrake, 21 Savage266986spotify:track:46s57QULU02Voy0Kup6UEb
199Sun to MeZach Bryan266968spotify:track:1SjsVdSXpwm1kTdYEHoPIT
200The Real Slim ShadyEminem266698spotify:track:3yfqSUWxFvZELEM4PmlwIR

200 rows × 4 columns

Gráficos de barra

Quantos streams as 10 músicas mais populares têm?

#In: 
charts
track_nameartist_namesstreamsuri
rank
1FlowersMiley Cyrus3356361spotify:track:0yLdNVWF3Srea0uzk55zFn
2Kill BillSZA2479445spotify:track:1Qrg8KqiBpW07V7PNxwwwL
3Creepin' (with The Weeknd & 21 Savage)Metro Boomin, The Weeknd, 21 Savage1337320spotify:track:2dHHgzDwk4BJdRwy9uXhTO
4Superhero (Heroes & Villains) [with Future & C...Metro Boomin, Future, Chris Brown1235285spotify:track:0vjeOZ3Ft5jvAi9SBFJm1j
5Rich FlexDrake, 21 Savage1109704spotify:track:1bDbXMyjaUIooNwFE9wn0N
...............
196Burn, Burn, BurnZach Bryan267772spotify:track:5jfhLCSIFUO4ndzNRh4w4G
197LET GOCentral Cee267401spotify:track:3zkyus0njMCL6phZmNNEeN
198Major DistributionDrake, 21 Savage266986spotify:track:46s57QULU02Voy0Kup6UEb
199Sun to MeZach Bryan266968spotify:track:1SjsVdSXpwm1kTdYEHoPIT
200The Real Slim ShadyEminem266698spotify:track:3yfqSUWxFvZELEM4PmlwIR

200 rows × 4 columns

#In: 
charts.take(np.arange(10))
track_nameartist_namesstreamsuri
rank
1FlowersMiley Cyrus3356361spotify:track:0yLdNVWF3Srea0uzk55zFn
2Kill BillSZA2479445spotify:track:1Qrg8KqiBpW07V7PNxwwwL
3Creepin' (with The Weeknd & 21 Savage)Metro Boomin, The Weeknd, 21 Savage1337320spotify:track:2dHHgzDwk4BJdRwy9uXhTO
4Superhero (Heroes & Villains) [with Future & C...Metro Boomin, Future, Chris Brown1235285spotify:track:0vjeOZ3Ft5jvAi9SBFJm1j
5Rich FlexDrake, 21 Savage1109704spotify:track:1bDbXMyjaUIooNwFE9wn0N
6Shakira: Bzrp Music Sessions, Vol. 53Bizarrap, Shakira1051226spotify:track:4nrPB8O7Y7wsOCJdgXkthe
7Just Wanna RockLil Uzi Vert998684spotify:track:4FyesJzVpA39hbYvcseO2d
8Anti-HeroTaylor Swift936166spotify:track:0V3wPSX9ygBnCm8psDIegu
9golden hourJVKE870031spotify:track:5odlY52u43F5BjByhxg7wg
10Unholy (feat. Kim Petras)Sam Smith, Kim Petras859271spotify:track:3nqQXoyQOWXiESFLlDF1hG
#In: 
charts.take(np.arange(10)).plot(kind='barh', x='track_name', y='streams');

png

Gráficos de barra

  • Os gráficos de barras visualizam a relação entre uma variável categórica e uma variável numérica.
  • Em um gráfico de barras…
  • A espessura e o espaçamento das barras são arbitrários.
  • A ordem dos rótulos categóricos não importa.
  • Para criar um a partir de um DataFrame df, use
    df.plot(
      kind='barh', 
      x=categorical_column_name, 
      y=numerical_column_name
    )
    
  • O “h” em 'barh' significa “horizontal”.
  • É mais fácil ler os rótulos desta forma.
  • No gráfico anterior, definimos y='Streams' mesmo que os streams sejam medidos pelo comprimento do eixo x.
#In: 
# The bars appear in the opposite order relative to the DataFrame
(charts
 .take(np.arange(10))
 .sort_values(by='streams')
 .plot(kind='barh', x='track_name', y='streams')
);

png

Quantas músicas os 15 melhores artistas têm entre os 200 melhores?

Primeiro, vamos criar um DataFrame com uma única coluna que descreve o número de músicas entre as 200 melhores por artista. Isso envolve usar .groupby com .count(). Como queremos uma linha por artista, agruparemos por 'nomes_artistas'.

#In: 
charts
track_nameartist_namesstreamsuri
rank
1FlowersMiley Cyrus3356361spotify:track:0yLdNVWF3Srea0uzk55zFn
2Kill BillSZA2479445spotify:track:1Qrg8KqiBpW07V7PNxwwwL
3Creepin' (with The Weeknd & 21 Savage)Metro Boomin, The Weeknd, 21 Savage1337320spotify:track:2dHHgzDwk4BJdRwy9uXhTO
4Superhero (Heroes & Villains) [with Future & C...Metro Boomin, Future, Chris Brown1235285spotify:track:0vjeOZ3Ft5jvAi9SBFJm1j
5Rich FlexDrake, 21 Savage1109704spotify:track:1bDbXMyjaUIooNwFE9wn0N
...............
196Burn, Burn, BurnZach Bryan267772spotify:track:5jfhLCSIFUO4ndzNRh4w4G
197LET GOCentral Cee267401spotify:track:3zkyus0njMCL6phZmNNEeN
198Major DistributionDrake, 21 Savage266986spotify:track:46s57QULU02Voy0Kup6UEb
199Sun to MeZach Bryan266968spotify:track:1SjsVdSXpwm1kTdYEHoPIT
200The Real Slim ShadyEminem266698spotify:track:3yfqSUWxFvZELEM4PmlwIR

200 rows × 4 columns

#In: 
songs_per_artist = charts.groupby('artist_names').count()
songs_per_artist
track_namestreamsuri
artist_names
21 Savage, Metro Boomin111
80purppp111
A Boogie Wit da Hoodie111
Arctic Monkeys222
Arcángel, Bad Bunny111
............
XXXTENTACION111
Yeat111
Zach Bryan444
d4vd222
Ñengo Flow, Bad Bunny111

145 rows × 3 columns

Usando .sort_values e .take, manteremos apenas os 15 melhores artistas. Observe que todas as colunas em songs_per_artist contêm as mesmas informações (isso é uma consequência do uso de .count()).

#In: 
top_15_artists = (songs_per_artist
                  .sort_values('streams', ascending=False)
                  .take(np.arange(15)))
top_15_artists
track_namestreamsuri
artist_names
SZA111111
Taylor Swift888
Morgan Wallen666
Drake, 21 Savage555
Zach Bryan444
............
Joji222
Eminem222
Kanye West222
Childish Gambino222
NewJeans222

15 rows × 3 columns

Usando .assign e .drop, criaremos uma coluna chamada 'count' que contém as mesmas informações que as outras 3 colunas contêm, e então .get apenas essa coluna (ou equivalentemente, eliminaremos o outras 3 colunas).

#In: 
# If we give .get a list, it will return a DataFrame instead of a Series!
top_15_artists = (top_15_artists
                  .assign(count=top_15_artists.get('streams'))
                  .get(['count']))
top_15_artists
count
artist_names
SZA11
Taylor Swift8
Morgan Wallen6
Drake, 21 Savage5
Zach Bryan4
......
Joji2
Eminem2
Kanye West2
Childish Gambino2
NewJeans2

15 rows × 1 columns

Antes de chamar .plot(kind='barh', y='count'), classificaremos top_15_artists por 'count' em ordem crescente. Isso ocorre porque, estranhamente, o Python inverte a ordem das linhas ao criar barras em gráficos de barras horizontais.

#In: 
top_15_artists.sort_values(by='count').plot(kind='barh', y='count');

png

Gráficos de barras verticais

Para criar um gráfico de barras verticais, use kind='bar' em vez de kind='barh'. No entanto, geralmente são mais difíceis de ler.

#In: 
top_15_artists.plot(kind='bar', y='count');

png

À parte: quantas transmissões as músicas do The Weeknd na parada receberam?

#In: 
(charts
 [charts.get('artist_names') == 'The Weeknd']
 .sort_values('streams')
 .plot(kind='barh', x='track_name', y='streams')
);

png

Parece que estamos perdendo algumas músicas populares…

Como incluímos músicas em destaque também?

Resposta: Usando .str.contains.

#In: 
weeknd = charts[charts.get('artist_names').str.contains('The Weeknd')]
weeknd
track_nameartist_namesstreamsuri
rank
3Creepin' (with The Weeknd & 21 Savage)Metro Boomin, The Weeknd, 21 Savage1337320spotify:track:2dHHgzDwk4BJdRwy9uXhTO
13Die For YouThe Weeknd794924spotify:track:2LBqCSwhJGcFQeTHMVGwy3
76Stargirl InterludeThe Weeknd, Lana Del Rey372624spotify:track:5gDWsRxpJ2lZAffh5p7K0w
78StarboyThe Weeknd, Daft Punk361999spotify:track:7MXVkk9YMctZqd1Srtv4MB
102The HillsThe Weeknd334354spotify:track:7fBv7CLKzipRk6EC6TWHOB
110I Was Never ThereThe Weeknd, Gesaffelstein328724spotify:track:1cKHdTo9u0ZymJdPGSh6nq
128Blinding LightsThe Weeknd311176spotify:track:0VjIjW4GlUZAMYd2vXMi3b
168Call Out My NameThe Weeknd281141spotify:track:09mEdoA6zrmBPgTEN5qXmN
#In: 
weeknd.sort_values('streams').plot(kind='barh', x='track_name', y='streams');

png

Demonstração divertida 🎵

#In: 
# Run this cell, don't worry about what it does.
def show_spotify(uri):
    code = uri[uri.rfind(':')+1:]
    src = f"https://open.spotify.com/embed/track/{code}"
    width = 400
    height = 75
    display(IFrame(src, width, height))

Vamos encontrar o URI de uma música que nos interessa.

#In: 
charts
track_nameartist_namesstreamsuri
rank
1FlowersMiley Cyrus3356361spotify:track:0yLdNVWF3Srea0uzk55zFn
2Kill BillSZA2479445spotify:track:1Qrg8KqiBpW07V7PNxwwwL
3Creepin' (with The Weeknd & 21 Savage)Metro Boomin, The Weeknd, 21 Savage1337320spotify:track:2dHHgzDwk4BJdRwy9uXhTO
4Superhero (Heroes & Villains) [with Future & C...Metro Boomin, Future, Chris Brown1235285spotify:track:0vjeOZ3Ft5jvAi9SBFJm1j
5Rich FlexDrake, 21 Savage1109704spotify:track:1bDbXMyjaUIooNwFE9wn0N
...............
196Burn, Burn, BurnZach Bryan267772spotify:track:5jfhLCSIFUO4ndzNRh4w4G
197LET GOCentral Cee267401spotify:track:3zkyus0njMCL6phZmNNEeN
198Major DistributionDrake, 21 Savage266986spotify:track:46s57QULU02Voy0Kup6UEb
199Sun to MeZach Bryan266968spotify:track:1SjsVdSXpwm1kTdYEHoPIT
200The Real Slim ShadyEminem266698spotify:track:3yfqSUWxFvZELEM4PmlwIR

200 rows × 4 columns

#In: 
favorite_song = 'Bejeweled'
#In: 
song_uri = (charts
            [charts.get('track_name') == favorite_song]
            .get('uri')
            .iloc[0])
song_uri
'spotify:track:3qoftcUZaUOncvIYjFSPdE'

Veja o que acontece! 🎶

#In: 
show_spotify(song_uri)

Experimente você mesmo!

Visualizações ruins

  • Conforme mencionado anteriormente, as visualizações nos permitem identificar facilmente tendências e comunicar nossos resultados a outras pessoas.
  • Algumas visualizações tornam mais difícil ver a tendência nos dados, ao:

  • Adicionando “chart junk.”

  • Usando eixos e tamanhos enganosos.

Resumo

Resumo

  • As visualizações facilitam a extração de padrões de conjuntos de dados.
  • Existem dois tipos principais de variáveis: categóricas e numéricas.
  • Os tipos de variáveis ​​que estamos visualizando informam nossa escolha de qual tipo de visualização usar.
  • Hoje, analisamos gráficos de dispersão, gráficos de linhas e gráficos de barras.
  • Próxima vez: Histogramas e gráficos sobrepostos.