1

I've tried using example pieces of code to embed my animated graph of mars and earth orbiting the sun using an _update_plot from pyplot from matplotlib into a PyQt5 GUI. There are no examples that use pyplot and I'm really struggling. What have I dont wrong here: (?)

Attempt:

import sys
import time

import numpy as np

from matplotlib.backends.qt_compat import QtCore, QtWidgets, is_pyqt5
if is_pyqt5():
    from matplotlib.backends.backend_qt5agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
    from matplotlib.backends.backend_qt4agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        layout = QtWidgets.QVBoxLayout(self._main)

        static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
        layout.addWidget(static_canvas)
        self.addToolBar(NavigationToolbar(static_canvas, self))

        dynamic_canvas = FigureCanvas(Figure(figsize=(5, 3)))
        layout.addWidget(dynamic_canvas)
        self.addToolBar(QtCore.Qt.BottomToolBarArea,
                        NavigationToolbar(dynamic_canvas, self))

        self._static_ax = static_canvas.figure.subplots()
        t = np.linspace(0, 10, 501)
        self._static_ax.plot(t, np.tan(t), ".")

        self._dynamic_ax = dynamic_canvas.figure.subplots()
        self._timer = dynamic_canvas.new_timer(
            100, [(self._update_canvas, (), {})])
        self._timer.start()

    def _update_canvas(self):
        scat = scat.set_offsets(([math.cos(math.radians(i))*7.5, math.sin(math.radians(i))*7.5], [math.cos(math.radians(i/2))*9, math.sin(math.radians(i/2))*9], [0, 0]))
        anim = self.animation.FuncAnimation(fig, scat, fargs = (fig, scat, l,l2),
                               frames = 720, interval = 10)



if __name__ == "__main__":
    qapp = QtWidgets.QApplication(sys.argv)
    app = ApplicationWindow()
    app.show()
    qapp.exec_()

the Original code I'm trying to embed is this:

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

def _update_plot(i, fig, scat): 
        M = ((math.sin(math.radians(i))*7.5)-(math.sin(math.radians(i/2))*9))/((math.cos(math.radians(i))*7.5)-(math.cos(math.radians(i/2))*9))
        g = M*(15-(math.cos(math.radians(i/2))*9))+(math.sin(math.radians(i/2))*9)

        scat.set_offsets(([math.cos(math.radians(i))*7.5, math.sin(math.radians(i))*7.5], [math.cos(math.radians(i/2))*9, math.sin(math.radians(i/2))*9], [0, 0]))
        return [scat]

fig = plt.figure()
x = [0]
y = [0]

ax = fig.add_subplot(111)
ax.set_aspect('equal')
ax.grid(True, linestyle = '-', color = '0.10')
ax.set_xlim([-15, 15])
ax.set_ylim([-15, 15])

scat = plt.scatter(x, y, c = x, zorder=3)
scat.set_alpha(0.8)

anim = animation.FuncAnimation(fig, _update_plot, fargs = (fig, scat),
                               frames = 720, interval = 10)

plt.show()

Any help/advice is greatly appreciated.

1 Answer 1

2

The idea is indeed to not use pyplot in case you embedd in a custom GUI. Else your figure would be managed by pyplot as well as the GUI.

The adaption of your example could look like this:

import sys
import numpy as np

from matplotlib.backends.qt_compat import QtWidgets
from matplotlib.backends.backend_qt5agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)

from matplotlib.figure import Figure
from matplotlib import animation


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        layout = QtWidgets.QVBoxLayout(self._main)

        self.fig = Figure(figsize=(5, 3))
        self.canvas = FigureCanvas(self.fig)
        layout.addWidget(self.canvas)
        self.addToolBar(NavigationToolbar(self.canvas, self))

        self.setup()

    def setup(self):
        self.ax = self.fig.subplots()
        self.ax.set_aspect('equal')
        self.ax.grid(True, linestyle = '-', color = '0.10')
        self.ax.set_xlim([-15, 15])
        self.ax.set_ylim([-15, 15])

        self.scat = self.ax.scatter([], [],  zorder=3)
        self.scat.set_alpha(0.8)

        self.anim = animation.FuncAnimation(self.fig, self.update,
                                                 frames = 720, interval = 10)


    def update(self, i):
        self.scat.set_offsets(([np.cos(np.radians(i))*7.5, np.sin(np.radians(i))*7.5], 
                                  [np.cos(np.radians(i/2))*9, np.sin(np.radians(i/2))*9]))



if __name__ == "__main__":
    qapp = QtWidgets.QApplication(sys.argv)
    app = ApplicationWindow()
    app.show()
    qapp.exec_()
Sign up to request clarification or add additional context in comments.

2 Comments

@ImportanceOfBeingIdle Thanks you so much this has helped me massively, I was tearing my hair out trying to find a way, thank you so much.
@ImportanceOfBeingIdle Also If I wanted to add a second animated graph (alot like the original graph) could I use these classes? How would I go about that?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.