Nesta unidade, vamos introduzir o pacote Matplotlib do Python (http://matplotlib.org/) que permite fazer uma grande variedade de gráficos (ver por exemplo, https://plot.ly/matplotlib/).
Lembre-se: Execute a última célula para melhorar a aparência deste notebook.
Vamos começar com um exemplo: suponha que você queira fazer um gráfico de linha para visualizar as cotações do dólar em algum periodo de um mês.
A tabela abaixo mostra as cotações no periodo entre 1/9/2017 e 8/9/2017 segundo o Banco Central do Brasil (Fonte: http://www4.bcb.gov.br/pec/taxas/port/ptaxnpesq.asp?id=txcotacao).
| Data | Compra | Venda |
|---|---|---|
| 1/09/2017 | 3.1327 | 3.1333 |
| 4/09/2017 | 3.1383 | 3.1389 |
| 5/09/2017 | 3.1197 | 3.1203 |
| 6/09/2017 | 3.1127 | 3.1133 |
| 8/09/2017 | 3.0902 | 3.0908 |
Como fazer um gráfico com esses dados em Python?
Começamos importando o módulo matplotlib.pyplot que tem diversas funções prontas para a gente usar.
No código abaixo, estamos dando o "apelido" de plt para essa biblioteca. Assim, não temos que digitar matplotlib.pyplot toda vez que usarmos suas funções.
A primeira linha de código %matplotlib notebook permite definir opções apropriadas para exibir os gráficos num notebook.
%matplotlib notebook
import matplotlib.pyplot as plt
A forma mais simples de fazer o gráfico duma função $f: D\to I$ em Python é usar diretamente a função predefinida plot do pacote matplotlib.pyplot. A chamada a plot deve ter como parâmetros duas listas com os valores do dominio $D$ e a imagem $I$ de $f$.
Por exemplo, para fazer o gráfico com os dados do valor de compra do dólar segundo a tabela acima podemos usar a seguinte instrução. Execute seguinte a célula e veja o resultado.
diaMes = [1,4,5,6,8] # Dominio
valorCompra = [3.1327,3.1383,3.1197,3.1127,3.0902] # Imagem
plt.plot(diaMes, valorCompra)
Como você pode ver na última linha usamos o "apelido" plt do pacote antes de chamar a função plot().
Os valores da lista fornecida como primeiro parâmetro foram colocados no eixo X enquanto os do segundo parâmetro no eixo Y.
Agora precisamos personalizar nosso gráfico e mostrar que o eixo X representa dias do mês e o eixo Y o valor da cotação do dólar.
Então vamos colocar "Dias de setembro" no eixo X:
plt.xlabel("Dias de setembro")
Note que o seu gráfico (acima) foi atualizado no eixo X. Vamos colocar "Cotação do dólar" como nome para o eixo Y:
plt.ylabel("Cotação do dólar")
Vamos colocar um título no gráfico?
plt.title("Valor de Compra do Dólar")
Às vezes, é útil ter uma grade no gráfico. Isso é bem fácil de se fazer:
plt.grid(True)
Agora ficou melhor, não é verdade?
plot¶A função plot tem várias opções para definir e personalizar o gráfico duma função. Por exemplo, é possível fornecer somente os valores do eixo Y. Nesse caso o eixo X toma automaticamente valores entre $0\ldots N-1$, onde $N$ é o número de valores da imagem da função.
Execute a seguinte célula e veja no gráfico acima o resultado.
plt.plot([1.4, 3.1, 2.3, 3.25, 4, 2.7])
Note que o domínio da nova função é [0,1,2,3,4,5] e o gráfico foi colocado junto com o anterior. Mas, e se você quisesse apagar o antigo e começar um novo? Basta clicar no símbolo de energia no topo do gráfico.

Vamos fazer um novo gráfico, agora usando a cor vermelha e pequenos círculos. A função plot permite definir as cores e marcas usadas para desenhar as funções. Para isso, é usado como parámetro uma cadeia de caracteres após os valores da imagem.
Execute a célula abaixo e veja a diferença.
plt.plot([1.4, 3.1, 2.3, 3.25, 4, 2.7], 'ro')
A seguinte tabela mostrar alguns dos caracteres que são aceitos para controlar o estilo ou marcador de linha:
| caracter | significado |
|---|---|
| '-' | linha sólida |
| ':' | linha pontilhada |
| '.' | marcador de ponto |
| 'o' | marcador de círculo |
| 's' | marcador de quadrado |
| '*' | marcador de estrela |
| '+' | marcador de + |
| 'x' | marcador de x |
| 'D' | marcador de diamante |
As seguintes abreviaturas são suportadas para as cores:
| caracter | cor |
|---|---|
| 'b' | azul |
| 'g' | verde |
| 'r' | vermelho |
| 'c' | cyan |
| 'm' | magenta |
| 'y' | amarelo |
| 'k' | preto |
| 'w' | branco |
Também, é possível colocar legendas e controlar a largura da linha. Você pode ver todas as opcões em http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot.
A seguir alguns exemplos.
plt.plot([1,2,3], [1,2,3], 'go-', label='Linha 1', linewidth=4)
plt.plot([1,2,3], [1,4,9], 'rs:', label='Linha 2')
plt.plot([7,3.4,5.9], 'bD')
plt.legend()
plt.show()
Agora, vamos a escrever o programa Python completo para mostrar de forma gráfica os dados da tabela com a cotação do dólar.
%matplotlib notebook
import matplotlib.pyplot as plt
diaMes = [1, 4, 5, 6, 8]
valorCompra = [3.1327, 3.1383 ,3.1197, 3.1127, 3.0902]
valorVenda = [ 3.1333, 3.1389, 3.1203, 3.1133, 3.0908 ]
plt.plot(diaMes, valorCompra, 'bo-', label='Valor de Compra')
plt.plot(diaMes, valorVenda, 'rD-', label='Valor de Venda')
plt.xlabel("Dias de setembro")
plt.ylabel("Valor do dólar em reais")
plt.title("Gráfico da Cotação do Dólar")
plt.grid(True)
plt.legend()
plt.show()
Escreva um programa para gerar um gráfico com as temperaturas máximas e míninas em São Paulo nos primeiros sete dias de setembro deste ano. Use a tabela abaixo (Fonte: https://www.accuweather.com/pt/br/sao-paulo/45881/september-weather/45881?monyr=9/1/2017&view=table).
| Data | Max/Min |
|---|---|
| sex 01/09 | 23°/14° |
| sáb 02/09 | 25°/14° |
| dom 03/09 | 27°/13° |
| seg 04/09 | 28°/13° |
| ter 05/09 | 28°/12° |
| qua 06/09 | 27°/15° |
| qui 07/09 | 28°/14° |
Como fazer o gráfico da função seno em Python?
Para fazer gráficos mais complicados é muito útil o NumPy, que é o pacote fundamental para a computação científica em Python. Essa biblioteca permite trabalhar com arranjos, vetores e matrizes de $N$ dimensões (de forma similar ao Matlab) e fornece diversas funções matemáticas úteis para fazer gráficos. Além disso, esse módulo inclui uma variedade de rotinas para classificação e seleção de dados, rotinas de álgebra linear, operações de estatística básicas, simulação aleatória e muito mais. Ver https://docs.scipy.org/doc/numpy/user/whatisnumpy.html.
Vamos importar a biblioteca numpy e dar o "apelido" de np:
import numpy as np
Agora, vamos criar uma lista com os números de -$2\pi$ até $2\pi$ com diferença de 0.1 e colocar em uma variável a.
O bom aqui é que o numpy já tem funções que fazem isso para a gente:
a = np.arange(-2*np.pi,2*np.pi,0.1)
Vamos ver como ficou a?
a
Então, note que em arange, -$2\pi$ é o número inicial, $2\pi$ é o número limite (não incluido na lista resultado), e 0.1 é o quanto acrescentamos em cada passo.
E para calcular o seno de cada número em a? De novo, o numpy já tem isso pronto para a gente. Vamos usar a função sin:
b = np.sin(a)
Vamos ver como ficou b?
b
Agora só falta fazer o gráfico! Vamos chamar o matplotlib.pyplot pelo seu apelido plt.
Lembre desligar o último gráfico gerado para criar um novo embaixo da célula.
plt.plot(a,b)
Vamos personalizar nosso gráfico.
Suponha que esse gráfico representa a variação dum sinal ao longo do tempo. Então vamos colocar "Tempo (s)" no eixo X:
plt.xlabel("Tempo (s)")
Note que o seu gráfico (acima) foi atualizado com no eixo x. Vamos colocar "Valor do sinal" como o nome do eixo Y:
plt.ylabel("Valor do sinal")
Vamos colocar um título no gráfico e grade?
plt.title("Acrescente você mesmo o título")
plt.grid(True)
Se você preferir tirar a grade, você pode colocar plt.grid(False) ou apagar a linha de código.
Talvez você esteja estranhando este gráfico do seno. O gráfico ficou meio "esticado", não?
Bom, isso porque o matplotlib tentou escolher uma escala para a gente.
Se você quiser que os eixos fiquem na mesma escala, basta digitar:
plt.axis('equal')
Explore um pouco o gráfico! Você pode salvar o gráfico num arquivo clicando no símbolo do disquete/salvar. Escreva abaixo código para mostrar no gráfico o cosseno de cada número em a.
O arange do numpy cria um tipo de dado chamado array. Veja como as operações com arrays funcionam:
c = np.arange(0,1,0.1)
c
O que você acha que deveria ser c+c? Veja abaixo:
c+c
E c*c?
c*c
Então note que em arrays, essas operações são realizadas ponto-a-ponto. E como faríamos a raiz quadrada de cada entrada de c?
np.sqrt(c)
A função linspace(a, b, N) do numpy permite criar um array de $N$ números uniformente distribuidos no intervalo $[a,b]$, incluindo $a$ e $b$. Veja abaixo.
d = np.linspace(2, 3, 5)
d
Os operadores e funções que fornece o pacote numpy para trabalhar com arrays, permitem criar diretamente outros arrays sem usar variáveis auxiliares. Veja o seguinte exemplo.
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 12, 100)
plt.plot(x, x, label='y=x')
plt.plot(x, x**2, label=r'$y=x^2$') # Usando fórmulas do Latex nos rótulos!
plt.plot(x, 2**x, label=r'$y=2^x$')
plt.xlabel('Eixo X')
plt.ylabel('Eixo Y')
plt.title("Gráficos de funções")
plt.legend()
plt.show()
Modifique o programa acima para mostrar o gráfico das funções $\sqrt{x}, e^x$ e $x^3+2x$ (use a multiplicação para calcular $x^3$). Coloque as legendas de forma apropriada.
Escreva um programa para fazer o gráfico das seguintes funções no intervalo $[-2, 2]$ com diferença de 0.1:
As três funções têm algum ponto de interseção no intervalo dado?
Dica: O botão com um quadradinho vazio em baixo do gráfico é uma ferramenta de zoom.
Uma das formas de desenhar uma circunferência de raio $r$ e centro $(x_0,y_0)$ é usar a função $f:[0,2\pi]\to \mathrm{R}\times \mathrm{R}$ definida como:
$$f(t)=(\ x_0+r*cos(t)\ ,\ y_0+r*sin(t)\ )$$Para entender o que faz essa função, considere a circunferência unitária (raio $1$ e centro $(0,0)$).
Sabemos que as cordenadas de um ponto sobre essa circunferência que corresponde a um ângulo $t$ será $(\cos{t}, \sin{t})$.

Portanto, se fizermos uma variável t (que representa o ângulo) variar de $0$ a $2\pi$ (0 a 365 graus), podemos plotar a circunferência unitária muito facilmente.
Para plotar uma circunferência de raio $r$, basta multiplicar as cordenadas de cada ponto por $r$. Para mudar o centro, basta somar o valor de $(x_0, y_0)$.
Vamos ver como podemos fazer um círculo de raio 5 e centro (1,2).
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
# Outra forma de criar um gŕafico e usar outras funções
fig, ax = plt.subplots()
x0, y0, r = 1, 2, 5 # dados do círculo
t = np.arange(0, 2*np.pi, 0.01) # dominio da função (passo 0.01 para melhorar a precisão)
x = x0 + r * np.cos(t) # calculando X e Y
y = y0 + r * np.sin(t)
ax.plot(x, y, 'r-')
plt.show()
Mas o gráfico mostra uma circunferência (na verdade uma elipse) e não um círculo?! Então vamos preencher e arrumar a escala. Além disso, vamos colocar a grade e um pequeno ponto no centro. Também vamos acrescentar informação usando fórmulas escritas em Latex. Veja o resultado!
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
x0, y0, r = 1, 2, 5 # dados do círculo
t = np.arange(0, np.pi * 2.0, 0.01) # dominio da função
x = x0 + r * np.cos(t) # calculando X e Y
y = y0 + r * np.sin(t)
#ax.plot(x, y, 'g-') # usando fill no lugar do plot para preencher
ax.fill(x, y, 'b-', alpha=0.3)
ax.plot([1], [2], 'ob') # mostrando o centro
plt.axis('equal') # arrumando a escala
plt.grid(True) # grade
plt.title(r'$f(\alpha)=(1+5*\mathrm{cos}(\alpha),2+5*\mathrm{sin}(\alpha))$') # Usando fórmulas em Latex
plt.text(-0.6, 0.6, r'$t = 0\ldots 2\pi$', fontsize=15)
plt.show()
Modifique o programa acima para
Dica: Não usar o parâmetro alpha na função fill.
Em muitas situações, é desejável ir mostrando o gráfico conforme ele está sendo construido. O exemplo a seguir ilustra uma maneira de conseguir isso. Execute a célula abaixo e veja o resultado.
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
fig,ax = plt.subplots()
x = [0,-8, -10, -6, 0, 6, 10, 8, 0]
y = [0, 4, 8, 8, 5, 8, 8, 4, 0]
x1 = []
y1 = []
N = len(x)
for i in range(0,N):
x1.append(x[i])
y1.append(y[i])
ax.plot(x1, y1, 'go-')
fig.canvas.draw()
if i < N-1:
input("Digite qualquer coisa para continuar ")
else:
print("Pronto")
A Amazon deseja acompanhar o percurso que usa um drone para fazer entregas e coletas de produtos. O drone sai da posição de origem $(0,0)$ e faz as entregas e coletas voando até outras posições especificadas por pontos no plano. O serviço termina quando o drone volta à posição de origem.
Adapte o programa anterior para ler as posições de entregas e coletas e mostrar, de forma incremental num gráfico, o percurso do drone até voltar à origem.
Nesta seção vamos aprender como fazer diferentes tipos de gráficos. Um dos mais simples é o gráfico de dispersão que como vimos acima pode ser obtido usando diretamente a função plot.
No entanto, o módulo matplotlib.pyplot inclui a função scatter que fornece diversas opções específicas para este tipo de gráfico.
Veja o exemplo abaixo. Nele, temos usado o módulo random do pacote numpy para gerar arrays de números aleatórios. Em particular, a função rand(N) cria um array de $N$ valores aleatórios no intervalo $[0.0, 1.0)$.
Outros exemplos podem ser encontrados em https://plot.ly/matplotlib/scatter/.
#Adaptado de http://matplotlib.org/examples/shapes_and_collections/scatter_demo.html
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt
N = 50
x1 = np.random.rand(N)
y1 = np.random.rand(N)
colors = np.random.rand(N)
plt.scatter(x1, y1, c=colors, marker='^')
x2 = np.random.rand(N)
y2 = np.random.rand(N)
plt.scatter(x2, y2, color='r', marker='o', alpha=.4)
plt.show()
O gráfico de pizza também pode ser gerado de forma muito simples usando o módulo matplotlib.pyplot. Para isso, é usada a função pie.
A área de cada pedaço da pizza é calculada como $\frac{x}{\sum x}$. Os pedaços da pizza são desenhados, por padrão, em sentido sentido anti-horário começando no eixo x (ou num ângulo especificado).
Veja o exemplo a seguir.
#Adaptado de http://matplotlib.org/examples/pie_and_polar_charts/pie_demo_features.html
%matplotlib notebook
import matplotlib.pyplot as plt
# Definindo os pedaços da piza
labels = ['Norte', 'Nordeste', 'Sudeste', 'Sul', 'Centro-Oeste']
sizes = [8.41, 27.79, 42.06, 14.3, 7.44]
explode = (0, 0, 0.1, 0, 0) # o terceiro pedaço da piza estará separado
# Desenhando o gráfico
fig1, ax1 = plt.subplots()
ax1.pie(sizes, explode, labels, autopct='%1.1f%%',
shadow=True, startangle=180) # Começa a colocar os pedaços no ângulo 180°
ax1.axis('equal') # Evitando que o círculo fique achatado
plt.title('Percentual da população nas cinco regiões brasileiras em 2012 (IBGE)')
plt.show()
A professora Alice tem os conceitos da sua turma na matéria de PI e quer fazer um gráfico de pizza com os dados. No entanto, ela não gosta de usar Excel nem nenhuma ferramenta similar.
Escreva um programa para ajudar a Alice. Seu programa deve ler o número de estudantes com conceito 'A', 'B', 'C', 'D', 'F' e 'O' e mostrar um gráfico de pizza com as porcentagens em cada caso. O pedaço da pizza correspondente ao conceito 'F' deve estar separado.
Finalmente, um gráfico de barras pode ser construido usando as funções bar (barras verticais) ou barh (barras horizontais).
Em ambos casos, o primeiro parâmetro é uma lista das posições no eixo correspondente (X ou Y) onde as barras serão desenhadas. O segundo parâmetro é uma lista que indica a altura de cada barra. Outros parâmetros podem ser fornecidos como por exemplo a largura das barras e a cor. Ver mais em https://matplotlib.org/devdocs/api/_as_gen/matplotlib.pyplot.bar.html
Além disso, as etiquetas das posições das barras podem ser personalizadas.
No programa a seguir é usado um gráfico de barras para resolver o Exercício 2: Temperatura em São Paulo.
#Adaptado de http://matplotlib.org/examples/style_sheets/style_sheets_reference.html
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook
fig, ax = plt.subplots()
#Dados
x = np.arange(7) # criando um array [0, ..., 6]
tmin = [ 14, 14, 13, 13, 12, 15, 14 ]
tmax = [ 23, 25, 27, 28, 28, 27, 28 ]
width = 0.25
#Gráfico
ax.bar(x, tmin, width, color='b', label = 'Mínima')
ax.bar(x + width, tmax, width, color='r', label = 'Máxima')
ax.set_xticks(x + width / 2)
ax.set_xticklabels(['sex 1/09', 'sáb 2/09', 'dom 3/09', 'seg 4/09', 'ter 5/09', 'qua 6/09', 'qui 7/09']) # mudando as etiquetas do eixo X
plt.legend()
plt.title("Temperatura em SP - primeira semana de setembro")
plt.show()
O próxima exemplo ilustra o uso de barh. Aqui, também temos usado a função randint(a, b, N) que cria um array de tamanho $N$ de números inteiros aleatórios no intervalo $[a, b)$.
Outros exemplos podem ser encontrados em https://plot.ly/matplotlib/bar-charts/.
#Adaptado de http://matplotlib.org/examples/lines_bars_and_markers/barh_demo.html
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook
fig, ax = plt.subplots()
# Dados
estudantes = ['Ana', 'João', 'Maria', 'Paulo', 'Gisele']
numEst = len(estudantes)
y_pos = np.arange(numEst) # criando um array [0, ..., numEst-1]
nota = np.random.randint(0, 11, numEst) # gerando notas aleatórias entre 0..10 para cada estudante
# Gráfico
ax.barh(y_pos, nota, align='center', color='blue')
ax.set_yticks(y_pos)
ax.set_yticklabels(estudantes)
ax.set_xlabel('Notas')
ax.set_title('Resultados P1')
plt.show()
Tente definir e usar funções sempre que possível.
Para deixar mais feliz à professora Alice, você quer melhorar seu programa do exercício anterior e incluir um gráfico de barras horizontais. Adapte o programa abaixo para isso.
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook
# Leitura dos dados
# Criando dois gráficos
fig, (ax0, ax1) = plt.subplots(nrows=2)
# Código para criar o gráfico de barras (use ax0, não ax)
# Código para criar o gráfico de piza (use ax1, não ax)
# Ajustando o espaço entre os gráficos (pode apagar se não precisar)
plt.subplots_adjust(hspace=0.5)
plt.show()
Escreva um programa que faça um gráfico da função $f(x) = x^4-16x^2+16$ para x de -5 a 5. Coloque a grade.
Olhando para o gráfico, para quais valores de $x$ temos $f(x) = 0$?
Faça um programa que gere o gráfico abaixo (25 círculos concêntricos de raios $1, 1.5, \dots, 13$).

Dica: use o comando for.
Escreva um programa para desenhar um gráfico com um tabuleiro de xadrez de tamanho 4X4. Cada casa do tabuleiro deve ter tamanho 1x1. Escolha a posição no plano que desejar para fazer o desenho.
Escreva um programa que simule 1000 vezes o lançamento dum dado e conte, nesse experimento, o número de ocorrências de cada face. O programa deve mostrar o resultado usando um gráfico de pizza.
Escreva um programa que simule 1000 vezes o lançamento de dois dados e conte, nesse experimento, quantas vezes a soma das faces foi igual a 7.
O programa também deve fazer um gráfico de dispersão para mostrar a distribuição dos lançamentos. Cada eixo do gráfico vai representar um dado. O gráfico deve mostrar os lançamentos nos quais a soma das faces foi igual a 7 com estilo e cor diferentes dos restantes.
Um bêbado está andando num campo aberto. A cada instânte o bêbado dá um passo para frente ou para trás ou para a esquerda ou para a direita com a mesma chance de caminhar em qualquer uma dessas direções. O bêbado parte da origem $(0,0)$. Na posição $(X_b,Y_b)$ tem um buraco muito fundo, do qual o bêbado não conseguiria sair caso caísse nele. Pede-se fazer um programa para:
Escreva um programa que desenhe um gráfico do jogo da forca. Veja a imagem abaixo como exemplo. No entanto, seu gráfico não precisa ser similar à imagem. Seja criativ@!

**Atenção: Este exercício é de entrega obrigatória para a próxima aula.**
Você pode inserir mais células de código pelo menu Insert » Insert Cell Below, ou digitando ESC+B.
%%html
<style>
.rendered_html h1 {
background-color: #555;
color: white;
padding: .5em;
// border-bottom: 2px solid #000;
// padding-bottom: .6em;
margin-bottom: 1em;
}
.rendered_html h1 code {
color: #EBB7C5;
background-color: rgba(0,0,0,0);
}
.rendered_html h2 {
border-bottom: 1px solid #333;
padding-bottom: .6em;
}
.rendered_html h3 {
color: #034f84;
}
.rendered_html code {
padding: 2px 4px;
font-size: 90%;
color: #c7254e;
background-color: #f9f2f4;
border-radius: 4px;
}
.rendered_html pre code {
padding: 0px;
font-size: 90%;
color: #c7254e;
background-color: rgba(0, 0, 0, 0);
}
kbd {
border-radius: 3px;
padding: 2px, 3px;
}
body {
counter-reset: h1counter excounter;
}
h1:before {
content: counter(h1counter) ".\0000a0\0000a0";
counter-increment: h1counter;
}
span.exec:before {
content: counter(excounter);
counter-increment: excounter;
}
</style>
<script>
location.hash = "#homesweethome";
</script>