Cómo hacer gráficos en tiempo real con Matplotlib: Guía completa

En el análisis de datos moderno, la visualización de datos en tiempo real se ha vuelto cada vez más importante. Matplotlib es una de las bibliotecas de visualización de datos más utilizadas en Python y, aprovechando sus funciones, es posible crear gráficos en tiempo real con facilidad. En esta guía, explicaremos paso a paso cómo realizar gráficos en tiempo real con Matplotlib, desde los conceptos básicos hasta aplicaciones avanzadas, con ejemplos de código específicos.

Índice

Conceptos básicos de los gráficos en tiempo real

Un gráfico en tiempo real es una técnica que permite actualizar los gráficos dinámicamente conforme se actualizan los datos. Esto es crucial en muchas aplicaciones, como la monitorización de datos de sensores o de mercados financieros. La idea básica es obtener datos y actualizar el gráfico periódicamente. Para ello, aprovecharemos la función de animación y los bucles de actualización de Matplotlib. Primero, vamos a comprender el flujo general de los gráficos en tiempo real y los elementos necesarios.

Instalación y configuración de Matplotlib

Para realizar gráficos en tiempo real, primero es necesario instalar y configurar Matplotlib. Sigamos los siguientes pasos.

Instalación de Matplotlib

Como Matplotlib no está incluido en la biblioteca estándar de Python, necesitamos instalarlo usando pip. Utilice el siguiente comando para instalarlo.

pip install matplotlib

Instalación de otras bibliotecas necesarias

Para implementar gráficos en tiempo real, además de Matplotlib, es común utilizar otras bibliotecas. Asegúrese de instalarlas también usando pip.

pip install numpy
pip install pandas

Configuración básica

Una vez completada la instalación, realice la configuración básica. Primero, importe las bibliotecas en su script de Python o en un Jupyter Notebook.

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

Verificación de funcionamiento

Para verificar que la instalación y configuración se han realizado correctamente, cree un gráfico simple. Ejecute el siguiente código y confirme que Matplotlib funciona correctamente.

import matplotlib.pyplot as plt

plt.plot([1, 2, 3, 4], [1, 4, 9, 16])
plt.xlabel('Etiqueta del eje x')
plt.ylabel('Etiqueta del eje y')
plt.title('Gráfico de prueba')
plt.show()

Si el gráfico se muestra correctamente, la instalación y configuración están completas. En el siguiente paso, veremos cómo obtener datos en tiempo real.

Métodos para la obtención de datos

Para lograr gráficos en tiempo real, primero es necesario comprender cómo obtener datos en tiempo real. Hay varios métodos para obtener datos; aquí presentamos algunos métodos comunes.

Obtención de datos de sensores

Para obtener datos en tiempo real de un sensor, se necesita una biblioteca que permita la comunicación con el hardware. Por ejemplo, al recopilar datos de sensores utilizando Arduino o Raspberry Pi, se puede utilizar una biblioteca de Python como pyserial para obtener los datos.

import serial

ser = serial.Serial('COM3', 9600)  # Especifique el puerto y la tasa de baudios
while True:
    data = ser.readline().decode('utf-8').strip()
    print(data)

Obtención de datos desde una API

Otra forma de obtener datos en tiempo real es utilizando una API. Por ejemplo, puede obtener datos de precios de acciones o información meteorológica utilizando una API pública en Internet. A continuación se muestra un ejemplo de cómo obtener datos de una API usando la biblioteca requests.

import requests
import time

url = 'https://api.example.com/data'
while True:
    response = requests.get(url)
    data = response.json()
    print(data)
    time.sleep(5)  # Obtiene datos cada 5 segundos

Obtención de datos desde una base de datos

Si obtiene datos en tiempo real desde una base de datos, utilice una biblioteca cliente para bases de datos. A continuación, se muestra un ejemplo de cómo obtener datos periódicamente de una base de datos SQLite.

import sqlite3
import time

conn = sqlite3.connect('example.db')
cursor = conn.cursor()

while True:
    cursor.execute("SELECT * FROM data_table ORDER BY timestamp DESC LIMIT 1")
    data = cursor.fetchone()
    print(data)
    time.sleep(5)  # Obtiene datos cada 5 segundos

Generación de datos simulados

Para propósitos de prueba, también puede simular datos en tiempo real. A continuación se muestra un ejemplo de cómo generar datos aleatorios utilizando numpy.

import numpy as np
import time

while True:
    data = np.random.random()
    print(data)
    time.sleep(1)  # Genera datos aleatorios cada segundo

Utilizando estos métodos, puede obtener datos en tiempo real y, en el siguiente paso, aprenderemos a graficarlos en tiempo real.

Implementación básica de gráficos en tiempo real

Para implementar gráficos en tiempo real, es necesario un mecanismo que actualice el gráfico periódicamente con los datos obtenidos. Aquí presentamos el método básico para implementar gráficos en tiempo real usando Matplotlib.

Actualización básica del gráfico

En Matplotlib, puede utilizar la clase FuncAnimation para actualizar el gráfico en tiempo real. El siguiente ejemplo muestra cómo graficar datos aleatorios en tiempo real.

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

# Lista para almacenar datos
x_data = []
y_data = []

# Configuración del gráfico
fig, ax = plt.subplots()
line, = ax.plot([], [], 'r-')

# Configuración inicial del gráfico
def init():
    ax.set_xlim(0, 100)
    ax.set_ylim(0, 1)
    return line,

# Función de actualización de datos
def update(frame):
    x_data.append(frame)
    y_data.append(np.random.random())

    # Elimina los datos antiguos si superan cierto límite
    if len(x_data) > 100:
        x_data.pop(0)
        y_data.pop(0)

    line.set_data(x_data, y_data)
    return line,

# Configuración de la animación
ani = animation.FuncAnimation(fig, update, frames=np.arange(0, 200), init_func=init, blit=True)

plt.show()

En este código, se grafican datos aleatorios en tiempo real mediante la actualización periódica del gráfico. Este es solo el inicio; en el siguiente paso, exploraremos cómo combinar la obtención de datos con el gráfico en tiempo real.

Ejemplo de aplicación: Gráfico en tiempo real de datos de acciones

El gráfico en tiempo real de datos de acciones es muy útil para traders e inversores. Aquí, se muestra cómo obtener y graficar datos en tiempo real de acciones utilizando la API de Yahoo Finance.

Configuración de la API de Yahoo Finance

Primero, instale la biblioteca yfinance. Esta biblioteca facilita la obtención de datos de acciones desde Yahoo Finance.

pip install yfinance

Obtención y graficación de datos en tiempo real

El siguiente código utiliza yfinance para obtener datos en tiempo real de una acción específica y graficarlos con Matplotlib.

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import yfinance as yf
import datetime

# Preparar listas para almacenar los datos
x_data, y_data = [], []

fig, ax = plt.subplots()
line, = ax.plot([], [], 'g-')

# Función de inicialización
def init():
    ax.set_xlim(0, 100)
    ax.set_ylim(0, 500)  # Configurar el rango de precios
    return line,

# Función de actualización
def update(frame):
    current_time = datetime.datetime.now().strftime('%H:%M:%S')
    x_data.append(current_time)

    # Obtener datos de acciones desde la API de Yahoo Finance
    stock = yf.Ticker('AAPL')
    data = stock.history(period='1m')
    y_data.append(data['Close'][-1])

    # Eliminar datos antiguos si se supera un cierto límite
    if len(x_data) > 100:
        x_data.pop(0)
        y_data.pop(0)

    line.set_data(range(len(x_data)), y_data)

    ax.set_xticks(range(0, len(x_data), 10))
    ax.set_xticklabels(x_data[::10], rotation=45, ha='right')

    return line,

ani = animation.FuncAnimation(fig, update, frames=np.arange(0, 100), init_func=init, blit=True, interval=60000)
plt.xlabel('Tiempo')
plt.ylabel('Precio de la acción ($)')
plt.title('Gráfico en tiempo real del precio de AAPL')
plt.show()

En este código, se obtiene el precio de las acciones de Apple (AAPL) cada minuto y se grafica en tiempo real. La función FuncAnimation llama a la función update cada minuto para actualizar el gráfico.

Guardado y registro de datos

Además de graficar los precios en tiempo real, es importante guardar los datos para analizarlos más tarde. En el siguiente código, se guarda la información en un archivo CSV mientras se grafican los datos.

import csv

# Abrir archivo CSV
with open('stock_data.csv', mode='w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow(['Tiempo', 'Precio'])

    def update(frame):
        current_time = datetime.datetime.now().strftime('%H:%M:%S')
        x_data.append(current_time)

        # Obtener datos de acciones desde la API de Yahoo Finance
        stock = yf.Ticker('AAPL')
        data = stock.history(period='1m')
        price = data['Close'][-1]
        y_data.append(price)

        # Escribir datos en el archivo CSV
        writer.writerow([current_time, price])

        # Eliminar datos antiguos si se supera un cierto límite
        if len(x_data) > 100:
            x_data.pop(0)
            y_data.pop(0)

        line.set_data(range(len(x_data)), y_data)

        ax.set_xticks(range(0, len(x_data), 10))
        ax.set_xticklabels(x_data[::10], rotation=45, ha='right')

        return line,

    ani = animation.FuncAnimation(fig, update, frames=np.arange(0, 100), init_func=init, blit=True, interval=60000)
    plt.xlabel('Tiempo')
    plt.ylabel('Precio de la acción ($)')
    plt.title('Gráfico en tiempo real del precio de AAPL')
    plt.show()

Este código guarda los datos que se grafican en tiempo real en el archivo stock_data.csv, logrando así una visualización en tiempo real y un registro persistente de los datos.

En la siguiente sección, explicaremos cómo guardar y compartir los datos.

Guardado y compartición de datos

No solo es importante graficar en tiempo real, sino también almacenar los datos recopilados para analizarlos o compartirlos más adelante. Aquí, se explica cómo guardar y compartir los datos del gráfico en tiempo real.

Método de guardado de datos

Un formato comúnmente utilizado para guardar datos es CSV (valores separados por comas). En Python, se puede escribir fácilmente en archivos CSV utilizando el módulo csv.

import csv

# Abrir archivo CSV
with open('realtime_data.csv', mode='w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow(['Tiempo', 'Valor'])

    def update(frame):
        current_time = datetime.datetime.now().strftime('%H:%M:%S')
        x_data.append(current_time)
        value = np.random.random()  # Se usa un valor aleatorio aquí
        y_data.append(value)

        # Escribir datos en el archivo CSV
        writer.writerow([current_time, value])

        if len(x_data) > 100:
            x_data.pop(0)
            y_data.pop(0)

        line.set_data(range(len(x_data)), y_data)

        ax.set_xticks(range(0, len(x_data), 10))
        ax.set_xticklabels(x_data[::10], rotation=45, ha='right')

        return line,

    ani = animation.FuncAnimation(fig, update, frames=np.arange(0, 100), init_func=init, blit=True, interval=1000)
    plt.xlabel('Tiempo')
    plt.ylabel('Valor de datos')
    plt.title('Gráfico en tiempo real de datos')
    plt.show()

Este código guarda los datos obtenidos en tiempo real en el archivo realtime_data.csv.

Métodos de compartición de datos

Existen varias formas de compartir los datos guardados. A continuación, se presentan algunos métodos comunes.

Compartir por correo electrónico

Una de las maneras más simples es adjuntar el archivo CSV guardado a un correo electrónico y compartirlo.

Uso de almacenamiento en la nube

También es útil compartir datos utilizando servicios de almacenamiento en la nube, como Google Drive o Dropbox.

Guardar en una base de datos

Otra opción es almacenar los datos recopilados en una base de datos, de modo que se pueda acceder a ellos desde aplicaciones web o herramientas de análisis de datos. A continuación, se muestra un ejemplo de cómo guardar los datos en una base de datos SQLite.

import sqlite3

# Abrir conexión a la base de datos
conn = sqlite3.connect('realtime_data.db')
cursor = conn.cursor()

# Crear tabla
cursor.execute('''CREATE TABLE IF NOT EXISTS data (timestamp TEXT, value REAL)''')

def update(frame):
    current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    value = np.random.random()  # Se usa un valor aleatorio aquí
    cursor.execute("INSERT INTO data (timestamp, value) VALUES (?, ?)", (current_time, value))
    conn.commit()

    x_data.append(current_time)
    y_data.append(value)

    if len(x_data) > 100:
        x_data.pop(0)
        y_data.pop(0)

    line.set_data(range(len(x_data)), y_data)

    ax.set_xticks(range(0, len(x_data), 10))
    ax.set_xticklabels(x_data[::10], rotation=45, ha='right')

    return line,

ani = animation.FuncAnimation(fig, update, frames=np.arange(0, 100), init_func=init, blit=True, interval=1000)
plt.xlabel('Tiempo')
plt.ylabel('Valor de datos')
plt.title('Gráfico en tiempo real de datos')
plt.show()

# Cerrar conexión a la base de datos
conn.close()

Este código guarda los datos obtenidos en tiempo real en una base de datos SQLite.

Visualización y análisis de datos

Para visualizar o analizar los datos guardados más adelante, puede usar la biblioteca Pandas. A continuación se muestra un ejemplo de cómo leer un archivo CSV guardado y graficar los datos.

import pandas as pd

# Leer datos
df = pd.read_csv('realtime_data.csv')

# Graficar datos
plt.figure()
plt.plot(df['Tiempo'], df['Valor'])
plt.xlabel('Tiempo')
plt.ylabel('Valor de datos')
plt.title('Gráfico de datos guardados')
plt.xticks(rotation=45, ha='right')
plt.show()

Este código lee el archivo CSV guardado con Pandas y grafica los datos, lo cual permite analizar y visualizar datos históricos.

En la siguiente sección, se explican problemas comunes y soluciones para el graficado en tiempo real.

Solución de problemas

Durante el graficado en tiempo real, pueden surgir varios problemas. Aquí se explican algunos problemas comunes y sus soluciones.

El gráfico no se actualiza

Si el gráfico en tiempo real no se actualiza, puede deberse a las siguientes razones.

Razón 1: Configuración incorrecta de la animación

Si la configuración de FuncAnimation es incorrecta, es posible que el gráfico no se actualice. Si ha configurado blit=True, asegúrese de que las funciones init_func y update estén devolviendo los datos correctamente.

ani = animation.FuncAnimation(fig, update, frames=np.arange(0, 100), init_func=init, blit=True, interval=1000)

Razón 2: Retraso en la obtención de datos

Si la obtención de datos toma mucho tiempo, la actualización del gráfico puede retrasarse. Revise la frecuencia de obtención de datos y el tiempo de respuesta de la API, y ajuste el intervalo adecuadamente.

def update(frame):
    try:
        # Proceso de obtención de datos
        data = requests.get('https://api.example.com/data').json()
        # Actualización de datos
    except Exception as e:
        print(f"Error de obtención de datos: {e}")
    return line,

El gráfico parpadea

Si el gráfico parpadea, puede mejorar al establecer blit=True para realizar actualizaciones parciales de la gráfica.

ani = animation.FuncAnimation(fig, update, frames=np.arange(0, 100), init_func=init, blit=True, interval=1000)

Problemas de fugas de memoria

En gráficos en tiempo real de larga duración, el uso de memoria puede aumentar. Es importante gestionar el uso de memoria eliminando datos innecesarios.

def update(frame):
    x_data.append(frame)
    y_data.append(np.random.random())

    # Eliminar datos antiguos
    if len(x_data) > 100:
        x_data.pop(0)
        y_data.pop(0)

    line.set_data(x_data, y_data)
    return line,

Manejo de errores en la obtención de datos

Al obtener datos en tiempo real, pueden ocurrir errores de red o fallos en la API. Maneje los errores adecuadamente e intente reintentar en caso de problemas.

import time

def update(frame):
    try:
        # Proceso de obtención de datos
        response = requests.get('https://api.example.com/data')
        response.raise_for_status()
        data = response.json()
        y_data.append(data['value'])
    except requests.exceptions.RequestException as e:
        print(f"Error de obtención de datos: {e}")
        time.sleep(5)  # Esperar 5 segundos antes de reintentar
    return line,

Ajuste del rango de visualización

Cuando los valores de los datos cambian dinámicamente, puede ser necesario ajustar el rango de visualización del gráfico de manera dinámica.

def update(frame):
    x_data.append(frame)
    y_data.append(np.random.random())

    if len(x_data) > 100:
        x_data.pop(0)
        y_data.pop(0)

    line.set_data(x_data, y_data)
    ax.set_xlim(max(0, frame - 100), frame)  # Ajuste dinámico del rango de visualización
    ax.set_ylim(min(y_data), max(y_data))    # Ajuste del rango Y en función de los datos
    return line,

Suavizado de datos

Si los datos en tiempo real contienen mucho ruido, el suavizado de datos puede mejorar el efecto visual. En el siguiente ejemplo, se utiliza un promedio móvil para suavizar los datos.

def smooth(data, window_size):
    return np.convolve(data, np.ones(window_size)/window_size, mode='valid')

def update(frame):
    x_data.append(frame)
    y_data.append(np.random.random())

    if len(x_data) > 100:
        x_data.pop(0)
        y_data.pop(0)

    smoothed_data = smooth(y_data, window_size=5)
    line.set_data(range(len(smoothed_data)), smoothed_data)

    ax.set_xlim(0, len(smoothed_data))
    ax.set_ylim(min(smoothed_data), max(smoothed_data))
    return line,

Utilice estos consejos de solución de problemas para resolver problemas de gráficos en tiempo real y lograr una visualización de datos más fluida.

En la siguiente sección, se resumen los contenidos de esta guía.

Resumen

El gráfico de datos en tiempo real es una técnica importante para diversas aplicaciones, como la monitorización de datos de sensores o el seguimiento de precios de acciones. Con Matplotlib, es fácil implementar gráficos en tiempo real en Python.

En esta guía, se detallaron los siguientes puntos:

  • Conceptos básicos del gráfico en tiempo real
  • Instalación y configuración de Matplotlib
  • Métodos para obtener datos desde sensores o APIs
  • Implementación básica del gráfico en tiempo real usando FuncAnimation
  • Configuraciones avanzadas de gráficos usando animación
  • Ejemplos específicos de datos de sensores y de acciones
  • Métodos para guardar y compartir datos
  • Problemas comunes y sus soluciones

Al comprender y practicar estos pasos, podrá visualizar datos en tiempo real de manera más efectiva. La visualización de datos es una herramienta poderosa para captar rápidamente las tendencias y anomalías en los datos. Le invitamos a aplicarlo en sus proyectos e investigaciones futuras.

Índice