Matplotlib und PyQt5

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Nick94
User
Beiträge: 10
Registriert: Dienstag 16. Juni 2020, 14:14

Hallo zusammen,

seit längerem bin ich dabei, ein Plot Tool zu entwerfen.
Dabei erzeuge ich mittels PyQt5 eine GUI, welche es ermöglicht verschiedene Kurven o.ä. auszuwählen.
Funktioniert auch alle soweit. (unter Windows 10)

Ich würde das ganze jetzt aber gerne unter Linux bzw. Unix (LXQt) laufen lassen.

Problematik dabei ist, dass Matplotlib und die Fenster von PyQt5 auf einmal nicht mehr zusammen funktionieren.
Der Plot wird angezeigt, aber das Fenster welches angezeigt werden soll, ist nur schwarz oder es zeigt den teil des Bildschirms an in dem es "aufploppt".

Hier mal ein kleines Beispiel:

Code: Alles auswählen

import sys
import PyQt5.QtWidgets as widgets
import PyQt5.uic as uic
import matplotlib.pyplot as plt
import numpy as np


app = widgets.QApplication(sys.argv)
w = uic.loadUi("Test_Window.ui")
w.show()

x = np.arange(0,4*np.pi,0.1)   # start,stop,step
y = np.sin(x)

plt.plot(x,y)
plt.show()

sys.exit(app.exec_())
Hat hier vllt. jemand eine Idee oder einen Tipp?
Würde mich über jeden Einwand und jede Hilfe freuen.

Schon mal Danke im Voraus
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist keine richtige Integration. Das die unter Windows funktioniert ist eher ein glücklicher Zufall. Sowas geht so: https://matplotlib.org/3.1.2/gallery/us ... gskip.html
Nick94
User
Beiträge: 10
Registriert: Dienstag 16. Juni 2020, 14:14

Danke für die Antwort.

Ist ein guter Hinweis, aber ich habe noch meine Probleme damit, es umzusetzen.
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist bedauerlich, aber ohne konkrete Fragen/Code kann ich da auch nur mit den Schultern zucken.
Nick94
User
Beiträge: 10
Registriert: Dienstag 16. Juni 2020, 14:14

Sorry...

Ich habe es jetzt so, dass der Plot im PyQt eingebettet ist.
Allerdings klappt es jetzt nicht mehr, dass ich auf den Plot zugreifen kann, um ihn beispielsweise zu zoomen oder zu verschieben....

Code: Alles auswählen

from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout, QMainWindow
import sys
import PyQt5.uic as uic
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.figure import Figure
import matplotlib
import numpy as np



class MatplotlibWidget(QWidget):
    def __init__(self, parent=None):
        super(MatplotlibWidget, self).__init__(parent)
        self.figure = Figure()
        self.canvas = FigureCanvasQTAgg(self.figure)
        self.axis = self.figure.add_subplot(111)
        
        self.layoutvertical = QVBoxLayout(self)
        self.layoutvertical.addWidget(self.canvas)
        
class MainWidget(QWidget):
    def __init__(self):
        super(MainWidget, self).__init__()
        uic.loadUi('Test_Window_2.ui', self)
        self.init_widget()
        self.pushButton.clicked.connect(self.plot_widget)
        
    def init_widget(self):
        self.matplotlibwidget = MatplotlibWidget()
        self.layoutvertical = QVBoxLayout(self.widget)
        self.layoutvertical.addWidget(self.matplotlibwidget)
    
    def plot_widget(self):
        self.matplotlibwidget.axis.clear()
        x = np.arange(0,10,0.1)
        y = np.sin(x)
        self.matplotlibwidget.axis.plot(x,y)
        self.matplotlibwidget.canvas.draw()



if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWidget()
    w.show()
    sys.exit(app.exec_())

Vorher habe ich mit dem folgenden Code die Kurve gezoomt. Ich weiß gerade aber nicht, wie ich an ax komme. Das habe ich vorher mit "axes = plt.gca()" gemacht.

Code: Alles auswählen

class ZoomPan:
    def __init__(self):
        self.press = None
        self.cur_xlim = None
        self.cur_ylim = None
        self.x0 = None
        self.y0 = None
        self.x1 = None
        self.y1 = None
        self.xpress = None
        self.ypress = None


    def zoom_factory(self, ax, base_scale = 2.):
        def zoom(event):
            cur_xlim = ax.get_xlim()
            #cur_ylim = ax.get_ylim()

            xdata = event.xdata # get event x location
            #ydata = event.ydata # get event y location

            if event.button == 'down':
                # deal with zoom in
                scale_factor = 1 / base_scale
            elif event.button == 'up':
                # deal with zoom out
                scale_factor = base_scale
            else:
                # deal with something that should never happen
                scale_factor = 1
                print (event.button)

            new_width = (cur_xlim[1] - cur_xlim[0]) * scale_factor
            #new_height = (cur_ylim[1] - cur_ylim[0]) * scale_factor

            relx = (cur_xlim[1] - xdata)/(cur_xlim[1] - cur_xlim[0])
            #rely = (cur_ylim[1] - ydata)/(cur_ylim[1] - cur_ylim[0])

            ax.set_xlim([xdata - new_width * (1-relx), xdata + new_width * (relx)])
            #ax.set_ylim([ydata - new_height * (1-rely), ydata + new_height * (rely)])
            ax.figure.canvas.draw()

        fig = ax.get_figure() # get the figure of interest
        fig.canvas.mpl_connect('scroll_event', zoom)

        return zoom

    def pan_factory(self, ax):
        def onPress(event):
            if event.inaxes != ax: return
            self.cur_xlim = ax.get_xlim()
            #self.cur_ylim = ax.get_ylim()
            #self.press = self.x0, self.y0, event.xdata, event.ydata
            self.press = self.x0, event.xdata
            #self.x0, self.y0, self.xpress, self.ypress = self.press
            self.x0, self.xpress

        def onRelease(event):
            self.press = None
            ax.figure.canvas.draw()

        def onMotion(event):
            if self.press is None: return
            if event.inaxes != ax: return
            dx = event.xdata - self.xpress
            #dy = event.ydata - self.ypress
            self.cur_xlim -= dx
            #self.cur_ylim -= dy
            ax.set_xlim(self.cur_xlim)
            #ax.set_ylim(self.cur_ylim)

            ax.figure.canvas.draw()

        fig = ax.get_figure() # get the figure of interest

        # attach the call back
        fig.canvas.mpl_connect('button_press_event',onPress)
        fig.canvas.mpl_connect('button_release_event',onRelease)
        fig.canvas.mpl_connect('motion_notify_event',onMotion)

        #return the function
        return onMotion
Vielen Dank für die Unterstützung
Antworten