A importância de colocar contexto e conclusão nos gráficos

Talietta
Data Hackers
Published in
6 min readNov 8, 2019

Algo bom para você não é necessariamente bom para mim

Bom dia, cientistas de dados xeretas.

Vou contar a história do Rober e veja se acontece esse mesmo tipo de problema com alguns de vocês: Rober era um cientista de dados que já tinha feito algumas análises incríveis, e numa delas alcançou uma daquelas conclusões mindblowing.

Todo animado, ele resolve apresentar para empresa. Mas na pressa, ele coloca isso na apresentação:

# Time to see my glorious data!
plt.plot(x,y)
plt.show()

E ele parte todo confiante pra mostrar para o diretor, que faz uma certa careta confusa…

Ah… bem…isso… parece anos 90? Hum… qual é o valor do sexto ponto? Pera, aquele 6 é o 7… maldito índice de base 0. Hum… me parece entre 0 e 0,2… porcaria, isso é 20% de erro em relação a amplitude máxima dos dados! E esse ponto é o menor? o 8 também é baixo… deixa eu chegar perto pra ver. Mas porque eu estou me importando com isso?

O que o gráfico quer dizer é claro! Houve uma baita queda entre o ponto 4 (aquele é o 4, né?) e o 5… ou será que é pra eu ver que a média da primeira metade do gráfico é maior que a média da outra média… Espera aí, o que eu estou vendo mesmo?

Depois de um bom tempo explicando, a reunião acaba e o diretor em questão volta pra mesa indeciso. Enquanto Rober solta fumaça em fúria porque as pessoas ‘são incapazes de entender minha arte!’ Ele volta para sua mesa e descobre na internet uma biblioteca chamada Seaborn… que vai resolver seus problemas…

# Ready cannon!
import seaborn as sns
# Load!
sns.set(style=”darkgrid”) # Admit, you love this command
# Fire!
sns.lineplot(x,y)

“Eh… mudou algo?… Parece igual… pelo menos é anos 2000! Combina com a nossa cultura de high tecnology! Ok, mas para que serve essa coisa que você plotou?”

Nessa hora Rober se convence de que o diretor é um idiota ignorante, abandona seu projeto, e ganha a fama de ‘louco que arranja números’. Sua brilhante conclusão nunca é contada, e ele estagna na empresa.

Mas o porque do triste caso? Se você olhou as imagens, deve estar confuso que nem o diretor. E realmente, não é culpa sua ou dele. Apesar desse estilo de gráfico ser super comum enquanto se explora os dados por serem rápidos de programar e leves no processar, eles não carregam o contexto necessário para quem não está trabalhando diretamente os dados. É um tradeoff entre a velocidade de trabalho e facilidade das pessoas entenderem. Ter uma biblioteca gráfica mais avançada não vai substituir isso, só dar mais recursos pra brincar, mas você ainda precisa usar.

A interpretação de qualquer dado depende totalmente do contexto da análise: O seu objetivo enquanto explora, a origem e tipo dos dados, as manipulações feitas, etc. Como autor do seu trabalho, você se lembra dessas informações porque você mesmo vivenciou o processo, mas na hora de apresentar os outros não sabem o que foi feito.

Aí na hora H você é obrigado à explicar todo esse contexto com uma parede de texto ou uma introdução de uns bons 15 minutos, e estará forçando a paciência das pessoas que vão ler/ouvir esses trechos. Para piorar, quando você mostrar o gráfico e estiver a falar sobre as conclusões, as pessoas ainda vão estar tentando entender o que elas estão vendo, distraindo-se da parte importante: A conclusão. *

*Em nota, você não plota pela idéia de data porn, que é mostrar dados porque dados são interessantes e bonitos por si, mas para conseguir transmitir algum conhecimento.

Não seria super top se você conseguisse carregar o contexto consigo e reduzisse a barreira da interpretação? Veja se esse exemplo alcança isso:

Mas você deve estar se perguntando porquê este gráfico é mais explícito e bem melhor que o outro, vamos listar as diferenças:

1) A conclusão está integrada ao gráfico, na forma de um comentário na parte de baixo. Ela é especialmente útil: Eu posso rapidamente alternar entre ler ela e olhar o comportamento dos dados. Um reforça o outro enquanto a pessoa ainda está no início da leitura.

2) Título e comentário trazem o contexto à imagem. Você consegue saber sobre o que ele está falando.

3) O eixo x agora está numerado de 1 à 10, colocando o número em paralelo com a ordenação (o primeiro é 1) reduzindo a confusão na hora de referenciar um ponto.

4) O valor dos pontos está explícito e direto. É mais rápido e claro de comparar.

5) Retirar o eixo y liberou mais espaço para focar nas partes importantes.

6) A letra não é miúda, e a linha vermelha e mais grossa contrasta melhor contra o fundo do gráfico, o que facilita a leitura.

7) Ele é maior. Sim, ser grande é importante, você deve sempre que possível aproveitar o espaço disponível, porque é necessário espaço para adicionar essas informações extras sem que a fonte fique miúda.

Bem mais legal né? Você consegue ver em poucos segundos o que o Rober queria dizer, volte lá na fala do diretor e veja se as mesmas dúvidas aconteceram com você.

Ele é tão prático que o seu coleguinha que acabou de passar atrás entendeu a mensagem. Não acredita em mim? Mostra pra pessoa do seu lado. Ainda não? Posta a imagem nas redes sociais então. (E o link pro meu artigo, tá?)

Até a próxima, cientistas de dados xeretas.

Ah… e para os nerds. Aqui está o código do gráfico: (Não, isso não é um código exemplar):

%matplotlib inline
# notebook dark magic!
import matplotlib.pyplot as plt
import numpy as np
# Machine teaching my pc to be random, but not too much
np.random.seed(666)
y = np.random.sample(10)
x = np.arange(0,10)
# let's start with some good names and variables
title = 'My PC being possessed by the random devil\n(numpy.seed 666)'
DPI = 96 # Used https://www.infobyip.com/detectmonitordpi.php , adapt to your monitor
LENGHT = 800
HEIGHT = 600
# y is ok, no need to change the data because it doesn't have a meaning
# but for non-pythonic people, the world starts at 1
x = list(range(1, y.shape[0]+1 ))
# data ready, so it's plot time!
# change color for better contrast against the background
plt.plot(x,y, 'r-', linewidth=3.0)
# geting certain objects for future use
figure = plt.gcf()
axes = plt.gca()
# Placing Title
plt.title(title, fontsize= 19)
# y axis for few data is a bummer
plt.yticks([])
# instead use direct annotation on those points! (Yeah, its big, but it's full auto)
xmin, xmax = axes.get_xlim()
axis_widht = xmax - xmin
ymin, ymax = axes.get_ylim()
axis_height = ymax - ymin
NUDGE_ACTIVATOR = 0.2 * axis_height
VERT_NUDGE = 0.05 * axis_height
HORI_NUDGE = 0.2 * axis_widht/len(x) # more elements, less nudge
for point, value, position in zip(x,y, range(len(x))):
text_len = len(str(value))
# Sense of lateral points to decide over or belox
try:
bef_value = y[position - 1]
aft_value = y[position + 1] # yes, it tries to looṕ, not very cool
except:
pass
if bef_value > value and aft_value > value: # valley
y_pos = value - VERT_NUDGE
x_pos = point
elif bef_value < value and aft_value < value: # montain
y_pos = value + VERT_NUDGE
x_pos = point
elif bef_value > value + NUDGE_ACTIVATOR or aft_value < value - NUDGE_ACTIVATOR: # sharp downhill
y_pos = value - VERT_NUDGE * 2
x_pos = point - HORI_NUDGE
elif bef_value < value - NUDGE_ACTIVATOR or aft_value > value + NUDGE_ACTIVATOR: # sharp uphill
y_pos = value + VERT_NUDGE * 2
x_pos = point - HORI_NUDGE
else:# Cases with looks plane
y_pos = value + VERT_NUDGE #arbitrary number
x_pos = point

plt.text(x=x_pos, y=y_pos,
s=str(round(value,2)),
color='red',
fontsize = 17,
horizontalalignment='center',
verticalalignment='center')
# stretching a little the y axis to allocate the annotations
stretch = axis_height * 0.05
axes.set_ylim([ymin - stretch ,ymax + stretch])
# the x axis should tell all points, as it has space
plt.xticks(x,fontsize=17, rotation=0)
# let's put the right size
figure.set_size_inches(LENGHT/DPI, HEIGHT/DPI) # so I can choose the aspect ratio for drama
# let's add a conclusion:
plt.text(x=3,
y=0.4,
s="Random data may \nlook to have trends, \nbut it's just \ncoincidences\ncontext is important",
fontsize = 20,
horizontalalignment='center',
verticalalignment='top')
# Show me you moves! (It has scraps of the seaborn import)
plt.savefig('size_trick.png', dpi= 2 * DPI) # This changes the size of the figure WITHOUT setting sizes for everything! :D

--

--

Talietta
Data Hackers

Writer for Data Hackers. Speciality in data viz. I love system-people relationships and how people interact with technology. Purple and ultramarine addicted