fbpixel
Etiquetas:

El paquete Matplotlib de Python es una potente herramienta para crear gráficos y analizar datos de forma gráfica. En este tutorial veremos cómo utilizar esta biblioteca y algunas de las funciones que debes conocer.

Instalación de Matplotlib

La biblioteca Matplotlib se instala como cualquier otro paquete de Python

python -m pip install matplotlib

Para manipular los datos, puede utilizar Numpy y Panda

python -m pip install numpy pandas

Recuperación de los datos a rastrear

Es posible recuperar datos de archivos CSV con 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"]

También es posible procesar los datos creados por tu programa con 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 a utilizar este último método para dibujar curvas

Dibujar una figura sencilla

Para trazar una curva, cree primero una ventana (figura) y, a continuación, una curva (trazado).

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 Creación de gráficos con Matplotlib en Python
python-matplotlib-several-plots Creación de gráficos con Matplotlib en Python

Para que una figura esté activa, puede darles nombres o números o recordar el orden de creación.

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

Cerrar cifras

Una vez que haya hecho lo que quería con la figura, puede cerrarla con el 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”) puede colocarse al inicio del programa para cerrar todas las ventanas abiertas previamente al ejecutar el programa.

Guardar una figura en formato de imagen

Es posible guardar cada imagen trazada utilizando el icono de guardar en la ventana. También puede pedir a pyplot que guarde la figura en formato PNG o JPG.

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

Personalizar la figura

Vimos que podíamos dar un identificador a la figura (plt.figure(«misDatos»). Es posible definir otros parámetros, en particular

  • el tamaño de la ventana figsize
  • el color de fondo facecolor
  • especificar un 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 Creación de gráficos con Matplotlib en Python

Personalizar el gráfico

Para completar la personalización de la figura, podemos personalizar el gráfico

  • el título del gráfico
  • etiquetas de eje
  • la leyenda y su posición
  • el extremo de los ejes
#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 Creación de gráficos con Matplotlib en Python

Personalizar la curva

Como hemos visto, cuando se dibujan varias curvas, Matplotlib selecciona diferentes estilos para cada curva. Es posible personalizar las curvas de forma específica.

  • estilo de línea (ls)
  • línea color color
  • ancho de línea ancho de línea (lw)
  • marcador estilo marcador
  • markerfacecolor (mfc) markeredgecolor (mec)
  • tamaño del marcador markersize (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 Creación de gráficos con Matplotlib en 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 Creación de gráficos con Matplotlib en Python

Crear una función para dibujar curvas

Como hay un gran número de parámetros a definir para trazar con Matplotlib, te aconsejo encarecidamente que crees una función de trazado que te simplifique la vida y que puedas adaptar según necesites.

# -*- 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 Creación de gráficos con Matplotlib en Python
matplotlib-tracefig-multi Creación de gráficos con Matplotlib en Python

Con estos conocimientos, podrás trazar y analizar todo tipo de curvas utilizando Matplotlib y Python.

Visualización de nubes de puntos

Para el análisis de datos, también es posible visualizar gráficos de dispersión. En este ejemplo, coloreamos los puntos en función de una tercera variable

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-colors-1 Creación de gráficos con Matplotlib en Python

Dibujar histogramas

Para cada tipo de datos existe una representación adecuada. En algunos casos, un histograma es más 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-colors Creación de gráficos con Matplotlib en Python

Dibujar gráficos circulares

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 Creación de gráficos con Matplotlib en Python

Dibujar contornos

Los contornos son útiles para trazar datos 3D, como gradientes, en 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 Creación de gráficos con Matplotlib en Python

Creación de gráficos con Matplotlib

Para obtener una visión más completa de los datos, una técnica importante es poder trazar varios gráficos en la misma figura.

Uso de subtramas

Es posible dividir una figura en filas y columnas para organizar las curvas con mayor claridad y enlazar los ejes más fácilmente.

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 Creación de gráficos con Matplotlib en Python

Utilizar subfiguras

Para disposiciones más complejas, puede utilizar la 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 Creación de gráficos con Matplotlib en Python

Uso de GridSpec

GridSpec permite dibujar rápidamente diseños complejos. En lugar de dividir las áreas una tras otra, definiremos una cuadrícula que iremos rellenando con subgrá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 Creación de gráficos con Matplotlib en Python

N.B.: Puedes combinar subfigure, subplot y gridspec y anidarlos como quieras para crear tus gráficos más bonitos.

Añade un cursor a tus gráficos

Para facilitar la lectura, puede añadir un cursor para ver ciertos detalles con mayor precisión. Este cursor puede compartirse entre varias curvas. Por ejemplo, podemos añadir un cursor a las tres curvas de la izquierda de la figura anterior y definir estos parámetros

  • ls estilo de línea
  • lw ancho de línea
  • color
  • horizOn línea horizontal
  • verdeEn línea 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 Creación de gráficos con Matplotlib en Python

Detección de eventos de ratón

Además de dibujar y animar curvas, también puedes utilizar el ratón para interactuar con el 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 Creación de gráficos con Matplotlib en Python

Crear una animación con Matplotlib

Puedes crear gráficas animadas y guardarlas en varios formatos utilizando la herramienta matplotlib.animation. Para ello, es necesario trazar el gráfico fotograma a fotograma en una función update(frame), que devuelve el objeto que contiene el gráfico (en este caso 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 Creación de gráficos con Matplotlib en Python

Existen diferentes formas de crear animaciones en función de sus tipos de datos. También puede guardar las animaciones en diferentes formatos dependiendo de su uso. No dude en consultar la documentación sobre animaciones.

Aplicaciones

Fuentes