fbpixel
Etiquetas:

O pacote Matplotlib Python é uma ferramenta poderosa para criar gráficos e analisar dados em formato gráfico. Neste tutorial, vamos ver como utilizar esta biblioteca e algumas das caraterísticas que precisa de conhecer.

Instalar o Matplotlib

A biblioteca Matplotlib é instalada como qualquer outro pacote Python

python -m pip install matplotlib

Para manipular os dados, pode utilizar o Numpy e o Panda

python -m pip install numpy pandas

Recuperação de dados a rastrear

É possível recuperar dados de ficheiros CSV com o Pandas

timemyData
032.0
146.2
22490
10-2,45
import pandas as pd
df = pd.read_csv(filename,sep=";",encoding = "ISO-8859-1",header=1)
mydata = df["myData"]

Também é possível processar os dados criados pelo seu programa com o Numpy

import numpy as np

ylist=[]
x = np.linspace(0, 10, 1000)

for i in range(8):
    y = np.random.randn(1)*np.sin((i+1)*np.random.randn(1)*x) # + 0.8 * np.random.randn(50)
    ylist.append(y)

Vamos utilizar este último método para desenhar curvas

Desenhar uma figura simples

Para traçar uma curva, comece por criar uma janela (figura) e depois crie uma curva (traçado).

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

#plt.close('all') #close all figure

#process data
ylist=[]
x = np.linspace(0, 10, 1000)

for i in range(8):
    y = np.random.randn(1)*np.sin((i+1)*np.random.randn(1)*x)
    ylist.append(y)

#single plot
fig = plt.figure()
plt.plot(x, y) # plot(y)

#mutliple plots
fig = plt.figure()
for y in ylist:
    plt.plot(x, y)
python-matplotlib-simplest-plot Criar gráficos com Matplotlib em Python
python-matplotlib-several-plots Criar gráficos com Matplotlib em Python

O gráfico é apresentado na figura ativa. Para tornar uma figura ativa, pode atribuir-lhe nomes ou números ou recordar a ordem pela qual foi criada.

fig1 = plt.figure(1)
fig2 = plt.figure(2)
fig3 = plt.figure("myData")
# use fig2
plt.figure(1) # make fig1 active 
#use fig1

Números aproximados

Depois de ter feito o que pretendia com a figura, pode fechá-la com o comando plt.close().

plt.close() #close active figure
plt.close(1) # plot first created figure or figure 1
plt.close("myData") #plot figure named myData
plt.close('all') # close all figures

N.B.: plt.close(‘all’) pode ser colocado no início do programa para fechar todas as janelas previamente abertas quando o programa é executado.

Guardar uma figura em formato de imagem

É possível guardar cada imagem traçada utilizando o ícone de guardar na janela. Também pode pedir ao pyplot para guardar a figura em formato PNG ou JPG.

plt.savefig("myImg.jpg",bbox_inches='tight') #png no label

Personalizar a figura

Vimos que podemos atribuir um identificador à figura (plt.figure(“myData”). É possível definir outros parâmetros, nomeadamente

  • o tamanho da janela figsize
  • a cor de fundo facecor
  • especificar um título suptitle
pyplot.figure(num=None, figsize=None, dpi=None, *, facecolor=None, edgecolor=None, frameon=True, FigureClass=<class 'matplotlib.figure.Figure'>, clear=False, **kwargs)
#customize figure
fig = plt.figure("myData",figsize=(12,4),facecolor=(0.5, 0.8, 0.3))
fig.suptitle("myFigure")
plt.plot(x, y)
matplotlib-figure-customization Criar gráficos com Matplotlib em Python

Personalizar o gráfico

Para completar a personalização da figura, podemos personalizar o gráfico

  • o título do gráfico
  • etiquetas de eixo
  • a legenda e a sua posição
  • o extremo dos eixos
#customize plot
fig = plt.figure("myData",figsize=(12,4),facecolor=(1, 1, 1))
plt.title("myData y(x)")
plt.plot(x, y, label="y(x)")
plt.axis([min(x)-1, max(x)+1, min(y)*1.05, max(y)*1.05]);
plt.xlabel("x [s]")
plt.ylabel("y [SI]")
plt.legend(loc='upper left')
matplotlib-plot-customization Criar gráficos com Matplotlib em Python

Personalizar a curva

Como vimos, quando desenha várias curvas, o Matplotlib seleciona estilos diferentes para cada curva. É possível personalizar as curvas de uma forma específica.

  • estilo de linha (ls)
  • cor da linha cor
  • largura da linha largura da linha (lw)
  • marcador de estilo marcador
  • markerfacecor (mfc) markeredgecor (mec)
  • tamanho do marcador tamanho do marcador (ms)
## customize curve
fig = plt.figure()
plt.plot(x, y, "ko--")
plt.axis([4, 4.5, min(y)*1.05, max(y)*1.05]);
#plt.plot(x, y, color="k", linestyle="--", linewidth=1, marker= "o") #equivalent
matplotlib-curve-customization Criar gráficos com Matplotlib em Python
#customize marker
fig = plt.figure()
plt.plot(x, y, marker = 'o', ms = 5, mfc = 'r', mec = 'k')
plt.axis([4, 4.5, min(y)*1.05, max(y)*1.05]);
matplotlib-marker-customization Criar gráficos com Matplotlib em Python

Criar uma função para desenhar curvas

Como há um grande número de parâmetros a definir para a criação de gráficos com o Matplotlib, aconselho-o vivamente a criar uma função de criação de gráficos que simplifique a sua vida e que possa ser adaptada conforme necessário.

# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
import numpy as np

plt.close("all")

ylist=[]
ylbl = []
x = np.linspace(0, 10, 1000)

for i in range(8):
    y = np.random.choice([-1,1])*(i+1)*np.sin((i+1)*x)
    ylist.append(y)
    ylbl.append('y{}(x)'.format(i))
    
##styles options
lstyles= ['-', '--', '-.', ':', 'None', ' ', '', 'solid', 'dashed', 'dashdot', 'dotted']
markers = [None,'o','*','.',',','x','X','+','P','s','D','d','p','H','h','v','^','<','>','1','2','3','4','|','_']


def tracefig(x,y,lbl,ls=None,mrkr=None,title=None,xlbl=None,ylbl=None,size=(12,4),zoomx=None,gridon=False):
    fig = plt.figure(figsize=size,facecolor=(1, 1, 1))
    if title is not None:
        title = "tracefig - {}".format(title)
        plt.title(title)

    if type(y) is not list:
        if ls is None:
            ls=np.random.choice(lstyles)
        if mrkr is None:
            mrkr=np.random.choice(markers) 
        plt.plot(x, y, linestyle=ls, marker = mrkr, label=lbl)
    else:
        for i,y in enumerate(ylist):
            if ls is None:
                ls=np.random.choice(lstyles)
            if mrkr is None:
                mrkr=np.random.choice(markers) 
            plt.plot(x, y, linestyle=ls, marker = mrkr, label=lbl[i])
    plt.xlabel(xlbl)
    plt.ylabel(ylbl)
    plt.legend(loc='upper left')
    if zoomx is None:
        plt.axis([min(x), max(x), np.min(ylist)*1.2, np.max(ylist)*1.2]); 
    else:
        plt.axis([zoomx[0], zoomx[1], np.min(ylist)*1.2, np.max(ylist)*1.2]); 
        
    if gridon:
        plt.grid() #diplay grid

    return fig

fig = tracefig(x,y,"y(x)",ls="-",mrkr="o",title="Single plot",xlbl="x [s]",ylbl="y [SI]",size=(12,4),zoomx=[0,2])    
fig = tracefig(x,ylist,ylbl,ls="-",mrkr=None,title="Multi plots",xlbl="x [s]",ylbl="y [SI]",size=(12,4),zoomx=[0,2], gridon=True)    
matplotlib-tracefig-single Criar gráficos com Matplotlib em Python
matplotlib-tracefig-multi Criar gráficos com Matplotlib em Python

Com estes conhecimentos, pode desenhar e analisar todos os tipos de curvas utilizando Matplotlib e Python.

Visualizar nuvens de pontos

Para a análise de dados, também é possível apresentar gráficos de dispersão. Neste exemplo, corimos os pontos em função de uma terceira variável

import matplotlib.pyplot as plt
import numpy as np

plt.close("all")
    
x = np.random.randn(50)
y = np.random.randn(50)
z = np.random.randint(1,100,50) #np.random.randn(50)

value=(z>50)
colors = np.where( value==True , "red", "#3498db")
fig = plt.figure()
plt.scatter(x,y,marker='s',color=colors)

plt.show()
matplotlib-scatter-cors-1 Criar gráficos com Matplotlib em Python

Desenhar histogramas

Para cada tipo de dados existe uma representação adequada. Em alguns casos, um histograma é mais significativo.

import matplotlib.pyplot as plt
import numpy as np

plt.close("all")

nb = 10
x_multi = [np.random.randn(n) for n in [10000, 5000, 2000]]

fig = plt.figure()
plt.hist(x_multi, nb, histtype='bar', label=['d1','d2','d3'])
plt.legend(prop={'size': 10})
plt.title('Histogram')
plt.show() 
matplotlib-histogram-cors Criar gráficos com Matplotlib em Python

Desenhar gráficos de pizza

import matplotlib.pyplot as plt

labels = 'Insurance', 'Workshop', 'Salary', 'Bank'
sizes = [15, 30, 45, 10]
explode = (0, 0.05, 0, 0)

fig, ax = plt.subplots()
ax.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',colors=['olivedrab', 'rosybrown', 'gray', 'saddlebrown'],startangle=80)
matplotlib-pie-diagram Criar gráficos com Matplotlib em Python

Desenhar contornos

Os contornos são úteis para traçar dados 3D, tais como gradientes, em 2D.

import numpy as np
import matplotlib.pyplot as plt

def g(x, obs = [[-2,0],[8,-5]], param = [[1000,20, 60],[500,10, 30]]):
	res = 200
	for i in range(0,len(obs)):
		alpha_obstacle, a_obstacle,b_obstacle = param[i]
		x_obstacle , y_obstacle = obs[i]
		res += -alpha_obstacle * np.exp(-((x[0] - x_obstacle)**2 / a_obstacle
								   + (x[1] - y_obstacle)**2 / b_obstacle)) 
	return res 

x = np.linspace(-10, 10, 200)
y = np.linspace(-10, 10, 200)
X = np.meshgrid(x, y)
Z = g(X)
	
CS = plt.contour(X[0], X[1], Z) #, colors='black')
plt.clabel(CS, fontsize=9, inline=True)
plt.show()
matplotlib-contours Criar gráficos com Matplotlib em Python

Criar gráficos com Matplotlib

Para uma visão mais abrangente dos dados, uma técnica importante é poder traçar vários gráficos na mesma figura.

Utilização de subparcelas

É possível dividir uma figura em linhas e colunas para organizar as curvas de forma mais clara e ligar os eixos mais facilmente.

fig = plt.figure()
ax_list = fig.subplots(row, col, sharex=True, sharey=True)
import matplotlib.pyplot as plt
import numpy as np

plt.close("all")

ylist=[]
ylbl = []
x = np.linspace(0, 10, 1000)

for i in range(8):
    y = np.random.choice([-1,1])*(i+1)*np.sin((i+1)*x)
    ylist.append(y)
    ylbl.append('y{}(x)'.format(i))
    

fig2 = plt.figure(figsize=(8, 6))
fig2.suptitle("my Plots")

#devide figure in 3 rows and 2 columns with shared axis
(row1col1, row1col2),(row2col1, row2col2),(row3col1, row3col2) = fig2.subplots(3, 2,sharex=True,sharey=True)

ax = row1col1
ax.plot(x, ylist[0], label="y1(x)")
ax.set_title('Y(X)')
ax = row1col2
ax.plot(x, ylist[1], label="y1(x)")
ax = row2col1
ax.plot(x, ylist[2], label="y2(x)")
ax = row2col2
ax.plot(x, ylist[3], label="y3(x)")
ax = row3col1
ax.plot(x, ylist[4], label="y4(x)")
ax = row3col2
ax.plot(x, ylist[5], label="y5(x)")
matplotlib-subplots Criar gráficos com Matplotlib em Python

Utilização de subfiguras

Para layouts mais complexos, é possível utilizar a subfigura

fig = plt.figure(figsize=(10, 8))

(row1fig, row2fig) = fig.subfigures(2, 1, height_ratios=[1, 2])
row1fig.suptitle("Subfigure")
(fig_row2left, fig_row2right) = row2fig.subfigures(1, 2)

row1_ax = row1fig.add_subplot()
row2l_axs = fig_row2left.subplots(2,1)
row2r_ax = fig_row2right.add_subplot()

ax = row1_ax
ax.plot(x, ylist[0])
ax = row2l_axs[0]
ax.plot(x, ylist[2],'ro-')
ax = row2l_axs[1]
ax.plot(x, ylist[3],'k.-')
ax = row2r_ax
ax.plot(ylist[4], ylist[5],'g-')
matplotlib-subfigures Criar gráficos com Matplotlib em Python

Utilização do GridSpec

O GridSpec torna possível desenhar rapidamente layouts complexos. Em vez de dividir as áreas uma após a outra, vamos definir uma grelha que será preenchida à medida que avançamos com sub-gráficos.

fig = plt.figure(figsize=(10, 8))
fig.suptitle("GridSpec")
gs = plt.GridSpec(3, 3)
gs.update(wspace=0.4, hspace=0.6)

col1fig0     = fig.add_subplot(gs[0, :2])
col1fig1     = fig.add_subplot(gs[1, :2],sharex=col1fig0)
col1fig2     = fig.add_subplot(gs[2, :2],sharex=col1fig0)
col2fig0     = fig.add_subplot(gs[:1, 2])
col2fig1     = fig.add_subplot(gs[1:, 2])


ax=col1fig0
ax.plot(x, ylist[1], label="y1(x)")
ax=col1fig1
ax.plot(x, ylist[2], 'kx-',label="y2(x)")
ax=col1fig2
ax.plot(x, ylist[3], 'ro:', label="y3(x)")
ax=col2fig0
ax.plot(ylist[4], ylist[5], 'g-',label="y5(y4)")
ax=col2fig1
ax.plot(ylist[6],x,'s',  label="y6(x)")
fig.legend(loc='upper left')
matplotlib-gridspec Criar gráficos com Matplotlib em Python

N.B.: Pode combinar subfigura, subparcela e gridspec e encaixá-los como quiser para criar os gráficos mais bonitos.

Adicionar um cursor aos seus gráficos

Para facilitar a leitura, pode adicionar um cursor para visualizar certos pormenores com mais precisão. Este cursor pode ser partilhado entre várias curvas. Por exemplo, podemos adicionar um cursor às três curvas à esquerda da figura anterior e definir os seguintes parâmetros

  • ls estilo de linha
  • lw largura da linha
  • cor
  • horizOn linha horizontal
  • verdeNa linha vertical
from matplotlib.widgets import MultiCursor
figlist = (col1fig0,col1fig1,col1fig2)
cursor = MultiCursor(fig.canvas, figlist, color='r',lw=0.5, ls='--', horizOn=True,vertOn=True)
matplotlib-widget-cursor Criar gráficos com Matplotlib em Python

Detetar eventos do rato

Para além de desenhar e animar curvas, também pode utilizar o rato para interagir com o gráfico.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backend_bases import MouseButton

def on_click(event):
	if event.button is MouseButton.LEFT:
		print("Click detected at X,Y: {}".format([event.xdata, event.ydata]))
fig = plt.figure()
plt.plot([0,1],[0,2])
plt.connect('button_press_event', on_click)

plt.show()
matplotlib-mouse-event Criar gráficos com Matplotlib em Python

Criar uma animação com Matplotlib

É possível criar gráficos animados e guardá-los em vários formatos utilizando a ferramenta matplotlib.animation. Para tal, é necessário traçar o gráfico quadro a quadro numa função update(frame), que devolve o objeto que contém o gráfico (neste caso, a curva).

import math
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

#create data
#process data
x = np.linspace(0, 10, 100)
y =  np.sin(2*x)

# plot first point
fig = plt.figure()
curve = plt.plot(x[0], y[0])
plt.axis([0, 10, -1.2, 1.2])

def update(frame):
    # update data
    xi = x[:frame]
    yi = y[:frame]
    
    # update plot
    curve[0].set_xdata(xi)
    curve[0].set_ydata(yi)
    return (curve)

#display animation
ani = animation.FuncAnimation(fig=fig, func=update, frames=100, interval=30)
plt.show()
#save animation as gif
ani.save(filename="./tmp/sinewave.gif", writer="pillow")
sinewave Criar gráficos com Matplotlib em Python

Existem diferentes formas de criar animações, consoante os tipos de dados. Também pode guardar as animações em diferentes formatos, consoante a sua utilização. Não hesite em consultar a documentação sobre animações.

Aplicações

Fontes