A importância de colocar contexto e conclusão nos gráficos
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 - yminNUDGE_ACTIVATOR = 0.2 * axis_height
VERT_NUDGE = 0.05 * axis_height
HORI_NUDGE = 0.2 * axis_widht/len(x) # more elements, less nudgefor 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