Matplotlib

In [1]:
%pylab inline
Populating the interactive namespace from numpy and matplotlib

Matplotlib é um módulo para a criação de gráficos 2D e 3D criada por John Hunter (2007). Sua sintaxe é propositalmente similar às funções de plotagem da MATLAB, facilitando o aprendizado de usuários que desejem replicar gráficos construídos naquele ambiente. Com uma grande comunidade de usuários, Matplolib possui diversos tutoriais na Web. Seu site oficial apresenta uma enorme galeria de exemplos que permite ao pesquisador rapidamente identificar o código necessário para o tipo de gráfico que pretende utilizar.

  • Biblioteca para plotting
  • Gráficos de alta qualidade que podem ser utilizados em publicação científica
  • Projetada de forma que a sintaxe de suas funções seja similar às análogas em MATLAB

Exemplo: exibição de duas funções, $\sin (\theta)$ e $\cos (\theta)$

Considere o domínio $X$, formado por 256 pontos no intervalo $[-\pi, \pi]$, e as funções $\cos(x)$ e $\sin(x)$:

In [2]:
X = linspace(-pi, pi, 256)
C = cos(X)
S = sin(X)

O gráfico das duas funções pode ser facilmente exibido com a função plot:

In [3]:
plot(X, C)
plot(X, S)
Out[3]:
[<matplotlib.lines.Line2D at 0x7f36f263fdd0>]

O exemplo acima apresenta um gráfico muito simples. Para ilustrar a grande variedade de personalizações fornecidas pela Matplotlib, é apresentado abaixo um exemplo mais complexo, uma versão modificada do código apresentado por Rougier et al.. O leitor interessado pode obter explicações detalhadas na Seção 1.4, Matplotlib: plotting, das SciPy Lecuture Notes.

In [4]:
fig = figure()
# Remover as bordas superior e inferior
ax = gca()  # gca significa 'get current axis'
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')

# Mover os eixos e as marcas para o centro do gráfico
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))

# Definie os intervalos exibidos nas oordenadas e abscissas
xlim(-3.5, 3.5)
ylim(-1.25, 1.25)

# Indica o texto a ser utilizado nas marcas dos eixos
xticks([-pi, -pi/2, 0, pi/2, pi], [r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$'])
yticks([-1, 0, +1], [r'$-1$', r'$0$', r'$+1$'])

# Anotação de dois pontos de interesse: o seno e o cosseno de 2pi/3
theta = 2 * pi / 3
plot([theta, theta], [0, cos(theta)], color='red', linewidth=2.5, linestyle="--")
scatter([theta], [cos(theta)], 25, color='red')
annotate(r'$sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',
            xy=(theta, sin(theta)), xycoords='data',
            xytext=(+10, +30), textcoords='offset points', fontsize=16,
            arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

plot([theta, theta],[0, sin(theta)], color='green', linewidth=2.5, linestyle="--")
scatter([theta, ],[sin(theta), ], 25, color='green')
annotate(r'$cos(\frac{2\pi}{3})=-\frac{1}{2}$',
          xy=(theta, cos(theta)), xycoords='data',
          xytext=(-90, -50), textcoords='offset points', fontsize=16,
          arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

# Exibe as funções
plot(X, C, color="red", linewidth=1.5, linestyle="-", label=r'$\cos(\theta)$')
plot(X, S, color="green", linewidth=1.5, linestyle="-", label=r'$\sin(\theta)$')

# Adiciona a legenda
legend(loc='upper left')
Out[4]:
<matplotlib.legend.Legend at 0x7f36f03bb3d0>

Armazenamento de figuras em arquivo

Uma das funções da Matplotlib é auxiliar os pesquisadores na preparação de gráficos para publicação em periódicos. Ao preparar um manuscrito, é comum o pesquisador se deparar com orientações como esta:

Suas figuras deveriam ser preparadas como qualidade de publicação, utilizando aplicações capazes de gerar arquivos TIFF de alta resolução (1200 dpi para linhas e 300 dpi para arte colorida ou half-tone.

In Preparing Your Manuscript, Oxford Journals

Exigências como a acima podem ser facilmente atendidas pela Matplotlib, que possui uma função savefig capaz de exportar o gráfico para um arquivo em disco, em diversos formatos, com resolução definida pelo pesquisador:

In [5]:
fig.savefig('trig.tif', dpi=1200)

Na ausência de ilustrações bitmap, uma alternativa é armazenar a imagem em um formato vetorial, suportado por exemplos em arquivos PDF e EPS:

In [6]:
fig.savefig('trig.pdf')

Subplots

In [7]:
# 1 linha, 2 colunas, posição 1
subplot(1, 2, 1)
plot(X, C, 'r-')
# 1 linha, 2 colunas, posição 2
subplot(1, 2, 2)
plot(X, S, 'g-')
Out[7]:
[<matplotlib.lines.Line2D at 0x7f36f036cd50>]
In [8]:
# 2 linhas, 2 colunas, posição 1
subplot(2, 2, 1)
plot(X, C, 'r-')

# 2 linha, 2 colunas, posição 2
subplot(2, 2, 2)
plot(X, S, 'g-')

# 2 linha, 2 colunas, posição 3
subplot(2, 2, 3)
plot(X, [tan(x) for x in X], 'b-')

# 2 linha, 2 colunas, posição 4
subplot(2, 2, 4)
plot(X, [cosh(x) for x in X], 'c-')
Out[8]:
[<matplotlib.lines.Line2D at 0x7f36eff35d90>]

Outros tipos de gráficos

Scatter plots

In [9]:
n = 1024
X = random.normal(0,1,n)
Y = random.normal(0,1,n)
scatter(X,Y)
Out[9]:
<matplotlib.collections.PathCollection at 0x7f36efd6ec90>

Um clássico: Iris Dataset

Este conjunto de dados é famoso na literatura de reconhecimento de padrões, sendo apresentado pela primeira vez por R. A. Fisher em 1950. Nele há 3 classes da planta Iris: Iris Setosa, Iris Virginica e Iris Versicolor. Cada classe possui 50 amostras com 4 medidas: comprimento e largura da sépala, comprimento e largura da pétala.

In [10]:
!head ./data/iris.data.txt
5.1	3.5	1.4	0.2	Iris-setosa
4.9	3.0	1.4	0.2	Iris-setosa
4.7	3.2	1.3	0.2	Iris-setosa
4.6	3.1	1.5	0.2	Iris-setosa
5.0	3.6	1.4	0.2	Iris-setosa
5.4	3.9	1.7	0.4	Iris-setosa
4.6	3.4	1.4	0.3	Iris-setosa
5.0	3.4	1.5	0.2	Iris-setosa
4.4	2.9	1.4	0.2	Iris-setosa
4.9	3.1	1.5	0.1	Iris-setosa

O código abaixo apenas carrega os dados das 3 classes de planta a partir do arquivo:

In [11]:
iris_data = loadtxt('./data/iris.data.txt', usecols=(0,1,2,3))
iris_class = loadtxt('./data/iris.data.txt', dtype='string')[:,4]

setosa = iris_data[iris_class == 'Iris-setosa']
virginica = iris_data[iris_class == 'Iris-virginica']
versicolor = iris_data[iris_class == 'Iris-versicolor']

Podemos definir o símbolo e a cor utilizada em um scatter plot. No exemplo abaixo, círculos vermelhos representam os dados para Setosa, triângulos azuis representam Versicolor e quadrados verdes exibem o dados de Virginica:

In [12]:
scatter(setosa[:,2], setosa[:,3], c='r', marker='o')
scatter(virginica[:,2], virginica[:,3], c='g', marker='s')
scatter(versicolor[:,2], versicolor[:,3], c='b', marker='^')
xlabel(u'comprimento da pétala')
ylabel(u'largura da pétala')
Out[12]:
<matplotlib.text.Text at 0x7f36efd3bdd0>

Imagens

In [13]:
from scipy.misc import lena
L = lena()

imshow(L)
colorbar()
Out[13]:
<matplotlib.colorbar.Colorbar instance at 0x7f371848cb90>
In [14]:
imshow(L, cmap=cm.gray)
colorbar()
Out[14]:
<matplotlib.colorbar.Colorbar instance at 0x7f3718301b48>

Barras

In [15]:
x = arange(20)
y = random.rand(20) + 1.
print x
print y
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]
[ 1.29827626  1.13998666  1.83450361  1.24080887  1.48694486  1.50219328
  1.3579808   1.74010606  1.93692425  1.24497407  1.85590657  1.37243084
  1.7797088   1.3252025   1.46785906  1.97451267  1.50515421  1.94232546
  1.44680971  1.04701475]
In [16]:
bar(x, y)
Out[16]:
<Container object of 20 artists>

Um exemplo mais elaborado

In [17]:
n = 12
X = arange(n)
Y = (1 - X / float(n)) * np.random.uniform(0.5, 1.0, n)

axes([0.025, 0.025, 0.95, 0.95])
bar(X, Y, facecolor='#9999ff', edgecolor='gray')

for x, y in zip(X, Y):
    text(x + 0.4, y + 0.05, '%.2f' % y, ha='center', va='bottom')

xlim(-.5, n)
xticks(())
ylim(0, 1.25)
yticks(())
Out[17]:
([], <a list of 0 Text yticklabel objects>)

Histogramas

In [18]:
x = random.randn(10000)
n, bins, patches = hist(x, 100)

A galeria da Matplotlib

Diversos exemplos de como utilizar a Matplotlib podem ser encontrados na galeria.

John Hunter (1968-2012)

Em 28 de agosto de 2012, John D. Hunter, o criador da matplotlib, faleceu devido a complicações durante o tratamento de um câncer. Ele foi diagnosticado em julho de 2012, logo após sua palestra na conferência SciPy, falecendo em agosto do mesmo ano.

Em retribuição a seu trabalho, a comunidade Python criou o John Hunter Memorial Fund, destinado principalmente ao fomento da educação de suas três filhas.

In [19]:
john = imread('./data/john-hunter.jpg')
imshow(john)
title('John D. Hunter')
axis('off')
Out[19]:
(-0.5, 599.5, 573.5, -0.5)

Exercício 6

  • Codifique alguma função $f(x)$ que achar interessante
  • Utilize plot para exibí-la
  • Leia a documentação utilizando plot? e varie os parâmetro para alterar seu gráfico
  • Navegue pela galeria e veja os vários recursos oferecidos pela Matplotlib