DEV Community

Cover image for Parte 09 - Seaborn - Melhorando seus Visuais
Walter R P Cortes
Walter R P Cortes

Posted on • Originally published at blog.wvcode.com.br on

Parte 09 - Seaborn - Melhorando seus Visuais

Olá Devs!

Se você chegou até aqui, você já se familiarizou com o básico das bibliotecas seaborn, matplotlib e pandas! Esse conhecimento já garante a você a capacidade de realizar análises de dados e apresentar resultados de maneira simples e eficiente.

O próximo passo é ensiná-lo a dar a esses gráficos uma aparência extremamente profissional e que leve em conta as boas práticas da área de Visualização de Dados. Para isso, vamos apresentar um pequeno problema e a versão inicial da visualização com o conhecimento que temos e, depois, apresentamos o passo a passo com as boas práticas e como codifica-las, chegando a nossa versão final da visualização.

Problema

Considere o seguinte cenário: Você é um cientista de dados encarregado de fazer uma análise em cima dos dados da população mundial. Os seus gráficos serão incorporados em uma apresentação PowerPoint.

O gráfico que você deve montar mostra a evolução no tamanho da população dos países do bloco econômico BRICS (Brasil, Russia, India, China e Africa do Sul), fazendo uma comparação com os Estados Unidos. Deve ser um gráfico de barras, onde cada barra irá representar um ano ou década.

O arquivo com os dados pode ser encontrado aqui. Você pode fazer o download e subir no seu Google Colab ou carregar diretamente do endereço.

Solução Passo a Passo

Carregando Bibliotecas

O primeiro passo é sempre carregar as bibliotecas que vamos utilizar.

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

Carregando dados

A próxima etapa é carregar os dados. Durante o curso, utilizamos um arquivo local para fazer isso. Hoje vamos exercitar uma pequena variação. Como explicamos anteriormente, todos os nossos conjuntos de dados estão em um repositório no GitHub -> https://github.com/labeduc/datasets. Ensinamos vocês a baixarem o repositório no seu computador e subir o arquivo que vocês vão trabalhar direto no Google Colab (que é temporário e precisar ser salvo lá cada vez que se abre o notebook) ou colocar no seu Google Drive e mapear o Google Drive no Google Colab.

Agora, vamos explorar uma capacidade da biblioteca pandas que é ler o arquivo direto da internet. O que fizemos foi ir até o Github e observar qual era a URL de download do arquivo que pretendemos usar. Copiamos e colocamos no primeiro parâmetro da função read_csv().

worldpop = pd.read_csv('https://media.githubusercontent.com/media/labeduc/datasets/main/worldpop/world_population.csv')

Para verificar que temos os dados carregados, vamos pedir um sample de 2 linhas.

worldpop.sample(2)
Rank CCA3 Country Capital Continent 2022 Population 2020 Population 2015 Population 2010 Population 2000 Population 1990 Population 1980 Population 1970 Population Area (km²) Density (per km²) Growth Rate World Population Percentage
131 10 MEX Mexico Mexico City North America 127504125 125998302 120149897 112532401 97873442 81720428 67705186 50289306 1964375 64.9082 1.0063 1.60
194 29 KOR South Korea Seoul Asia 51815810 51844690 50994401 48813042 46788591 44120039 38170501 32601143 100210 517.0722 0.9997 0.65

Perfeito, temos os dados, e estamos prontos para prosseguir.

Analisando os dados

A primeira coisa que podemos fazer nesta análise é descobrir quais são todos os campos de conjunto de dados, seus tipos de dados e se temos muitos campos vazios.

worldpop.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 234 entries, 0 to 233
Data columns (total 17 columns):
 # Column Non-Null Count Dtype  
--- ------ -------------- -----  
 0 Rank 234 non-null int64  
 1 CCA3 234 non-null object 
 2 Country 234 non-null object 
 3 Capital 234 non-null object 
 4 Continent 234 non-null object 
 5 2022 Population 234 non-null int64  
 6 2020 Population 234 non-null int64  
 7 2015 Population 234 non-null int64  
 8 2010 Population 234 non-null int64  
 9 2000 Population 234 non-null int64  
 10 1990 Population 234 non-null int64  
 11 1980 Population 234 non-null int64  
 12 1970 Population 234 non-null int64  
 13 Area (km²) 234 non-null int64  
 14 Density (per km²) 234 non-null float64
 15 Growth Rate 234 non-null float64
 16 World Population Percentage 234 non-null float64
dtypes: float64(3), int64(10), object(4)
memory usage: 31.2+ KB

A informação está bem estruturada: todos os campos tem valores, os campos númerico são de um tipo numérico, temos poucas categorias e são do tipo object, que basicamente diz que são texto.

Podemos perceber que estruturalmente, esse conjunto de dados tem um país por linha, com os anos sendo colunas. Em um cenário ideal, os nossos gráficos devem plotar a partir de uma única coluna de valor, e teríamos algum outro atributo para separa-los se for o caso.

Outro ponto a ser considerado é que precisamos apenas dos Estados Unidos e dos países do bloco econômico BRICS, então temos mais dados do que o necessário.

Isso significa que vamos fazer alguns ajustes nos nossos dados.

Transformando os dados

Acompanhem explicações nos comentários.

# Primeira coisa é selecionar apenas as colunas que vamos utilizar
worldpop_sb = worldpop[["Country", 
 "1970 Population",
 "1980 Population",
 "1990 Population",
 "2000 Population",
 "2010 Population",
 "2015 Population",
 "2020 Population",
 "2022 Population"]]

# Em seguida, filtramos as linhas para pegar apenas US e os países do BRICS
worldpop_sb2 = worldpop_sb.query("Country in ('United States', 'Brazil', 'Russia', 'India', 'China', 'South Africa')")

# Fazemos a transformação das colunas de ano em linhas.
brics_us = worldpop_sb2.melt(id_vars='Country', var_name='Year', value_name='Population')

# Pedimos uma amostra para ver como nossos dados ficaram.
# Parece tudo certo, temos apenas paises do BRICS e US,
# no caso do Brasil, vemos agora duas linhas, uma para a
# informação do ano de 2022 e outra para 2015.
brics_us.sample(5)
Country Year Population
1 China 1970 Population 822534450
13 China 1990 Population 1153704252
32 India 2015 Population 1322866505
19 China 2000 Population 1264099069
18 Brazil 2000 Population 175873720

Aí estão nossos dados, devidamente formatados. Vamos agora plotar o gráfico.

Primeira Versão

sns.barplot(brics_us, x='Country', y='Population', hue='Year')

plt.show()

E aí está nosso gráfico. A partir de agora, vamos passo a passo aplicando melhorias sucessivas.

Passo 1 - Adicionando Títulos

Os gráficos precisam de títulos, preferencialmente um título que esclareça o significado do gráfico. Em nossas aulas anteriores, já haviamos adicionado títulos significativos em nossos gráficos e nos eixos também. Então, vamos apenas relembrar.

sns.barplot(brics_us, x='Country', y='Population', hue='Year')
# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('Países')
plt.ylabel('População')

plt.show()

Passo 2 - Ajustando tamanho da imagem

Ao olharmos nosso gráfico, logo percebemos que os nomes dos países estão se sobrepondo no final. Para este e muitos outros ajustes, vamos introduzir a propriedade rcParams. Esta propriedade é um dicionário que armazena outras configurações. Você pode encontrar mais informaç!oes aqui.

# É aconselhavel mudar o tamanho da imagem antes de plotar
# Para tanto, o MatPlotLib nos permite modificar entradas 
# em um dicionário de parâmetros chamado rcParams.
# A nossa modificação será da entrada figure.figsize
# Este parâmetro recebe uma tupla com largura e altura em polegadas
# O valor padrão é 6.4 de largura e 4.8 de altura em polegadas
plt.rcParams["figure.figsize"] = (9,5)

sns.barplot(brics_us, x='Country', y='Population', hue='Year')

# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('Países')
plt.ylabel('População')

plt.show()

Esse tamanho deixou as barras mais separadas, e agora conseguimos ver claramente todos os países.

Passo 3 - Ajustando Qualidade da Imagem

Dentro do contexto de visualização online, nosso gráfico parece bom. Mas, se precisarmos exportar esse gráfico como imagem para usar em um powerpoint, por exemplo, veremos que a qualidade da imagem ficará ruim. Isso acontece porque o padrão do matplotlib é gerar imagens com resolução de 100dpi. Para exportar, normalmente é recomendado utilizar 300dpi. Vamos arrumar isso e ver como fica?

# É aconselhavel mudar o tamanho da imagem antes de plotar
# Para tanto, o MatPlotLib nos permite modificar entradas 
# em um dicionário de parâmetros chamado rcParams.
# A nossa modificação será da entrada figure.figsize
# Este parâmetro recebe uma tupla com largura e altura em polegadas
# O valor padrão é 6.4 de largura e 4.8 de altura em polegadas
plt.rcParams["figure.figsize"] = (9,5)

#Ajustando qualidade da imagem
plt.rcParams["figure.dpi"] = 300
plt.rcParams["savefig.dpi"] = 300
plt.rcParams["savefig.format"] = "svg"

sns.barplot(brics_us, x='Country', y='Population', hue='Year')

# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('Países')
plt.ylabel('População')

plt.show()

Passo 4 - Removendo o “Ruído” do Gráfico

De acordo com as boas práticas na área de visualização, uma boa visualização é limpa, ou seja, não possui elementos que não estejam relacionados aos dados. No gráfico acima, o box em torno do gráfico, a legenda com muito texto, aquela informação 1e9 perdida no gráfico são ruídos, que tiram a atenção das barras que são os dados.

# É aconselhavel mudar o tamanho da imagem antes de plotar
# Para tanto, o MatPlotLib nos permite modificar entradas 
# em um dicionário de parâmetros chamado rcParams.
# A nossa modificação será da entrada figure.figsize
# Este parâmetro recebe uma tupla com largura e altura em polegadas
# O valor padrão é 6.4 de largura e 4.8 de altura em polegadas
plt.rcParams["figure.figsize"] = (9,5)

#Ajustando qualidade da imagem
plt.rcParams["figure.dpi"] = 300
plt.rcParams["savefig.dpi"] = 300
plt.rcParams["savefig.format"] = "svg"

# Para remover parte do box da imagem, fazemos isso:
plt.rcParams["axes.spines.right"] = False
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.bottom"] = False

plt.ticklabel_format(style="plain", useLocale=True)

sns.barplot(brics_us, x='Country', y='Population', hue='Year')

# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('Países')
plt.ylabel('População')

plt.show()

Conseguimos deixar a imagem maior, removemos alguns elementos que adicionavam apenas ruído no gráfico. Mas observem que agora a formatação dos valores no eixo Y está estranho. Vamos corrigir?

# É aconselhavel mudar o tamanho da imagem antes de plotar
# Para tanto, o MatPlotLib nos permite modificar entradas 
# em um dicionário de parâmetros chamado rcParams.
# A nossa modificação será da entrada figure.figsize
# Este parâmetro recebe uma tupla com largura e altura em polegadas
# O valor padrão é 6.4 de largura e 4.8 de altura em polegadas
plt.rcParams["figure.figsize"] = (9,5)

#Ajustando qualidade da imagem
plt.rcParams["figure.dpi"] = 300
plt.rcParams["savefig.dpi"] = 300
plt.rcParams["savefig.format"] = "svg"

# Para remover parte do box da imagem, fazemos isso:
plt.rcParams["axes.spines.right"] = False
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.bottom"] = False

plt.ticklabel_format(style="plain", useLocale=True)

sns.barplot(brics_us, x='Country', y='Population', hue='Year')

# Aqui buscamos os valores que foram adicionados no eixo e os modificamos 
# com a formatação adequada
current_values = plt.gca().get_yticks()
plt.gca().set_yticklabels(['{:,.1f}'.format(x) for x in current_values/1000000000]);

# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('Países')
plt.ylabel('População (bilhões)')

plt.show()
/tmp/ipykernel_382990/823456077.py:26: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.
  plt.gca().set_yticklabels(['{:,.1f}'.format(x) for x in current_values/1000000000]);

Por último, vamos remover o label do eixo X.

# É aconselhavel mudar o tamanho da imagem antes de plotar
# Para tanto, o MatPlotLib nos permite modificar entradas 
# em um dicionário de parâmetros chamado rcParams.
# A nossa modificação será da entrada figure.figsize
# Este parâmetro recebe uma tupla com largura e altura em polegadas
# O valor padrão é 6.4 de largura e 4.8 de altura em polegadas
plt.rcParams["figure.figsize"] = (9,5)

#Ajustando qualidade da imagem
plt.rcParams["figure.dpi"] = 300
plt.rcParams["savefig.dpi"] = 300
plt.rcParams["savefig.format"] = "svg"

# Para remover parte do box da imagem, fazemos isso:
plt.rcParams["axes.spines.right"] = False
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.bottom"] = False

plt.ticklabel_format(style="plain", useLocale=True)

sns.barplot(brics_us, x='Country', y='Population', hue='Year')

# Aqui buscamos os valores que foram adicionados no eixo e os modificamos 
# com a formatação adequada
current_values = plt.gca().get_yticks()
plt.gca().set_yticklabels(['{:,.1f}'.format(x) for x in current_values/1000000000]);

# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('')
plt.ylabel('População (bilhões)')

plt.show()
/tmp/ipykernel_382990/1234354454.py:26: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.
  plt.gca().set_yticklabels(['{:,.1f}'.format(x) for x in current_values/1000000000]);

Passo 5 - Colocando foco nos dados

Agora que trabalhamos na formatação inicial, precisamos realizar melhorias que irão nos ajudar a colocar o foco nos dados. Eis o que vamos fazer: - diminuir a legenda - Alinhar o título a esquerda - o título centralizado faz com que os olhos façam um escaneamento extra do gráfico, dificultando a compreensão - vamos colocar os valores em cima de cada barra. Também para evitar que precisemos olhar no eixo a esquerda para ver o valor de cada barra, ou seja, que fiquemos constantemente escaneando o gráfico - ajustar o tamanho das fontes - ajustar as cores.

Diminuindo a legenda

A princípio, podemos resolver isso manipulando os dados.

brics_us['Year'] = brics_us['Year'].apply(lambda x: x.replace(' Population',''))

Vamos ver o resultado?

# É aconselhavel mudar o tamanho da imagem antes de plotar
# Para tanto, o MatPlotLib nos permite modificar entradas 
# em um dicionário de parâmetros chamado rcParams.
# A nossa modificação será da entrada figure.figsize
# Este parâmetro recebe uma tupla com largura e altura em polegadas
# O valor padrão é 6.4 de largura e 4.8 de altura em polegadas
plt.rcParams["figure.figsize"] = (9,5)

#Ajustando qualidade da imagem
plt.rcParams["figure.dpi"] = 300
plt.rcParams["savefig.dpi"] = 300
plt.rcParams["savefig.format"] = "svg"

# Para remover parte do box da imagem, fazemos isso:
plt.rcParams["axes.spines.right"] = False
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.bottom"] = False

plt.ticklabel_format(style="plain", useLocale=True)

sns.barplot(brics_us, x='Country', y='Population', hue='Year')

# Aqui buscamos os valores que foram adicionados no eixo e os modificamos 
# com a formatação adequada
current_values = plt.gca().get_yticks()
plt.gca().set_yticklabels(['{:,.1f}'.format(x) for x in current_values/1000000000]);

# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('')
plt.ylabel('População (bilhões)')

plt.show()
/tmp/ipykernel_382990/1234354454.py:26: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.
  plt.gca().set_yticklabels(['{:,.1f}'.format(x) for x in current_values/1000000000]);

Alinhar o Titulo e Diminuir fontes

# É aconselhavel mudar o tamanho da imagem antes de plotar
# Para tanto, o MatPlotLib nos permite modificar entradas 
# em um dicionário de parâmetros chamado rcParams.
# A nossa modificação será da entrada figure.figsize
# Este parâmetro recebe uma tupla com largura e altura em polegadas
# O valor padrão é 6.4 de largura e 4.8 de altura em polegadas
plt.rcParams["figure.figsize"] = (9,5)

#Ajustando qualidade da imagem
plt.rcParams["figure.dpi"] = 300
plt.rcParams["savefig.dpi"] = 300
plt.rcParams["savefig.format"] = "svg"

# Para remover parte do box da imagem, fazemos isso:
plt.rcParams["axes.spines.right"] = False
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.bottom"] = False

#Fontes
plt.rcParams["legend.fontsize"] = 5
plt.rcParams["legend.title_fontsize"] = 6
plt.rcParams["legend.frameon"] = False

plt.ticklabel_format(style="plain", useLocale=True)
plt.tick_params(axis='both', which='major', labelsize=6)

sns.barplot(brics_us, x='Country', y='Population', hue='Year')

# Aqui buscamos os valores que foram adicionados no eixo e os modificamos 
# com a formatação adequada
current_values = plt.gca().get_yticks()
plt.gca().set_yticklabels(['{:,.1f}'.format(x) for x in current_values/1000000000]);

# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)', fontsize=8, loc='left')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('')
plt.ylabel('População (bilhões)')

plt.show()
/tmp/ipykernel_382990/1419233821.py:32: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.
  plt.gca().set_yticklabels(['{:,.1f}'.format(x) for x in current_values/1000000000]);

Removendo o eixo Y e adicionando os valores nas barras

# É aconselhavel mudar o tamanho da imagem antes de plotar
# Para tanto, o MatPlotLib nos permite modificar entradas 
# em um dicionário de parâmetros chamado rcParams.
# A nossa modificação será da entrada figure.figsize
# Este parâmetro recebe uma tupla com largura e altura em polegadas
# O valor padrão é 6.4 de largura e 4.8 de altura em polegadas
plt.rcParams["figure.figsize"] = (9,5)

#Ajustando qualidade da imagem
plt.rcParams["figure.dpi"] = 300
plt.rcParams["savefig.dpi"] = 300
plt.rcParams["savefig.format"] = "svg"

# Para remover parte do box da imagem, fazemos isso:
plt.rcParams["axes.spines.left"] = False
plt.rcParams["axes.spines.right"] = False
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.bottom"] = False

#Fontes
plt.rcParams["legend.fontsize"] = 5
plt.rcParams["legend.title_fontsize"] = 6
plt.rcParams["legend.frameon"] = False

plt.ticklabel_format(style="plain", useLocale=True)
plt.tick_params(axis='both', which='major', labelsize=6)

sx = sns.barplot(brics_us, x='Country', y='Population', hue='Year')

# Aqui buscamos os valores que foram adicionados no eixo e os modificamos 
# com a formatação adequada
current_values = plt.gca().get_yticks()
plt.gca().set_yticklabels(['{:,.1f}'.format(x) for x in current_values/1000000000]);

# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)', fontsize=8, loc='left')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('')

# Removendo todo o eixo Y
sx.get_yaxis().set_visible(False)

# O Objeto patches contém todos os elementos (neste caso barras) que foram plotados no gráfico
# Então percorremos eles e fazemos os seguintes calculos:
# a coordenada x para posicionar o texto = Coordenada X do canto superior da barra + largura da barra / 2
# a coordenada Y para posicionar o texto = Coordenada Y do canto superior da barra + 1% desta altura
for p in sx.patches:
 _x = (p.get_x() + p.get_width() / 2)
 _y = p.get_y() + p.get_height() + (p.get_height()*0.01)
 value = '{:.2f}'.format(p.get_height()/1000000000)
 sx.text(_x, _y, value, ha="center", size=3) 

plt.show()
/tmp/ipykernel_382990/1997790246.py:33: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.
  plt.gca().set_yticklabels(['{:,.1f}'.format(x) for x in current_values/1000000000]);

Acertando as cores

A paleta de cores precisa ser ajustada para respeitar as cores da empresa.

# É aconselhavel mudar o tamanho da imagem antes de plotar
# Para tanto, o MatPlotLib nos permite modificar entradas 
# em um dicionário de parâmetros chamado rcParams.
# A nossa modificação será da entrada figure.figsize
# Este parâmetro recebe uma tupla com largura e altura em polegadas
# O valor padrão é 6.4 de largura e 4.8 de altura em polegadas
plt.rcParams["figure.figsize"] = (9,5)

#Definindo a paleta de cores
cores = ["#0c4f6a", "#177498", "#0a8faa", "#bfdce5", "#82bd4a", "#b8d67a", "#b2b3b6", "#58585a", "#edb634", "#d97933", "#f1bdb1", "#eca091", "#e26c54", "#b0391e"]
sns.set_palette(sns.color_palette(cores))

#Ajustando qualidade da imagem
plt.rcParams["figure.dpi"] = 300
plt.rcParams["savefig.dpi"] = 300
plt.rcParams["savefig.format"] = "svg"

# Para remover parte do box da imagem, fazemos isso:
plt.rcParams["axes.spines.left"] = False
plt.rcParams["axes.spines.right"] = False
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.bottom"] = False

#Fontes
plt.rcParams["legend.fontsize"] = 5
plt.rcParams["legend.title_fontsize"] = 6
plt.rcParams["legend.frameon"] = False

plt.ticklabel_format(style="plain", useLocale=True)
plt.tick_params(axis='both', which='major', labelsize=6)

sx = sns.barplot(brics_us, x='Country', y='Population', hue='Year')

# Aqui buscamos os valores que foram adicionados no eixo e os modificamos 
# com a formatação adequada
current_values = plt.gca().get_yticks().tolist()
formatted_values = ['{:,.1f}'.format(x/1000000000) for x in current_values]
plt.gca().set_yticklabels(formatted_values)

# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)', fontsize=8, loc='left')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('')

# Removendo todo o eixo Y
sx.get_yaxis().set_visible(False)

# O Objeto patches contém todos os elementos (neste caso barras) que foram plotados no gráfico
# Então percorremos eles e fazemos os seguintes calculos:
# a coordenada x para posicionar o texto = Coordenada X do canto superior da barra + largura da barra / 2
# a coordenada Y para posicionar o texto = Coordenada Y do canto superior da barra + 1% desta altura
for p in sx.patches:
 _x = (p.get_x() + p.get_width() / 2)
 _y = p.get_y() + p.get_height() + (p.get_height()*0.01)
 value = '{:.2f}'.format(p.get_height()/1000000000)
 sx.text(_x, _y, value, ha="center", size=3) 

plt.show()
/tmp/ipykernel_382990/620366550.py:38: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.
  plt.gca().set_yticklabels(formatted_values)

E aí está o nosso gráfico, com suas cores modificadas. Para este gráfico ficar realmente bom, faltam apenas duas correções: deixar nossas barras um pouco mais largas para que possamos aumentar a fonte dos valores.

# É aconselhavel mudar o tamanho da imagem antes de plotar
# Para tanto, o MatPlotLib nos permite modificar entradas 
# em um dicionário de parâmetros chamado rcParams.
# A nossa modificação será da entrada figure.figsize
# Este parâmetro recebe uma tupla com largura e altura em polegadas
# O valor padrão é 6.4 de largura e 4.8 de altura em polegadas
plt.rcParams["figure.figsize"] = (9,5)

#Definindo a paleta de cores
cores = ["#0c4f6a", "#177498", "#0a8faa", "#bfdce5", "#82bd4a", "#b8d67a", "#b2b3b6", "#58585a", "#edb634", "#d97933", "#f1bdb1", "#eca091", "#e26c54", "#b0391e"]
sns.set_palette(sns.color_palette(cores))

#Ajustando qualidade da imagem
plt.rcParams["figure.dpi"] = 300
plt.rcParams["savefig.dpi"] = 300
plt.rcParams["savefig.format"] = "svg"

# Para remover parte do box da imagem, fazemos isso:
plt.rcParams["axes.spines.left"] = False
plt.rcParams["axes.spines.right"] = False
plt.rcParams["axes.spines.top"] = False
plt.rcParams["axes.spines.bottom"] = False

#Fontes
plt.rcParams["legend.fontsize"] = 5
plt.rcParams["legend.title_fontsize"] = 6
plt.rcParams["legend.frameon"] = False

plt.ticklabel_format(style="plain", useLocale=True)
plt.tick_params(axis='both', which='major', labelsize=6)

# O padrão para tamanho das barras é 0.8. Quando colocamos 1, as barras se encostam. 
# Portanto, aumentamos para 0.95 para que não se encostem, mas fiquem mais largas.
# A nossa outra alteração foi na rotina que imprime os valores, onde pudemos ajustar
# o tamanho da fonte de 3 para 4
sx = sns.barplot(brics_us, x='Country', y='Population', hue='Year', width=0.95)

# Aqui buscamos os valores que foram adicionados no eixo e os modificamos 
# com a formatação adequada
current_values = plt.gca().get_yticks().tolist()
formatted_values = ['{:,.1f}'.format(x/1000000000) for x in current_values]
plt.gca().set_yticklabels(formatted_values)

# Esta função adiciona um título no gráfico
plt.title('Crescimento Populacional no BRICS (1970 - 2020)', fontsize=8, loc='left')

# Estas funções nos permitem alterar o títulos nos eixos
plt.xlabel('')

# Removendo todo o eixo Y
sx.get_yaxis().set_visible(False)

# O Objeto patches contém todos os elementos (neste caso barras) que foram plotados no gráfico
# Então percorremos eles e fazemos os seguintes calculos:
# a coordenada x para posicionar o texto = Coordenada X do canto superior da barra + largura da barra / 2
# a coordenada Y para posicionar o texto = Coordenada Y do canto superior da barra + 1% desta altura
for p in sx.patches:
 _x = (p.get_x() + p.get_width() / 2)
 _y = p.get_y() + p.get_height() + (p.get_height()*0.01)
 value = '{:.2f}'.format(p.get_height()/1000000000)
 sx.text(_x, _y, value, ha="center", size=4) 

# Essa alteração foi no improviso, pois estava dizendo Year, ou seja,
# uma parte do gráfico utilizava um idioma diferente.
plt.legend(title='Ano')

plt.show()
/var/folders/fc/hns7cg2j2xg_05kdl6cbxkw40000gn/T/ipykernel_47418/1546591451.py:42: UserWarning: FixedFormatter should only be used together with FixedLocator
  plt.gca().set_yticklabels(formatted_values)

Acho que agora, estamos prontos para enviar esse belo gráfico para quem vai usá-lo!


Conclusão

Nesta aula, aprendemos sobre como configurar nossos gráficos para que fiquem com uma aparência mais profissional e respeitem as boas práticas da área de Visualização de Dados. Vamos deixar também os links para as documentações das bibliotecas que utilizamos: - Seaborn - Matplotlib

Este artigo também marca o final da nossa série Visualização de Dados com Python! Com o conhecimento aqui compartilhado, você já é capaz de criar visualizações de dados incríveis e profissionais. Esperamos que você tenha gostado e que tenha aprendido muito!

Até a próxima!

Walter

Top comments (0)