Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Grafica animada en Python y qt designer
#1
Buenas tardes soy nuevo en el foro.

Hace unos días me aventuré con python, soy nuevo manejando este lenguaje.

Escribo en este foro para saber si puedo tener ayuda para desarrollar un programa que me está dejando calvo......

Realice una grafica matplotlib que se puede visualizar en QT5 designer, el programa realizadó manda datos aleatoriamente y se grafican en un intervalo de tiempo, pero ahora lo que quiero realizar es que esta grafica este animada, que siempre este leyendo datos aleatoriamente
Código:
#librerias, programa sin animación en QT 5 designer
import sys

from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget
from PyQt5.QtGui import QIcon

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

import random
#-----------


class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.left = 800 #posición de ventana QT
        self.top = 400 #posición de ventana QT
        self.title = 'PyQt5 matplotlib' # Nombre de ventana
        self.width = 640 #Tamaño de ventana
        self.height = 400 #Tamaño de ventana
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title) # nombre de ventana PyQt5 matplotlib
        self.setGeometry(self.left, self.top, self.width, self.height) #tamaño de grafica

        m = PlotCanvas(self, width=5, height=4)#Tamaño de grafica
        m.move(0,0) #posici{on de grafica

        self.show()


class PlotCanvas(FigureCanvas):

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        self.plot()

# ------valores a gráfica con random---------------

    def plot(self):
        data = [random.random() for i in range(25)]
        ax = self.figure.add_subplot(111)
        ax.plot(data, 'r-')
        ax.set_title('PyQt Matplotlib')
        self.draw()
## ------valores a gráfica con random---------------

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

investigando en internet encontré un programa en el cual utiliza lo siguiente --animation.FuncAnimation --- el cual genera una grafica matplotlib y realiza la animación correctamente mandando datos aleatorios pero sin usar QT 5 designer

Mi problema es que no puedo juntar estos dos programas para que mi grafica en qt5 tenga esa animación, tengo muy poca experiencia en python asi que espero que me puedan apoyar, gracias :=)

Adjunto los programas
Código:
grafica = figura.add_subplot(1, 1, 1)

# Nueva Trama
def unatrama(i, xi, yi):

    # Recibe un dato nuevo
  
    undato = int(rnd.random()*20)+1
    print(undato)

    # actualiza cada linea
    yi.append(undato)
    xi.append(len(yi)) # devuelve el numero de la cadena
   

    # ventana de datos
    xi = xi[-tamano:]
    yi = yi[-tamano:]

    # limpia y grafica de nuevo
    grafica.clear()
    grafica.plot(yi)


    return()

# Animación

ani = animation.FuncAnimation(figura,
                              unatrama,
                              fargs=(xi, yi),
                              interval=retraso)

plt.show()
Responder
#2
Hola Eduardo, bienvenido.

En Qt podés usar un QTimer para ejecutar una acción cada determinada cantidad de tiempo. Una solución posible a tu problema es la siguente.

Primero, agregás al principio del archivo:

  1. from PyQt5.QtCore import QTimer


Luego, creás el QTimer al inciar la ventana:

  1. self.timer = QTimer(self)
  2. self.timer.start(2000) # 2000 = 2 segundos. Ajustar según corresponda.
  3. self.timer.timeout.connect(self.redraw)
  4.  
  5. self.plot_canvas = PlotCanvas(self, width=5, height=4)#Tamaño de grafica
  6. self.plot_canvas.move(0,0) #posici{on de grafica


Y el método redraw() que se va a invocar periódicamente:

  1. def redraw(self):
  2. self.plot_canvas.figure.clf() # Borrar el gráfico anterior.
  3. self.plot_canvas.plot() # Generar uno nuevo.


Código completo:

Código:
#librerias, programa sin animación en QT 5 designer
import sys

from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget
from PyQt5.QtGui import QIcon

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt

import random
#-----------


class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.left = 800 #posición de ventana QT
        self.top = 400 #posición de ventana QT
        self.title = 'PyQt5 matplotlib' # Nombre de ventana
        self.width = 640 #Tamaño de ventana
        self.height = 400 #Tamaño de ventana
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title) # nombre de ventana PyQt5 matplotlib
        self.setGeometry(self.left, self.top, self.width, self.height) #tamaño de grafica

        self.timer = QTimer(self)
        self.timer.start(2000)
        self.timer.timeout.connect(self.redraw)

        self.plot_canvas = PlotCanvas(self, width=5, height=4)#Tamaño de grafica
        self.plot_canvas.move(0,0) #posici{on de grafica

        self.show()
    
    def redraw(self):
        self.plot_canvas.figure.clf()
        self.plot_canvas.plot()


class PlotCanvas(FigureCanvas):

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        self.plot()

# ------valores a gráfica con random---------------

    def plot(self):
        data = [random.random() for i in range(25)]
        ax = self.figure.add_subplot(111)
        ax.plot(data, 'r-')
        ax.set_title('PyQt Matplotlib')
        self.draw()
## ------valores a gráfica con random---------------

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Saludos
Responder
#3
Gracias por la ayuda, probé el código y me sirvió para seguir con mi trabajo, se me complicó mucho realizar este código.

En el código tengo valores aleatoreos de 0 a 1, obviamente la grafica toma el valor mas grande y lo pone como límite en el eje vertical, como puedo yo decirle al programa que quiero que la grafica tenga como visualización un rango en vertical de 5 por poner un ejemplo, pero aun quiero que los valores aleatoreos sean de 0 a 1.

Por ejemplo la parte horizontal la controlo de aquí :  range(25)

def plot(self):
        data = [random.random() for i in range(25)]
        ax = self.figure.add_subplot(111)
        ax.plot(data, 'r-')
        ax.set_title('PyQt Matplotlib')
        self.draw()
Responder
#4
Para que el eje Y muestre, por ejemplo, de -5 a 5, usás set_ylim():

  1. def plot(self):
  2. data = [random.random() for i in range(25)]
  3. ax = self.figure.add_subplot(111)
  4. ax.set_ylim(-5, 5) # <-------
  5. ax.plot(data, 'r-')
  6. ax.set_title('PyQt Matplotlib')
  7. self.draw()


Saludos
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)