Ex Matplotlib
Ex Matplotlib
MatPlotLib
Ao ler este documento provavelmente você já escutou falar de gnuplot e de xmgrace e deve se perguntar,
outro???, sim, é outro de entre muitos. decidi escrever sobre esta biblioteca porque a diferencia do xmgrace
(que é o que eu uso) dá para instalar no windows de uma forma relativamente fácil; comparado ao gnuplot ele é
menos árido no que diz respeita a colocar formulas dentro do gráfico; finalmente ele uma faz parte do python,
uma plataforma que está em franco crescimento.
Se você é usuario windows instalei o pythonxy esse pacote já traz tudo o que você precisa em python como um
estudante de Física, se você se sente bem pagando pois acha que terá a segurança de alguma empresa, de
uma olhada em enthought. Se você é usuário mac, o python está no mac e agorá é só instalar o matplotlib.
Finalmente se você é usuário Linux a vida fica mais o menos fácil, usuários de ubuntu (e derivados):
Gráficos Simples
Trabalhar com o matplotlib lembra o gnuplot já que se cimentam numa linguagem de script, mas a diferença é
que o matplotlib o faz sobre o python, onde se comporta como um outro módulo mais. Assim a leitura e
tratamento de dados (ajustes polinomiais ou não lineares) é feito com o Python e no fim mandar a imprimir com
o matplotlib.
1 #!/usr/bin/env python ?
2
3 #Modulos python
4 import numpy as np
5 import scipy.interpolate
6 import matplotlib as mpl
7 import matplotlib.pyplot as plt
8
9 #*******************************************
10
11 #le os dados e armazena em 2 vetores: x, y.
12 x, y = np.loadtxt('dados01.dat', unpack=True)
13
14 #plotando os dados
15 plt.plot(x, y, '*')
16 plt.show()
Para executar no Linux você digita python nome_do_script.py, note que tradicionalmente se coloca .py como
extensão dos scripts python.
[usuario@python: ]# python script01.py
1 de 20
Figura 01: gráfico simples de um conjunto de dados com matplotlib.
Tipo de simbolo
Observe que na linha 15 do script se manda a plotar os dados de x contra y utilizando ∗ para representar os
pontos, além de ∗ existe outras opções:
No script No gráfico
. ponto
o circulo
, pixel
2 de 20
No script No gráfico
s quadrado
p pentágono
* estrela
h hexágono
H hexágono rotado
+ mais
x cruz (x)
D diamante
| linha vertical
- linha horizontal
Tipo de linhas
1 #!/usr/bin/env python ?
2
3 #Modulos python
4 import numpy as np
5 import scipy.interpolate
6 import matplotlib as mpl
7 import matplotlib.pyplot as plt
8
9 #*******************************************
10
11 #le os dados e armazena em 2 vetores: x, y.
12 x, y = np.loadtxt('dados01.dat', unpack=True)
13
14 #plotando os dados
15 plt.plot(x, y, '-')
16 plt.show()
3 de 20
Figura 02: gráfico simples de um conjunto de dados com matplotlib.
No script No gráfico
- linha sólida
-- linha tracejada
: linha pontilhada
-. linha traço-ponto
Cor
Para mudar a cor das linhas (símbolos) colocamos entre aspas a cor que desejamos
1 #!/usr/bin/env python ?
2
3 #Modulos python
4 import numpy as np
5 import scipy.interpolate
6 import matplotlib as mpl
7 import matplotlib.pyplot as plt
8
9 #*******************************************
10
11 #le os dados e armazena em 2 vetores: x, y.
12 x, y = np.loadtxt('dados01.dat', unpack=True)
13
14 #plotando os dados
15 plt.plot(x, y, ':', color='m', marker="o")
16 plt.show()
4 de 20
Figura 03: gráfico simples mudando a cor dos pontos.
No script No gráfico
b ou blue azul
c ou cian ciano
g ou green verde
k ou black preto
m ou magenta magenta
r ou red vermelho
w ou white branco
y ou yellow amarelo
Além dessas cores podemos utilizar cores ao estilo das usada em HTML: #d3ddff.
Atributos
No exemplo anterior vimos que a cor da linha foi passada como um atributo, de fato, todos os parâmetros que
apresentamos até aqui são atributos do gráficos que podem ser explicitamente nomeados. O atributos que o
matplotlib aceita estão dados na tabela a seguir:
No script No gráfico
color ou c cor
5 de 20
No script No gráfico
Vamos agora a plotar simultaneamente dois conjuntos de dados, utilizaremos a informação da tabela previa
para poder identificar cada um das curvas. Para você testar terá que baixar o arquivo dados02.dat de aqui.
1 #!/usr/bin/env python ?
2
3 #Modulos python
4 import numpy as np
5 import scipy.interpolate
6 import matplotlib as mpl
7 import matplotlib.pyplot as plt
8
9 #*******************************************
10
11 #le os dados e armazena em 2 vetores: x, y.
12 x, y = np.loadtxt('dados01.dat', unpack=True)
13
14 #le os II dados e armazena em 2 vetores: x, y.
15 x1, y1 = np.loadtxt('dados02.dat', unpack=True)
16
17 #plotando os dados
18 plt.plot(x, y, linestyle='-', color='black', marker="o", \
19 markersize=20, markerfacecolor="w")
20
21 plt.plot(x1, y1, linestyle='-.', color='red', marker="o",\
22 markersize=10, markeredgecolor="blue", markerfacecolor="w")
23
24 plt.show()
6 de 20
Figura 04: Dois gráfico simples com definições de atributos.
Títulos, eixos
Agora abordaremos o texto que se coloca no gráfico. Na figura script embaixo se mostra como se coloca a
legenda nos eixo, o título, e a legenda do próprio gráfico
1 #!/usr/bin/env python ?
2 # -*- coding: utf-8 -*-
3
4 #Modulos python
5 import numpy as np
6 import scipy.interpolate
7 import matplotlib as mpl
8 import matplotlib.pyplot as plt
9
10 #*******************************************
11
12 #le os dados e armazena em 2 vetores: x, y.
13 x, y = np.loadtxt('dados01.dat', unpack=True)
14
15 #le os II dados e armazena em 2 vetores: x, y.
16 x1, y1 = np.loadtxt('dados02.dat', unpack=True)
17
18 #plotando os dados
19 plt.plot(x, y, linestyle='-', color='black',\
20 marker="*", label=u"posição")
21
22 plt.plot(x1, y1, linestyle='-.', color='red',\
23 marker="o", label="velocidade")
24
25 plt.legend(loc='upper left')
26
27 plt.grid(True)
28
29 plt.xlabel('t (s)')
30
31 plt.ylabel(r'$Y(m)$ e $V_y(\frac{m}{s})$')
32
33 plt.title("Exemplo")
34
35 plt.show()
7 de 20
Note que a legenda associada à curva é colocada via o atributo label. Para que ele apareça no gráfico
devemos colocar a linha 22 que nesse caso indica que a caixa com legenda deverá aparecer no canto superior
esquerdo, além dessa posição temos:
No script No gráfico
5 ou right à direita
10 ou center centralizado
Note que a tabela diz que podemos utilizar números ou letras (entre aspas) para indicar a posição (loc=10 é
igual a loc='center'). De fato além de números podemos utilizar uma tupla de dados (coordenadas) onde por
exemplo (0,0) é o canto inferior esquerdo e (0.5,0.5) o centro, assim um exemplo de posicionamento seria
loc=(0.05,0.8) quase equivalente à loc='upper left'. Quando usamos português colocamos um u a frente da
palavra como feito no label da linha 18 (label=u'posição'), para que isso funcione direito devemos salvar nosso
script em UTF-8 e colocar no cabeçalho # -*- coding: utf-8 -*-.
Para a legenda dos eixos x e y se utiliza plt.xlabel('') e plt.ylabel(''), respetivamente. Se você quer colocar uma
equação ou letra grega, por exemplo no eixo x, devemos escrever entre $$ a equação (latex) é iniciar com r a
legenda, como feito na linha 29 (para maiores informações de uma olhada em formulas com matplotlib)
Como se pode ver na figura acima o tamanhos das legendas nos eixos e o próprio título são pequenos demais,
afortunadamente o matplotlib tem a opção fontsize que permite modificar esse comportamento padrão:
1 #!/usr/bin/env python ?
2 # -*- coding: utf-8 -*-
3
4 #Modulos python
5 import numpy as np
6 import scipy.interpolate
7 import matplotlib as mpl
8 import matplotlib.pyplot as plt
9
10 #*******************************************
11
12 #le os dados e armazena em 2 vetores: x, y.
13 x, y = np.loadtxt('dados01.dat', unpack=True)
14
15 #le os II dados e armazena em 2 vetores: x, y.
16 x1, y1 = np.loadtxt('dados02.dat', unpack=True)
17
18 #plotando os dados
19 plt.plot(x, y, linestyle='-', color='black',\
20 marker="*", label=u"posição")
21
22 plt.plot(x1, y1, linestyle='-.', color='red',\
23 marker="o", label="velocidade")
24
25 plt.legend(loc=(0.05,0.85))
26
27 plt.grid(True)
8 de 20
28
29 plt.xlabel('t (s)', fontsize=30)
30
31 plt.tick_params(axis='both', labelsize=20)
32
33 plt.ylabel(r'$Y(m)$ e $V_y(\frac{m}{s})$', fontsize=30)
34
35 plt.title("Exemplo", fontsize=30)
36
37 plt.savefig('figura51.png')
38
39 plt.show()
Observe que agora temos um novo problema, as letras são maiores do que a área definida por padrão, para
ajeitar esse comportamento indesejado utilizamos a função plt.tight_layout():
1 #!/usr/bin/env python ?
2 # -*- coding: utf-8 -*-
3
4 #Modulos python
5 import numpy as np
6 import scipy.interpolate
7 import matplotlib as mpl
8 import matplotlib.pyplot as plt
9
10 #*******************************************
11
12 #le os dados e armazena em 2 vetores: x, y.
13 x, y = np.loadtxt('dados01.dat', unpack=True)
14
15 #le os II dados e armazena em 2 vetores: x, y.
16 x1, y1 = np.loadtxt('dados02.dat', unpack=True)
17
18 #plotando os dados
19 plt.plot(x, y, linestyle='-', color='black',\
20 marker="*", label=u"posição")
21
22 plt.plot(x1, y1, linestyle='-.', color='red',\
23 marker="o", label="velocidade")
24
25 plt.legend(loc=(0.05,0.85))
26
27 plt.grid(True)
28
9 de 20
29 plt.xlabel('t (s)', fontsize=30)
30
31 plt.tick_params(axis='both', labelsize=20)
32
33 plt.ylabel(r'$Y(m)$ e $V_y(\frac{m}{s})$', fontsize=30)
34
35 plt.title("Exemplo", fontsize=30)
36
37 plt.savefig('figura51.png')
38
39 plt.tight_layout()
40
41 plt.show()
Observe que além das legendas modificamos o tamanho dos números nos eixos, isso foi feito com a função
plt.tick_params() na qual informamos o tamanho das novas letras (labelsize) e qual dos eixos será afetado
(axis), que no caso escolhemos serem ambos ('both'), para maiores informações veja o manual no site.
1 #!/usr/bin/env python ?
2 # -*- coding: utf-8 -*-
3
4 #Modulos python
5 import numpy as np
6 import scipy.interpolate
7 import matplotlib as mpl
8 import matplotlib.pyplot as plt
9
10 #*******************************************
11
12 #le os dados e armazena em 2 vetores: x, y.
13 x, y, err = np.loadtxt('dados04.dat', unpack=True)
14
15 #plotando os dados
16 plt.errorbar(x, y, yerr=err, linestyle='-', color='black', marker="*", label=
17
10 de 20
18 plt.legend(loc='upper left')
19
20 plt.grid(True)
21
22 plt.xlabel(u'Indivíduos')
23
24 plt.ylabel(u'frequência')
25
26 plt.title("Grafico com erro em y")
27
28 plt.show()
É possível associar um erro ao pontos nos eixo x (simultaneamente com y, dado um cruz no ponto), para isso
utilizamos o parâmetro xerr= vetor com dados do erro.
1 #!/usr/bin/env python ?
2 # -*- coding: utf-8 -*-
3
4 #Modulos python
5 import numpy as np
6 import scipy.interpolate
7 import matplotlib as mpl
8 import matplotlib.pyplot as plt
9
10 #*******************************************
11
12 #le os dados e armazena em 2 vetores: x, y.
13 x, y = np.loadtxt('dados01.dat', unpack=True)
14
15 #calcula os coeficientes do polinomio
16 print 'coeficientes do polinomio'
17 coef = np.polyfit(x, y, 2)
18 print coef
19
20 #cria o polinomio
21 print '\nPolinomio ajustado'
22 pol = np.poly1d(coef)
23 print pol
11 de 20
24
25 #calcula os novos y com o juste
26 yajus = pol(x)
27
28 #cria o grafico
29 plt.plot(x, y, 'o')
30 plt.plot(x, yajus, '--')
31 plt.legend(['dados', 'ajuste'], loc=2)
32 plt.grid(True)
33 plt.xlabel('t')
34 plt.ylabel('V')
35 plt.title("Exemplo de ajuste")
36 plt.show()
Polinomio ajustado
2
1 x - 3.924e-15 x + 1.331e-14
A função polyfit devolve os coeficientes do ajuste polinomial, se esse coeficientes são passados à função
poly1d ela vai montar a equação correspondente, como se mostra nas linhas 22 e 23. Com o polinômio criado
na linha 22 podemos calcular os novos valores (yajus) como se mostra na linha 26.
1 #!/usr/bin/env python ?
2 # -*- coding: utf-8 -*-
3
4 #Modulos python
5 import numpy as np
6 import scipy.optimize
7 import matplotlib as mpl
12 de 20
8 import matplotlib.pyplot as plt
9
10 #*******************************************
11
12 #Função que desejamos ajustar
13 def gausiana(x, yo, xo, s):
14 y = yo * np.exp(-(x-xo)**2 / (2.0*s*s))
15 return y
16
17 #*******************************************
18
19 #le os dados e armazena em 2 vetores: x, y.
20 x, y = np.loadtxt('dados03.dat', unpack=True)
21
22 chuteInicial = np.array([7.0, 15.0, 3.0])
23
24 resAjuste, mcov = scipy.optimize.curve_fit(gausiana, x, y, p0=chuteInicial)
25
26 print "Resultado do ajuste: ", resAjuste
27 print u'\nMatriz de covariança (diagonal eh variança dos resultados):'
28 print mcov
29
30 #gera os y ajustados
31 yajus = gausiana(x, resAjuste[0], resAjuste[1], resAjuste[2])
32
33
34 #cria o grafico
35 plt.plot(x, y, 'o')
36 plt.plot(x, yajus, '-')
37 plt.legend(['dados', 'ajuste'], loc=2)
38 plt.grid(True)
39 plt.xlabel('x')
40 plt.ylabel('y')
41 plt.title(u'Exemplo de ajuste não linear')
42 plt.show()
13 de 20
Figura 07: Ajuste não linear.
Para o ajuste não linear utilizamos a função scipy.optimize.curve_fit, essa função espera o nome de outra
função a qual é o modelo a ser ajustado ao dados, no programa chamada de gausiana e definida entre as
linhas 13 e 15; seguidamente são passado a scipy.optimize.curve_fit os vetores de dados x e y; finalmente
damos para ela um chute inicial dos parâmetros que definem a função a ser ajustada. Como resultado do ajuste
ela devolve um vetor e uma matriz, o vetor armazena parâmetros resultantes do ajuste na ordem que foram
definidos na função, a matriz devolve a matriz de covariança.
1 #!/usr/bin/env python ?
2 # -*- coding: utf-8 -*-
3
4 #Modulos python
5 import numpy as np
6 import scipy.optimize
7 import matplotlib as mpl
8 import matplotlib.pyplot as plt
9
10 #*******************************************
11
12 #Função que desejamos ajustar
13 def gausiana(x, yo, xo, s):
14 y = yo * np.exp(-(x-xo)**2 / (2.0*s*s))
15 return y
16
17 #*******************************************
18
19 #le os dados e armazena em 2 vetores: x, y.
20 x, y, yerr= np.loadtxt('dados04.dat', unpack=True)
21
22 chuteInicial = np.array([7.0, 15.0, 3.0])
23
24 resAjuste, mcov = scipy.optimize.curve_fit(gausiana, x, y, p0=chuteInicial, sigma
25
26 print "Resultado do ajuste: ", resAjuste
27 print u'\nMatriz de covariança (diagonal eh variança dos resultados):'
28 print mcov
14 de 20
29
30 #gera os y ajustados
31 xajus = np.linspace(0.0, 40.0, 100) #gera 100 pontos desde 0 até 40
32 yajus = gausiana(xajus, resAjuste[0], resAjuste[1], resAjuste[2])
33
34
35 #cria o grafico
36 plt.errorbar(x, y, yerr, marker='o', linestyle=' ')
37 plt.plot(xajus, yajus, '-')
38 plt.legend(['dados', 'ajuste'], loc=2)
39 plt.grid(True)
40 plt.xlabel('x')
41 plt.ylabel('y')
42 plt.title(u'Exemplo de ajuste não linear')
43 plt.show()
15 de 20
Figura 08: Analise da figura de difração.
sin2 α
I = I0
α2
onde
ϕ a sin θ
α= =π
2 λ
Utilizando o seguinte script podemos ver os dados experimentais
1 #!/usr/bin/env python ?
2 # -*- coding: utf-8 -*-
3
4 #Modulos python
5 import numpy as np
6 import scipy.optimize
7 import matplotlib as mpl
8 import matplotlib.pyplot as plt
9
10 #*******************************************
11
12 #le os dados e armazena em 2 vetores: x, y.
13 x, y = np.loadtxt('dadosDifracao.dat', unpack=True)
14
15 #plotando os dados
16 plt.plot(x, y, '.')
Resulta na figura da esquerda, onde depois de se fazer um ampliação na região de interesse, resulta na figura
da direita.
1 #!/usr/bin/env python ?
2 # -*- coding: utf-8 -*-
3
4 #Modulos python
16 de 20
5 import numpy as np
6 import scipy.optimize
7 import matplotlib as mpl
8 import matplotlib.pyplot as plt
9
10 #*******************************************
11
12 #Função que desejamos ajustar
13 def difracao(x, a, yo):
14 alphaD2 = np.pi * a * np.sin(x)/632.0
15 y = yo * (np.sin(alphaD2)/alphaD2)**2
16 return y
17
18 #*******************************************
19
20 #define duas matrizes vazias
21 x = []
22 y = []
23
24 #le os dados e armazena em 2 vetores temporarios: xtemp, ytemp.
25 xtemp, ytemp = np.loadtxt('dadosDifracao.dat', unpack=True)
26
27 for i in range(len(xtemp)): #percorre todos os elementos em xr
28 if (np.abs(xtemp[i]) <= 1.30): #limita os dados em x entre -1.3 e 1.3
29 #coloca os dados recortados nos novos vetores x e y
30 x.append(xtemp[i] + 0.01) #desloca o grafico ligeiramente para a direita
31 #isso evita um dado exatamente em zero pois da erro
32 y.append(ytemp[i])
33
34 chuteInicial = np.array([1.0, 132.0])
35
36 resAjuste, mcov = scipy.optimize.curve_fit(difracao, x, y, p0=chuteInicial, maxfev
37
38 print "Resultado do ajuste: ", resAjuste
39 print u'\nMatriz de covariança (diagonal eh variança dos resultados):'
40 print mcov
41
42 #gera os y ajustados
43 yajus = difracao(x, resAjuste[0], resAjuste[1])
44
45 #cria o grafico
46 plt.plot(x, y, 'o')
47 plt.plot(x, yajus, '-')
48
49 plt.legend([r'$dados$', r'$I_0\frac{\sin \left( \pi\, \frac{a\,\sin \theta}{\lambda} \right)}{
50
51 plt.xlabel(r'$\pi\, \frac{a\,\sin \theta}{\lambda} (radiano)$', fontsize=20)
52 plt.ylabel(r'$I$', fontsize=20)
53
54 plt.title(u'Intensidade da luz que passa por uma fenda')
55 plt.show()
17 de 20
Figura 10: Ajuste aos dados experimentais.
Tópicos avançados
Aqui vamos tratar de assuntos que você muito provavelmente não terá que se preocupar tão cedo mas podem
ser uteis no futuro próximo.
Para começar é necessário desconstruir, de certa forma, parte do que foi feito até aqui. Vamos criar um objeto
(isso mesmo, de orientação a objeto) com as propriedades do módulo matplotlib.pyplot. Ao fazermos
herdaremos as propriedades desse módulo e seu métodos. Para se conseguir isso primeiro criamos uma figura
sobre a qual colocaremos nossos gráficos:
1 #!/usr/bin/env python ?
2 # -*- coding: utf-8 -*-
3
4 #Modulos python
5 import numpy as np
6 import scipy.optimize
7 import matplotlib as mpl
8 import matplotlib.pyplot as plt
9
10 #*******************************************
11
12 papel = plt.figure()
Note que a variável que utilizei para armazenar o objeto criado chamei de papel pois tem o rol que um papel
utilizado em um desenho. Os argumentos que podemos colocar dentro da função figura são
num: é um numero utilizado para fazer referencia a uma dada figura, é isso que se armazena na variável
papel.
figsize: é o tamanho da figura width x height em polegadas
dpi: resolução da figura
facecolor: é a cor do papel
18 de 20
edgecolor: cor da borda
Exercícios 106
1. Utilizando matplotlib leia o seguinte conjunto de dados: dados01.dat e com eles cria um gráfico de
pontos, coloque como título do gráfico: exemplo 01, no eixo das abscisas coloque X e no eixo das
ordenadas Y, a legenda deve ser colocada no canto inferior esquerdo e informar que os pontos são
dados01.dat. Realize o ajuste dos dados e plote o ajuste em conjunto com os dados, a legenda
associada ao ajuste deve aparecer y = αx2 + βx + γ. Os pontos associados ao ajuste devem ser
triangulo para acima de tamanho 7 e de cor azul; o ajuste deve ser em linha tracejada verde. Salve o
resultado do ajuste como figura em formato png.
2. Utilizando matplotlib leia os seguintes conjuntos de dados: dados02.dat e dados03.dat, plote no mesmo
gráfico ambos conjuntos de dados utilizando para ambos as seguintes propriedades: símbolo círculo em
branco e borda vermelha, linha continua vermelha.
3. Crie um programa que leia os dados dados01.dat (são 25 pontos). Considere que esses dados
correspondem a uma parábola, a qual tem por equação y = a x2 + b x + c, calcule o vértice da
parábola (x0 , y0 ) e a posição do foco (xf , yf ) sabendo que
b
x0 = −
2.0a
4ac − b2
y0 =
4a
1.0
f=
4.0a
Aqui f é a distância do vértice ao foco (esta parábola é uma parábola com eixo paralelo ao eixo x).
Dica: Se você pegar 3 pontos quaisquer dos dados (pegue os pontos 5, 15 e 20) poderá formar um
sistema de 3 equações simultâneas. De uma dessas equações isole o b e substitua nas outras duas
equações, dessa forma ficará com 2 equações e duas incógnitas (a e c). Sistemas de 2 equações são
fáceis de resolver (caneta e papel para encontrar as equações finais).
4. Por definição a hipérbole é o lugar geométrico de todos os pontos do plano tais que a diferença da suas
distâncias a dois pontos dados (focos) é constante. Sabendo que a equação de uma hipérbole é
(y − y0 )2 (x − x0 )2
− =1
a2 b2
onde (a, b) e (−a, −b) são os vértices da hipérbole e os focos está a c2 = b2 + a2 distantes de cada
vértice. Faça um programa que mostre que todos os dados dados02.dat e dados03.dat correspondem a
pontos sobre uma hipérbole na qual x0 = y0 = 5.0, a = 4.0 e b = 2.0.
5. Escreva um programa que leia desde um arquivo quatro números de ponto flutuante, os dois primeiros
representam a amplitude e os dois últimos representaram o período de oscilação de duas ondas
sinusoidais. Matematicamente essa ondas podem ser escritas como
yi = y0i sin(ωi t)
onde ωi = 2πfi , sendo fi a frequência (inverso do período) da onda (que pode ser i = 1 ou i = 2);
y0i é a amplitude de oscilação da onda i = {1, 2}. Faça um programa que crie 2 arquivos, onda1.dat e
onda1.dat onde serão armazenado n = 200 pontos de yi distribuídos uniformemente em 10 períodos de
oscilação. O programa também deve imprimir a superposição de ambas ondas y = y1 + y2, com a
mesma quantidade de pontos e no mesmo intervalo de tempo, no arquivo superposicao.dat. Com esses
dados crie um gráfico com matplotlib onde apareçam as três curvas com legendas de cada curva e rotulo
nos eixos do gráfico, o título do gráfico deve ser Princípio de superposição.
19 de 20
20 de 20